diff -Nrc3pad gcc-3.2.3/gcc/cp/call.c gcc-3.3/gcc/cp/call.c *** gcc-3.2.3/gcc/cp/call.c 2003-03-19 18:18:05.000000000 +0000 --- gcc-3.3/gcc/cp/call.c 2003-04-24 06:01:22.000000000 +0000 *************** *** 1,6 **** /* Functions related to invoking methods and overloaded functions. ! Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, ! 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) and modified by Brendan Kehoe (brendan@cygnus.com). --- 1,6 ---- /* Functions related to invoking methods and overloaded functions. ! Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003, ! 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) and modified by Brendan Kehoe (brendan@cygnus.com). *************** Boston, MA 02111-1307, USA. */ *** 38,46 **** extern int inhibit_warnings; ! static tree build_new_method_call PARAMS ((tree, tree, tree, tree, int)); ! ! static tree build_field_call PARAMS ((tree, tree, tree, tree)); static struct z_candidate * tourney PARAMS ((struct z_candidate *)); static int equal_functions PARAMS ((tree, tree)); static int joust PARAMS ((struct z_candidate *, struct z_candidate *, int)); --- 38,44 ---- extern int inhibit_warnings; ! static tree build_field_call PARAMS ((tree, tree, tree)); static struct z_candidate * tourney PARAMS ((struct z_candidate *)); static int equal_functions PARAMS ((tree, tree)); static int joust PARAMS ((struct z_candidate *, struct z_candidate *, int)); *************** static void print_z_candidates PARAMS (( *** 62,99 **** static tree build_this PARAMS ((tree)); static struct z_candidate * splice_viable PARAMS ((struct z_candidate *)); static int any_viable PARAMS ((struct z_candidate *)); static struct z_candidate * add_template_candidate ! PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree, int, ! unification_kind_t)); static struct z_candidate * add_template_candidate_real ! PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree, int, ! tree, unification_kind_t)); static struct z_candidate * add_template_conv_candidate ! PARAMS ((struct z_candidate *, tree, tree, tree, tree)); ! static struct z_candidate * add_builtin_candidates ! PARAMS ((struct z_candidate *, enum tree_code, enum tree_code, tree, tree *, int)); ! static struct z_candidate * add_builtin_candidate ! PARAMS ((struct z_candidate *, enum tree_code, enum tree_code, tree, tree, tree, tree *, tree *, int)); static int is_complete PARAMS ((tree)); ! static struct z_candidate * build_builtin_candidate ! PARAMS ((struct z_candidate *, tree, tree, tree, tree *, tree *, int)); static struct z_candidate * add_conv_candidate ! PARAMS ((struct z_candidate *, tree, tree, tree)); static struct z_candidate * add_function_candidate ! PARAMS ((struct z_candidate *, tree, tree, tree, int)); static tree implicit_conversion PARAMS ((tree, tree, tree, int)); static tree standard_conversion PARAMS ((tree, tree, tree)); ! static tree reference_binding PARAMS ((tree, tree, tree, int)); static tree non_reference PARAMS ((tree)); static tree build_conv PARAMS ((enum tree_code, tree, tree)); static int is_subseq PARAMS ((tree, tree)); static tree maybe_handle_ref_bind PARAMS ((tree*)); static void maybe_handle_implicit_object PARAMS ((tree*)); ! static struct z_candidate * add_candidate PARAMS ((struct z_candidate *, ! tree, tree, int)); static tree source_type PARAMS ((tree)); static void add_warning PARAMS ((struct z_candidate *, struct z_candidate *)); static int reference_related_p PARAMS ((tree, tree)); --- 60,98 ---- static tree build_this PARAMS ((tree)); static struct z_candidate * splice_viable PARAMS ((struct z_candidate *)); static int any_viable PARAMS ((struct z_candidate *)); + static int any_strictly_viable PARAMS ((struct z_candidate *)); static struct z_candidate * add_template_candidate ! PARAMS ((struct z_candidate **, tree, tree, tree, tree, tree, ! tree, tree, int, unification_kind_t)); static struct z_candidate * add_template_candidate_real ! PARAMS ((struct z_candidate **, tree, tree, tree, tree, tree, ! tree, tree, int, tree, unification_kind_t)); static struct z_candidate * add_template_conv_candidate ! PARAMS ((struct z_candidate **, tree, tree, tree, tree, tree, tree)); ! static void add_builtin_candidates ! PARAMS ((struct z_candidate **, enum tree_code, enum tree_code, tree, tree *, int)); ! static void add_builtin_candidate ! PARAMS ((struct z_candidate **, enum tree_code, enum tree_code, tree, tree, tree, tree *, tree *, int)); static int is_complete PARAMS ((tree)); ! static void build_builtin_candidate ! PARAMS ((struct z_candidate **, tree, tree, tree, tree *, tree *, int)); static struct z_candidate * add_conv_candidate ! PARAMS ((struct z_candidate **, tree, tree, tree, tree, tree)); static struct z_candidate * add_function_candidate ! (struct z_candidate **, tree, tree, tree, tree, tree, int); static tree implicit_conversion PARAMS ((tree, tree, tree, int)); static tree standard_conversion PARAMS ((tree, tree, tree)); ! static tree reference_binding (tree, tree, tree, int); static tree non_reference PARAMS ((tree)); static tree build_conv PARAMS ((enum tree_code, tree, tree)); static int is_subseq PARAMS ((tree, tree)); static tree maybe_handle_ref_bind PARAMS ((tree*)); static void maybe_handle_implicit_object PARAMS ((tree*)); ! static struct z_candidate *add_candidate ! (struct z_candidate **, tree, tree, tree, tree, int); static tree source_type PARAMS ((tree)); static void add_warning PARAMS ((struct z_candidate *, struct z_candidate *)); static int reference_related_p PARAMS ((tree, tree)); *************** static tree direct_reference_binding PAR *** 103,158 **** static int promoted_arithmetic_type_p PARAMS ((tree)); static tree conditional_conversion PARAMS ((tree, tree)); static tree call_builtin_trap PARAMS ((void)); tree build_vfield_ref (datum, type) tree datum, type; { - tree rval; - if (datum == error_mark_node) return error_mark_node; if (TREE_CODE (TREE_TYPE (datum)) == REFERENCE_TYPE) datum = convert_from_reference (datum); ! if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)) ! rval = build (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)), ! datum, TYPE_VFIELD (type)); ! else ! rval = build_component_ref (datum, DECL_NAME (TYPE_VFIELD (type)), NULL_TREE, 0); ! return rval; } /* Build a call to a member of an object. I.e., one that overloads operator ()(), or is a pointer-to-function or pointer-to-method. */ static tree ! build_field_call (basetype_path, instance_ptr, name, parms) ! tree basetype_path, instance_ptr, name, parms; { ! tree field, instance; ! ! if (IDENTIFIER_CTOR_OR_DTOR_P (name)) ! return NULL_TREE; ! ! /* Speed up the common case. */ ! if (instance_ptr == current_class_ptr ! && IDENTIFIER_CLASS_VALUE (name) == NULL_TREE) ! return NULL_TREE; ! ! field = lookup_field (basetype_path, name, 1, 0); ! if (field == error_mark_node || field == NULL_TREE) ! return field; ! if (TREE_CODE (field) == FIELD_DECL || TREE_CODE (field) == VAR_DECL) { /* If it's a field, try overloading operator (), or calling if the field is a pointer-to-function. */ instance = build_indirect_ref (instance_ptr, NULL); ! instance = build_component_ref_1 (instance, field, 0); if (instance == error_mark_node) return error_mark_node; --- 102,146 ---- static int promoted_arithmetic_type_p PARAMS ((tree)); static tree conditional_conversion PARAMS ((tree, tree)); static tree call_builtin_trap PARAMS ((void)); + static tree merge_conversion_sequences (tree, tree); tree build_vfield_ref (datum, type) tree datum, type; { if (datum == error_mark_node) return error_mark_node; if (TREE_CODE (TREE_TYPE (datum)) == REFERENCE_TYPE) datum = convert_from_reference (datum); ! if (TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type) ! && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type)) ! datum = convert_to_base (datum, type, /*check_access=*/false); ! return build (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)), ! datum, TYPE_VFIELD (type)); } /* Build a call to a member of an object. I.e., one that overloads operator ()(), or is a pointer-to-function or pointer-to-method. */ static tree ! build_field_call (tree instance_ptr, tree decl, tree parms) { ! tree instance; ! if (decl == error_mark_node || decl == NULL_TREE) ! return decl; ! if (TREE_CODE (decl) == FIELD_DECL || TREE_CODE (decl) == VAR_DECL) { /* If it's a field, try overloading operator (), or calling if the field is a pointer-to-function. */ instance = build_indirect_ref (instance_ptr, NULL); ! instance = build_class_member_access_expr (instance, decl, ! /*access_path=*/NULL_TREE, ! /*preserve_reference=*/false); if (instance == error_mark_node) return error_mark_node; *************** build_scoped_method_call (exp, basetype, *** 299,325 **** return error_mark_node; } ! if (! binfo) ! { ! binfo = lookup_base (type, basetype, ba_check, NULL); ! if (binfo == error_mark_node) ! return error_mark_node; ! if (! binfo) ! error_not_base_type (basetype, type); ! } if (binfo) { - if (TREE_CODE (exp) == INDIRECT_REF) - { - decl = build_base_path (PLUS_EXPR, - build_unary_op (ADDR_EXPR, exp, 0), - binfo, 1); - decl = build_indirect_ref (decl, NULL); - } - else - decl = build_scoped_ref (exp, basetype); - /* Call to a destructor. */ if (TREE_CODE (name) == BIT_NOT_EXPR) { --- 287,296 ---- return error_mark_node; } ! decl = build_scoped_ref (exp, basetype, &binfo); if (binfo) { /* Call to a destructor. */ if (TREE_CODE (name) == BIT_NOT_EXPR) { *************** build_addr_func (function) *** 356,362 **** type = build_pointer_type (type); ! if (mark_addressable (function) == 0) return error_mark_node; addr = build1 (ADDR_EXPR, type, function); --- 327,333 ---- type = build_pointer_type (type); ! if (!cxx_mark_addressable (function)) return error_mark_node; addr = build1 (ADDR_EXPR, type, function); *************** build_call (function, parms) *** 387,392 **** --- 358,364 ---- tree tmp; tree decl; tree result_type; + tree fntype; function = build_addr_func (function); *************** build_call (function, parms) *** 396,402 **** return error_mark_node; } ! result_type = TREE_TYPE (TREE_TYPE (TREE_TYPE (function))); if (TREE_CODE (function) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL) --- 368,375 ---- return error_mark_node; } ! fntype = TREE_TYPE (TREE_TYPE (function)); ! result_type = TREE_TYPE (fntype); if (TREE_CODE (function) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL) *************** build_call (function, parms) *** 414,419 **** --- 387,393 ---- if (decl && TREE_DEPRECATED (decl)) warn_deprecated_use (decl); + require_complete_eh_spec_types (fntype, decl); if (decl && DECL_CONSTRUCTOR_P (decl)) is_constructor = 1; *************** build_method_call (instance, name, parms *** 493,499 **** tree instance, name, parms, basetype_path; int flags; { ! tree basetype, instance_ptr; #ifdef GATHER_STATISTICS n_build_method_call++; --- 467,476 ---- tree instance, name, parms, basetype_path; int flags; { ! tree fn; ! tree object_type; ! tree template_args = NULL_TREE; ! bool has_template_args = false; #ifdef GATHER_STATISTICS n_build_method_call++; *************** build_method_call (instance, name, parms *** 502,508 **** if (instance == error_mark_node || name == error_mark_node || parms == error_mark_node ! || (instance != NULL_TREE && TREE_TYPE (instance) == error_mark_node)) return error_mark_node; if (processing_template_decl) --- 479,485 ---- if (instance == error_mark_node || name == error_mark_node || parms == error_mark_node ! || (instance && TREE_TYPE (instance) == error_mark_node)) return error_mark_node; if (processing_template_decl) *************** build_method_call (instance, name, parms *** 525,563 **** return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE); } if (TREE_CODE (name) == BIT_NOT_EXPR) { if (parms) error ("destructors take no parameters"); - basetype = TREE_TYPE (instance); - if (TREE_CODE (basetype) == REFERENCE_TYPE) - basetype = TREE_TYPE (basetype); ! if (! check_dtor_name (basetype, name)) error ("destructor name `~%T' does not match type `%T' of expression", ! TREE_OPERAND (name, 0), basetype); ! if (! TYPE_HAS_DESTRUCTOR (complete_type (basetype))) return cp_convert (void_type_node, instance); instance = default_conversion (instance); instance_ptr = build_unary_op (ADDR_EXPR, instance, 0); ! return build_delete (build_pointer_type (basetype), instance_ptr, sfk_complete_destructor, LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0); } ! return build_new_method_call (instance, name, parms, basetype_path, flags); } /* New overloading code. */ ! struct z_candidate { tree fn; tree convs; tree second_conv; int viable; ! tree basetype_path; tree template; tree warnings; struct z_candidate *next; --- 502,612 ---- return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE); } + if (TREE_CODE (instance) == OFFSET_REF) + instance = resolve_offset_ref (instance); + if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE) + instance = convert_from_reference (instance); + object_type = TREE_TYPE (instance); + if (TREE_CODE (name) == BIT_NOT_EXPR) { + tree instance_ptr; + if (parms) error ("destructors take no parameters"); ! if (! check_dtor_name (object_type, name)) error ("destructor name `~%T' does not match type `%T' of expression", ! TREE_OPERAND (name, 0), object_type); ! /* The destructor type must be complete. */ ! object_type = complete_type_or_else (object_type, NULL_TREE); ! if (!object_type || object_type == error_mark_node) ! return error_mark_node; ! ! if (! TYPE_HAS_DESTRUCTOR (object_type)) return cp_convert (void_type_node, instance); instance = default_conversion (instance); instance_ptr = build_unary_op (ADDR_EXPR, instance, 0); ! return build_delete (build_pointer_type (object_type), instance_ptr, sfk_complete_destructor, LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0); } ! if (!CLASS_TYPE_P (object_type)) ! { ! if ((flags & LOOKUP_COMPLAIN) ! && TREE_TYPE (instance) != error_mark_node) ! error ("request for member `%D' in `%E', which is of non-aggregate type `%T'", ! name, instance, object_type); ! return error_mark_node; ! } ! ! if (TREE_CODE (name) == TEMPLATE_ID_EXPR) ! { ! template_args = TREE_OPERAND (name, 1); ! has_template_args = true; ! name = TREE_OPERAND (name, 0); ! } ! if (TREE_CODE (name) == OVERLOAD) ! name = DECL_NAME (get_first_fn (name)); ! else if (TREE_CODE (name) == LOOKUP_EXPR) ! name = TREE_OPERAND (name, 0); ! else if (DECL_P (name)) ! name = DECL_NAME (name); ! if (has_template_args) ! fn = lookup_fnfields (object_type, name, /*protect=*/2); ! else ! fn = lookup_member (object_type, name, /*protect=*/2, /*want_type=*/0); ! ! if (fn && TREE_CODE (fn) == TREE_LIST && !BASELINK_P (fn)) ! { ! error ("request for member `%D' is ambiguous", name); ! print_candidates (fn); ! return error_mark_node; ! } ! ! /* If the name could not be found, issue an error. */ ! if (!fn) ! { ! unqualified_name_lookup_error (name); ! return error_mark_node; ! } ! ! if (BASELINK_P (fn) && has_template_args) ! BASELINK_FUNCTIONS (fn) ! = build_nt (TEMPLATE_ID_EXPR, ! BASELINK_FUNCTIONS (fn), ! template_args); ! if (BASELINK_P (fn) && basetype_path) ! BASELINK_ACCESS_BINFO (fn) = basetype_path; ! ! return build_new_method_call (instance, fn, parms, ! /*conversion_path=*/NULL_TREE, flags); } /* New overloading code. */ ! struct z_candidate GTY(()) { ! /* The FUNCTION_DECL that will be called if this candidate is ! selected by overload resolution. */ tree fn; tree convs; tree second_conv; int viable; ! /* If FN is a member function, the binfo indicating the path used to ! qualify the name of FN at the call site. This path is used to ! determine whether or not FN is accessible if it is selected by ! overload resolution. The DECL_CONTEXT of FN will always be a ! (possibly improper) base of this binfo. */ ! tree access_path; ! /* If FN is a non-static member function, the binfo indicating the ! subobject to which the `this' pointer should be converted if FN ! is selected by overload resolution. The type pointed to the by ! the `this' pointer must correspond to the most derived class ! indicated by the CONVERSION_PATH. */ ! tree conversion_path; tree template; tree warnings; struct z_candidate *next; *************** struct z_candidate { *** 589,596 **** should be created to hold the result of the conversion. */ #define NEED_TEMPORARY_P(NODE) TREE_LANG_FLAG_4 (NODE) ! #define USER_CONV_CAND(NODE) \ ! ((struct z_candidate *)WRAPPER_PTR (TREE_OPERAND (NODE, 1))) #define USER_CONV_FN(NODE) (USER_CONV_CAND (NODE)->fn) int --- 638,644 ---- should be created to hold the result of the conversion. */ #define NEED_TEMPORARY_P(NODE) TREE_LANG_FLAG_4 (NODE) ! #define USER_CONV_CAND(NODE) WRAPPER_ZC (TREE_OPERAND (NODE, 1)) #define USER_CONV_FN(NODE) (USER_CONV_CAND (NODE)->fn) int *************** null_ptr_cst_p (t) *** 608,615 **** } ! /* Returns non-zero if PARMLIST consists of only default parms and/or ! ellipsis. */ int sufficient_parms_p (parmlist) --- 656,663 ---- } ! /* Returns nonzero if PARMLIST consists of only default parms and/or ! ellipsis. */ int sufficient_parms_p (parmlist) *************** build_conv (code, type, from) *** 655,661 **** break; } ICS_STD_RANK (t) = rank; ! ICS_USER_FLAG (t) = ICS_USER_FLAG (from); ICS_BAD_FLAG (t) = ICS_BAD_FLAG (from); return t; } --- 703,709 ---- break; } ICS_STD_RANK (t) = rank; ! ICS_USER_FLAG (t) = (code == USER_CONV || ICS_USER_FLAG (from)); ICS_BAD_FLAG (t) = ICS_BAD_FLAG (from); return t; } *************** standard_conversion (to, from, expr) *** 802,809 **** (TREE_TYPE (TREE_TYPE (from)), TREE_TYPE (TREE_TYPE (to))))) { ! from = build_offset_type (tbase, TREE_TYPE (TREE_TYPE (from))); ! from = build_pointer_type (from); conv = build_conv (PMEM_CONV, from, conv); } } --- 850,856 ---- (TREE_TYPE (TREE_TYPE (from)), TREE_TYPE (TREE_TYPE (to))))) { ! from = build_ptrmem_type (tbase, TREE_TYPE (TREE_TYPE (from))); conv = build_conv (PMEM_CONV, from, conv); } } *************** standard_conversion (to, from, expr) *** 900,906 **** return conv; } ! /* Returns non-zero if T1 is reference-related to T2. */ static int reference_related_p (t1, t2) --- 947,953 ---- return conv; } ! /* Returns nonzero if T1 is reference-related to T2. */ static int reference_related_p (t1, t2) *************** reference_related_p (t1, t2) *** 920,926 **** && DERIVED_FROM_P (t1, t2))); } ! /* Returns non-zero if T1 is reference-compatible with T2. */ static int reference_compatible_p (t1, t2) --- 967,973 ---- && DERIVED_FROM_P (t1, t2))); } ! /* Returns nonzero if T1 is reference-compatible with T2. */ static int reference_compatible_p (t1, t2) *************** convert_class_to_reference (t, s, expr) *** 948,956 **** --- 995,1008 ---- tree conversions; tree arglist; tree conv; + tree reference_type; struct z_candidate *candidates; struct z_candidate *cand; + conversions = lookup_conversions (s); + if (!conversions) + return NULL_TREE; + /* [over.match.ref] Assuming that "cv1 T" is the underlying type of the reference *************** convert_class_to_reference (t, s, expr) *** 976,985 **** arglist = build_int_2 (0, 0); TREE_TYPE (arglist) = build_pointer_type (s); arglist = build_tree_list (NULL_TREE, arglist); ! ! for (conversions = lookup_conversions (s); ! conversions; ! conversions = TREE_CHAIN (conversions)) { tree fns = TREE_VALUE (conversions); --- 1028,1037 ---- arglist = build_int_2 (0, 0); TREE_TYPE (arglist) = build_pointer_type (s); arglist = build_tree_list (NULL_TREE, arglist); ! ! reference_type = build_reference_type (t); ! ! while (conversions) { tree fns = TREE_VALUE (conversions); *************** convert_class_to_reference (t, s, expr) *** 987,1029 **** { tree f = OVL_CURRENT (fns); tree t2 = TREE_TYPE (TREE_TYPE (f)); ! struct z_candidate *old_candidates = candidates; /* If this is a template function, try to get an exact match. */ if (TREE_CODE (f) == TEMPLATE_DECL) { ! candidates ! = add_template_candidate (candidates, ! f, s, ! NULL_TREE, ! arglist, ! build_reference_type (t), ! LOOKUP_NORMAL, ! DEDUCE_CONV); ! if (candidates != old_candidates) { /* Now, see if the conversion function really returns an lvalue of the appropriate type. From the point of view of unification, simply returning an rvalue of the right type is good enough. */ ! f = candidates->fn; t2 = TREE_TYPE (TREE_TYPE (f)); if (TREE_CODE (t2) != REFERENCE_TYPE || !reference_compatible_p (t, TREE_TYPE (t2))) ! candidates = candidates->next; } } else if (TREE_CODE (t2) == REFERENCE_TYPE && reference_compatible_p (t, TREE_TYPE (t2))) ! candidates ! = add_function_candidate (candidates, f, s, arglist, ! LOOKUP_NORMAL); ! ! if (candidates != old_candidates) ! candidates->basetype_path = TYPE_BINFO (s); } } /* If none of the conversion functions worked out, let our caller --- 1039,1096 ---- { tree f = OVL_CURRENT (fns); tree t2 = TREE_TYPE (TREE_TYPE (f)); ! ! cand = NULL; /* If this is a template function, try to get an exact match. */ if (TREE_CODE (f) == TEMPLATE_DECL) { ! cand = add_template_candidate (&candidates, ! f, s, ! NULL_TREE, ! arglist, ! reference_type, ! TYPE_BINFO (s), ! TREE_PURPOSE (conversions), ! LOOKUP_NORMAL, ! DEDUCE_CONV); ! if (cand) { /* Now, see if the conversion function really returns an lvalue of the appropriate type. From the point of view of unification, simply returning an rvalue of the right type is good enough. */ ! f = cand->fn; t2 = TREE_TYPE (TREE_TYPE (f)); if (TREE_CODE (t2) != REFERENCE_TYPE || !reference_compatible_p (t, TREE_TYPE (t2))) ! { ! candidates = candidates->next; ! cand = NULL; ! } } } else if (TREE_CODE (t2) == REFERENCE_TYPE && reference_compatible_p (t, TREE_TYPE (t2))) ! cand = add_function_candidate (&candidates, f, s, arglist, ! TYPE_BINFO (s), ! TREE_PURPOSE (conversions), ! LOOKUP_NORMAL); ! ! if (cand) ! /* Build a standard conversion sequence indicating the ! binding from the reference type returned by the ! function to the desired REFERENCE_TYPE. */ ! cand->second_conv ! = (direct_reference_binding ! (reference_type, ! build1 (IDENTITY_CONV, ! TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))), ! NULL_TREE))); } + conversions = TREE_CHAIN (conversions); } /* If none of the conversion functions worked out, let our caller *************** convert_class_to_reference (t, s, expr) *** 1036,1051 **** if (!cand) return NULL_TREE; ! conv = build1 (IDENTITY_CONV, s, expr); ! conv = build_conv (USER_CONV, TREE_TYPE (TREE_TYPE (cand->fn)), ! conv); ! TREE_OPERAND (conv, 1) = build_ptr_wrapper (cand); ! ICS_USER_FLAG (conv) = 1; if (cand->viable == -1) ICS_BAD_FLAG (conv) = 1; - cand->second_conv = conv; ! return conv; } /* A reference of the indicated TYPE is being bound directly to the --- 1103,1123 ---- if (!cand) return NULL_TREE; ! /* Build a user-defined conversion sequence representing the ! conversion. */ ! conv = build_conv (USER_CONV, ! TREE_TYPE (TREE_TYPE (cand->fn)), ! build1 (IDENTITY_CONV, TREE_TYPE (expr), expr)); ! TREE_OPERAND (conv, 1) = build_zc_wrapper (cand); ! ! /* Merge it with the standard conversion sequence from the ! conversion function's return type to the desired type. */ ! cand->second_conv = merge_conversion_sequences (conv, cand->second_conv); ! if (cand->viable == -1) ICS_BAD_FLAG (conv) = 1; ! return cand->second_conv; } /* A reference of the indicated TYPE is being bound directly to the *************** direct_reference_binding (type, conv) *** 1057,1063 **** tree type; tree conv; { ! tree t = TREE_TYPE (type); /* [over.ics.rank] --- 1129,1141 ---- tree type; tree conv; { ! tree t; ! ! my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 20030306); ! my_friendly_assert (TREE_CODE (TREE_TYPE (conv)) != REFERENCE_TYPE, ! 20030306); ! ! t = TREE_TYPE (type); /* [over.ics.rank] *************** direct_reference_binding (type, conv) *** 1094,1102 **** the conversion returned. */ static tree ! reference_binding (rto, rfrom, expr, flags) ! tree rto, rfrom, expr; ! int flags; { tree conv = NULL_TREE; tree to = TREE_TYPE (rto); --- 1172,1178 ---- the conversion returned. */ static tree ! reference_binding (tree rto, tree rfrom, tree expr, int flags) { tree conv = NULL_TREE; tree to = TREE_TYPE (rto); *************** reference_binding (rto, rfrom, expr, fla *** 1174,1180 **** in the second case. */ conv = convert_class_to_reference (to, from, expr); if (conv) ! return direct_reference_binding (rto, conv); } /* From this point on, we conceptually need temporaries, even if we --- 1250,1256 ---- in the second case. */ conv = convert_class_to_reference (to, from, expr); if (conv) ! return conv; } /* From this point on, we conceptually need temporaries, even if we *************** reference_binding (rto, rfrom, expr, fla *** 1208,1218 **** -- The reference is bound to the object represented by the rvalue or to a sub-object within that object. ! In this case, the implicit conversion sequence is supposed to be ! same as we would obtain by generating a temporary. Fortunately, ! if the types are reference compatible, then this is either an ! identity conversion or the derived-to-base conversion, just as ! for direct binding. */ if (CLASS_TYPE_P (from) && compatible_p) { conv = build1 (IDENTITY_CONV, from, expr); --- 1284,1296 ---- -- The reference is bound to the object represented by the rvalue or to a sub-object within that object. ! -- ... ! ! We use the first alternative. The implicit conversion sequence ! is supposed to be same as we would obtain by generating a ! temporary. Fortunately, if the types are reference compatible, ! then this is either an identity conversion or the derived-to-base ! conversion, just as for direct binding. */ if (CLASS_TYPE_P (from) && compatible_p) { conv = build1 (IDENTITY_CONV, from, expr); *************** implicit_conversion (to, from, expr, fla *** 1252,1258 **** int flags; { tree conv; - struct z_candidate *cand; /* Resolve expressions like `A::p' that we thought might become pointers-to-members. */ --- 1330,1335 ---- *************** implicit_conversion (to, from, expr, fla *** 1278,1283 **** --- 1355,1362 ---- || IS_AGGR_TYPE (to)) && (flags & LOOKUP_NO_CONVERSION) == 0) { + struct z_candidate *cand; + cand = build_user_type_conversion_1 (to, expr, LOOKUP_ONLYCONVERTING); if (cand) *************** implicit_conversion (to, from, expr, fla *** 1295,1312 **** functions. */ static struct z_candidate * ! add_candidate (candidates, fn, convs, viable) ! struct z_candidate *candidates; ! tree fn, convs; ! int viable; { struct z_candidate *cand = (struct z_candidate *) ggc_alloc_cleared (sizeof (struct z_candidate)); cand->fn = fn; cand->convs = convs; cand->viable = viable; ! cand->next = candidates; return cand; } --- 1374,1393 ---- functions. */ static struct z_candidate * ! add_candidate (struct z_candidate **candidates, ! tree fn, tree convs, tree access_path, tree ! conversion_path, int viable) { struct z_candidate *cand = (struct z_candidate *) ggc_alloc_cleared (sizeof (struct z_candidate)); cand->fn = fn; cand->convs = convs; + cand->access_path = access_path; + cand->conversion_path = conversion_path; cand->viable = viable; ! cand->next = *candidates; ! *candidates = cand; return cand; } *************** add_candidate (candidates, fn, convs, vi *** 1319,1328 **** comes from for purposes of overload resolution. */ static struct z_candidate * ! add_function_candidate (candidates, fn, ctype, arglist, flags) ! struct z_candidate *candidates; ! tree fn, ctype, arglist; ! int flags; { tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn)); int i, len; --- 1400,1409 ---- comes from for purposes of overload resolution. */ static struct z_candidate * ! add_function_candidate (struct z_candidate **candidates, ! tree fn, tree ctype, tree arglist, ! tree access_path, tree conversion_path, ! int flags) { tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn)); int i, len; *************** add_function_candidate (candidates, fn, *** 1330,1335 **** --- 1411,1421 ---- tree parmnode, argnode; int viable = 1; + /* Built-in functions that haven't been declared don't really + exist. */ + if (DECL_ANTICIPATED (fn)) + return NULL; + /* The `this', `in_chrg' and VTT arguments to constructors are not considered in overload resolution. */ if (DECL_CONSTRUCTOR_P (fn)) *************** add_function_candidate (candidates, fn, *** 1434,1440 **** } out: ! return add_candidate (candidates, fn, convs, viable); } /* Create an overload candidate for the conversion function FN which will --- 1520,1527 ---- } out: ! return add_candidate (candidates, fn, convs, access_path, ! conversion_path, viable); } /* Create an overload candidate for the conversion function FN which will *************** add_function_candidate (candidates, fn, *** 1449,1457 **** instead of the function. */ static struct z_candidate * ! add_conv_candidate (candidates, fn, obj, arglist) ! struct z_candidate *candidates; tree fn, obj, arglist; { tree totype = TREE_TYPE (TREE_TYPE (fn)); int i, len, viable, flags; --- 1536,1547 ---- instead of the function. */ static struct z_candidate * ! add_conv_candidate (candidates, fn, obj, arglist, access_path, ! conversion_path) ! struct z_candidate **candidates; tree fn, obj, arglist; + tree access_path; + tree conversion_path; { tree totype = TREE_TYPE (TREE_TYPE (fn)); int i, len, viable, flags; *************** add_conv_candidate (candidates, fn, obj, *** 1469,1476 **** flags = LOOKUP_NORMAL; /* Don't bother looking up the same type twice. */ ! if (candidates && candidates->fn == totype) ! return candidates; for (i = 0; i < len; ++i) { --- 1559,1566 ---- flags = LOOKUP_NORMAL; /* Don't bother looking up the same type twice. */ ! if (*candidates && (*candidates)->fn == totype) ! return NULL; for (i = 0; i < len; ++i) { *************** add_conv_candidate (candidates, fn, obj, *** 1511,1523 **** if (!sufficient_parms_p (parmnode)) viable = 0; ! return add_candidate (candidates, totype, convs, viable); } ! static struct z_candidate * build_builtin_candidate (candidates, fnname, type1, type2, args, argtypes, flags) ! struct z_candidate *candidates; tree fnname, type1, type2, *args, *argtypes; int flags; --- 1601,1614 ---- if (!sufficient_parms_p (parmnode)) viable = 0; ! return add_candidate (candidates, totype, convs, access_path, ! conversion_path, viable); } ! static void build_builtin_candidate (candidates, fnname, type1, type2, args, argtypes, flags) ! struct z_candidate **candidates; tree fnname, type1, type2, *args, *argtypes; int flags; *************** build_builtin_candidate (candidates, fnn *** 1560,1566 **** viable = 0; } ! return add_candidate (candidates, fnname, convs, viable); } static int --- 1651,1660 ---- viable = 0; } ! add_candidate (candidates, fnname, convs, ! /*access_path=*/NULL_TREE, ! /*conversion_path=*/NULL_TREE, ! viable); } static int *************** is_complete (t) *** 1570,1576 **** return COMPLETE_TYPE_P (complete_type (t)); } ! /* Returns non-zero if TYPE is a promoted arithmetic type. */ static int promoted_arithmetic_type_p (type) --- 1664,1670 ---- return COMPLETE_TYPE_P (complete_type (t)); } ! /* Returns nonzero if TYPE is a promoted arithmetic type. */ static int promoted_arithmetic_type_p (type) *************** promoted_arithmetic_type_p (type) *** 1598,1607 **** of which TYPE1 and TYPE2 are, we add both candidates CODE (TYPE1, TYPE1) and CODE (TYPE2, TYPE2). */ ! static struct z_candidate * add_builtin_candidate (candidates, code, code2, fnname, type1, type2, args, argtypes, flags) ! struct z_candidate *candidates; enum tree_code code, code2; tree fnname, type1, type2, *args, *argtypes; int flags; --- 1692,1701 ---- of which TYPE1 and TYPE2 are, we add both candidates CODE (TYPE1, TYPE1) and CODE (TYPE2, TYPE2). */ ! static void add_builtin_candidate (candidates, code, code2, fnname, type1, type2, args, argtypes, flags) ! struct z_candidate **candidates; enum tree_code code, code2; tree fnname, type1, type2, *args, *argtypes; int flags; *************** add_builtin_candidate (candidates, code, *** 1641,1647 **** case POSTDECREMENT_EXPR: case PREDECREMENT_EXPR: if (TREE_CODE (type1) == BOOLEAN_TYPE) ! return candidates; case POSTINCREMENT_EXPR: case PREINCREMENT_EXPR: if (ARITHMETIC_TYPE_P (type1) || TYPE_PTROB_P (type1)) --- 1735,1741 ---- case POSTDECREMENT_EXPR: case PREDECREMENT_EXPR: if (TREE_CODE (type1) == BOOLEAN_TYPE) ! return; case POSTINCREMENT_EXPR: case PREINCREMENT_EXPR: if (ARITHMETIC_TYPE_P (type1) || TYPE_PTROB_P (type1)) *************** add_builtin_candidate (candidates, code, *** 1649,1655 **** type1 = build_reference_type (type1); break; } ! return candidates; /* 7 For every cv-qualified or cv-unqualified complete object type T, there exist candidate operator functions of the form --- 1743,1749 ---- type1 = build_reference_type (type1); break; } ! return; /* 7 For every cv-qualified or cv-unqualified complete object type T, there exist candidate operator functions of the form *************** add_builtin_candidate (candidates, code, *** 1665,1671 **** && (TYPE_PTROB_P (type1) || TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)) break; ! return candidates; /* 9 For every type T, there exist candidate operator functions of the form T* operator+(T*); --- 1759,1765 ---- && (TYPE_PTROB_P (type1) || TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)) break; ! return; /* 9 For every type T, there exist candidate operator functions of the form T* operator+(T*); *************** add_builtin_candidate (candidates, code, *** 1682,1688 **** case NEGATE_EXPR: if (ARITHMETIC_TYPE_P (type1)) break; ! return candidates; /* 11For every promoted integral type T, there exist candidate operator functions of the form --- 1776,1782 ---- case NEGATE_EXPR: if (ARITHMETIC_TYPE_P (type1)) break; ! return; /* 11For every promoted integral type T, there exist candidate operator functions of the form *************** add_builtin_candidate (candidates, code, *** 1691,1697 **** case BIT_NOT_EXPR: if (INTEGRAL_TYPE_P (type1)) break; ! return candidates; /* 12For every quintuple C1, C2, T, CV1, CV2), where C2 is a class type, C1 is the same type as C2 or is a derived class of C2, T is a complete --- 1785,1791 ---- case BIT_NOT_EXPR: if (INTEGRAL_TYPE_P (type1)) break; ! return; /* 12For every quintuple C1, C2, T, CV1, CV2), where C2 is a class type, C1 is the same type as C2 or is a derived class of C2, T is a complete *************** add_builtin_candidate (candidates, code, *** 1714,1720 **** || is_complete (TREE_TYPE (TREE_TYPE (type2))))) break; } ! return candidates; /* 13For every pair of promoted arithmetic types L and R, there exist can- didate operator functions of the form --- 1808,1814 ---- || is_complete (TREE_TYPE (TREE_TYPE (type2))))) break; } ! return; /* 13For every pair of promoted arithmetic types L and R, there exist can- didate operator functions of the form *************** add_builtin_candidate (candidates, code, *** 1770,1776 **** case TRUNC_DIV_EXPR: if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) break; ! return candidates; case EQ_EXPR: case NE_EXPR: --- 1864,1870 ---- case TRUNC_DIV_EXPR: if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) break; ! return; case EQ_EXPR: case NE_EXPR: *************** add_builtin_candidate (candidates, code, *** 1812,1818 **** type1 = type2; break; } ! return candidates; case PLUS_EXPR: if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) --- 1906,1912 ---- type1 = type2; break; } ! return; case PLUS_EXPR: if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) *************** add_builtin_candidate (candidates, code, *** 1828,1834 **** type2 = ptrdiff_type_node; break; } ! return candidates; /* 18For every pair of promoted integral types L and R, there exist candi- date operator functions of the form --- 1922,1928 ---- type2 = ptrdiff_type_node; break; } ! return; /* 18For every pair of promoted integral types L and R, there exist candi- date operator functions of the form *************** add_builtin_candidate (candidates, code, *** 1849,1855 **** case RSHIFT_EXPR: if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)) break; ! return candidates; /* 19For every triple L, VQ, R), where L is an arithmetic or enumeration type, VQ is either volatile or empty, and R is a promoted arithmetic --- 1943,1949 ---- case RSHIFT_EXPR: if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)) break; ! return; /* 19For every triple L, VQ, R), where L is an arithmetic or enumeration type, VQ is either volatile or empty, and R is a promoted arithmetic *************** add_builtin_candidate (candidates, code, *** 1901,1907 **** case TRUNC_DIV_EXPR: if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) break; ! return candidates; case TRUNC_MOD_EXPR: case BIT_AND_EXPR: --- 1995,2001 ---- case TRUNC_DIV_EXPR: if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) break; ! return; case TRUNC_MOD_EXPR: case BIT_AND_EXPR: *************** add_builtin_candidate (candidates, code, *** 1911,1917 **** case RSHIFT_EXPR: if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)) break; ! return candidates; case NOP_EXPR: if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) --- 2005,2011 ---- case RSHIFT_EXPR: if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)) break; ! return; case NOP_EXPR: if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) *************** add_builtin_candidate (candidates, code, *** 1926,1932 **** type2 = type1; break; } ! return candidates; default: abort (); --- 2020,2026 ---- type2 = type1; break; } ! return; default: abort (); *************** add_builtin_candidate (candidates, code, *** 1961,1976 **** || !(TREE_CODE (type2) == POINTER_TYPE || TYPE_PTRMEM_P (type2) || TYPE_PTRMEMFUNC_P (type2))) ! return candidates; /* We don't check that the two types are the same; the logic below will actually create two candidates; one in which both parameter types are TYPE1, and one in which both parameter types are TYPE2. */ ! break; ! ! /* These arguments do not make for a legal overloaded operator. */ ! return candidates; default: abort (); --- 2055,2067 ---- || !(TREE_CODE (type2) == POINTER_TYPE || TYPE_PTRMEM_P (type2) || TYPE_PTRMEMFUNC_P (type2))) ! return; /* We don't check that the two types are the same; the logic below will actually create two candidates; one in which both parameter types are TYPE1, and one in which both parameter types are TYPE2. */ ! break; default: abort (); *************** add_builtin_candidate (candidates, code, *** 1987,1999 **** || IS_AGGR_TYPE (type1) || TREE_CODE (type1) == ENUMERAL_TYPE)) { ! candidates = build_builtin_candidate (candidates, fnname, type1, type1, args, argtypes, flags); ! return build_builtin_candidate (candidates, fnname, type2, type2, args, argtypes, flags); } ! return build_builtin_candidate (candidates, fnname, type1, type2, args, argtypes, flags); } --- 2078,2091 ---- || IS_AGGR_TYPE (type1) || TREE_CODE (type1) == ENUMERAL_TYPE)) { ! build_builtin_candidate (candidates, fnname, type1, type1, args, argtypes, flags); ! build_builtin_candidate (candidates, fnname, type2, type2, args, argtypes, flags); + return; } ! build_builtin_candidate (candidates, fnname, type1, type2, args, argtypes, flags); } *************** type_decays_to (type) *** 2019,2029 **** Here we generate a superset of the possible candidates for this particular case. That is a subset of the full set the standard defines, plus some other cases which the standard disallows. add_builtin_candidate will ! filter out the illegal set. */ ! static struct z_candidate * add_builtin_candidates (candidates, code, code2, fnname, args, flags) ! struct z_candidate *candidates; enum tree_code code, code2; tree fnname, *args; int flags; --- 2111,2121 ---- Here we generate a superset of the possible candidates for this particular case. That is a subset of the full set the standard defines, plus some other cases which the standard disallows. add_builtin_candidate will ! filter out the invalid set. */ ! static void add_builtin_candidates (candidates, code, code2, fnname, args, flags) ! struct z_candidate **candidates; enum tree_code code, code2; tree fnname, *args; int flags; *************** add_builtin_candidates (candidates, code *** 2066,2085 **** bool operator||(bool, bool); */ case TRUTH_NOT_EXPR: ! return build_builtin_candidate (candidates, fnname, boolean_type_node, NULL_TREE, args, argtypes, flags); case TRUTH_ORIF_EXPR: case TRUTH_ANDIF_EXPR: ! return build_builtin_candidate (candidates, fnname, boolean_type_node, boolean_type_node, args, argtypes, flags); case ADDR_EXPR: case COMPOUND_EXPR: case COMPONENT_REF: ! return candidates; case COND_EXPR: case EQ_EXPR: --- 2158,2179 ---- bool operator||(bool, bool); */ case TRUTH_NOT_EXPR: ! build_builtin_candidate (candidates, fnname, boolean_type_node, NULL_TREE, args, argtypes, flags); + return; case TRUTH_ORIF_EXPR: case TRUTH_ANDIF_EXPR: ! build_builtin_candidate (candidates, fnname, boolean_type_node, boolean_type_node, args, argtypes, flags); + return; case ADDR_EXPR: case COMPOUND_EXPR: case COMPONENT_REF: ! return; case COND_EXPR: case EQ_EXPR: *************** add_builtin_candidates (candidates, code *** 2106,2112 **** tree convs; if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR) ! return candidates; convs = lookup_conversions (argtypes[i]); --- 2200,2206 ---- tree convs; if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR) ! return; convs = lookup_conversions (argtypes[i]); *************** add_builtin_candidates (candidates, code *** 2121,2127 **** } else if (! convs) ! return candidates; for (; convs; convs = TREE_CHAIN (convs)) { --- 2215,2221 ---- } else if (! convs) ! return; for (; convs; convs = TREE_CHAIN (convs)) { *************** add_builtin_candidates (candidates, code *** 2173,2188 **** { if (types[1]) for (type = types[1]; type; type = TREE_CHAIN (type)) ! candidates = add_builtin_candidate (candidates, code, code2, fnname, TREE_VALUE (types[0]), TREE_VALUE (type), args, argtypes, flags); else ! candidates = add_builtin_candidate (candidates, code, code2, fnname, TREE_VALUE (types[0]), NULL_TREE, args, argtypes, flags); } ! return candidates; } --- 2267,2282 ---- { if (types[1]) for (type = types[1]; type; type = TREE_CHAIN (type)) ! add_builtin_candidate (candidates, code, code2, fnname, TREE_VALUE (types[0]), TREE_VALUE (type), args, argtypes, flags); else ! add_builtin_candidate (candidates, code, code2, fnname, TREE_VALUE (types[0]), NULL_TREE, args, argtypes, flags); } ! return; } *************** add_builtin_candidates (candidates, code *** 2198,2207 **** static struct z_candidate* add_template_candidate_real (candidates, tmpl, ctype, explicit_targs, ! arglist, return_type, flags, ! obj, strict) ! struct z_candidate *candidates; tree tmpl, ctype, explicit_targs, arglist, return_type; int flags; tree obj; unification_kind_t strict; --- 2292,2303 ---- static struct z_candidate* add_template_candidate_real (candidates, tmpl, ctype, explicit_targs, ! arglist, return_type, access_path, ! conversion_path, flags, obj, strict) ! struct z_candidate **candidates; tree tmpl, ctype, explicit_targs, arglist, return_type; + tree access_path; + tree conversion_path; int flags; tree obj; unification_kind_t strict; *************** add_template_candidate_real (candidates, *** 2228,2238 **** return_type, strict, -1); if (i != 0) ! return candidates; fn = instantiate_template (tmpl, targs); if (fn == error_mark_node) ! return candidates; /* In [class.copy]: --- 2324,2334 ---- return_type, strict, -1); if (i != 0) ! return NULL; fn = instantiate_template (tmpl, targs); if (fn == error_mark_node) ! return NULL; /* In [class.copy]: *************** add_template_candidate_real (candidates, *** 2261,2275 **** tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn); if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)), ctype)) ! return candidates; } if (obj != NULL_TREE) /* Aha, this is a conversion function. */ ! cand = add_conv_candidate (candidates, fn, obj, arglist); else cand = add_function_candidate (candidates, fn, ctype, ! arglist, flags); if (DECL_TI_TEMPLATE (fn) != tmpl) /* This situation can occur if a member template of a template class is specialized. Then, instantiate_template might return --- 2357,2373 ---- tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn); if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)), ctype)) ! return NULL; } if (obj != NULL_TREE) /* Aha, this is a conversion function. */ ! cand = add_conv_candidate (candidates, fn, obj, access_path, ! conversion_path, arglist); else cand = add_function_candidate (candidates, fn, ctype, ! arglist, access_path, ! conversion_path, flags); if (DECL_TI_TEMPLATE (fn) != tmpl) /* This situation can occur if a member template of a template class is specialized. Then, instantiate_template might return *************** add_template_candidate_real (candidates, *** 2298,2324 **** static struct z_candidate * add_template_candidate (candidates, tmpl, ctype, explicit_targs, ! arglist, return_type, flags, strict) ! struct z_candidate *candidates; tree tmpl, ctype, explicit_targs, arglist, return_type; int flags; unification_kind_t strict; { return add_template_candidate_real (candidates, tmpl, ctype, ! explicit_targs, arglist, return_type, flags, ! NULL_TREE, strict); } static struct z_candidate * ! add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type) ! struct z_candidate *candidates; tree tmpl, obj, arglist, return_type; { return add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE, ! arglist, return_type, 0, obj, DEDUCE_CONV); } --- 2396,2430 ---- static struct z_candidate * add_template_candidate (candidates, tmpl, ctype, explicit_targs, ! arglist, return_type, access_path, ! conversion_path, flags, strict) ! struct z_candidate **candidates; tree tmpl, ctype, explicit_targs, arglist, return_type; + tree access_path; + tree conversion_path; int flags; unification_kind_t strict; { return add_template_candidate_real (candidates, tmpl, ctype, ! explicit_targs, arglist, return_type, ! access_path, conversion_path, ! flags, NULL_TREE, strict); } static struct z_candidate * ! add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type, ! access_path, conversion_path) ! struct z_candidate **candidates; tree tmpl, obj, arglist, return_type; + tree access_path; + tree conversion_path; { return add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE, ! arglist, return_type, access_path, ! conversion_path, 0, obj, DEDUCE_CONV); } *************** any_viable (cands) *** 2332,2337 **** --- 2438,2453 ---- return 0; } + static int + any_strictly_viable (cands) + struct z_candidate *cands; + { + for (; cands; cands = cands->next) + if (cands->viable == 1) + return 1; + return 0; + } + static struct z_candidate * splice_viable (cands) struct z_candidate *cands; *************** build_this (obj) *** 2357,2367 **** return build_unary_op (ADDR_EXPR, obj, 0); } static void ! print_z_candidates (candidates) ! struct z_candidate *candidates; { ! const char *str = "candidates are:"; for (; candidates; candidates = candidates->next) { if (TREE_CODE (candidates->fn) == IDENTIFIER_NODE) --- 2473,2523 ---- return build_unary_op (ADDR_EXPR, obj, 0); } + /* Returns true iff functions are equivalent. Equivalent functions are + not '==' only if one is a function-local extern function or if + both are extern "C". */ + + static inline int + equal_functions (fn1, fn2) + tree fn1; + tree fn2; + { + if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2) + || DECL_EXTERN_C_FUNCTION_P (fn1)) + return decls_match (fn1, fn2); + return fn1 == fn2; + } + static void ! print_z_candidates (struct z_candidate *candidates) { ! const char *str; ! struct z_candidate *cand1; ! struct z_candidate **cand2; ! ! /* There may be duplicates in the set of candidates. We put off ! checking this condition as long as possible, since we have no way ! to eliminate duplicates from a set of functions in less than n^2 ! time. Now we are about to emit an error message, so it is more ! permissible to go slowly. */ ! for (cand1 = candidates; cand1; cand1 = cand1->next) ! { ! tree fn = cand1->fn; ! /* Skip builtin candidates and conversion functions. */ ! if (TREE_CODE (fn) != FUNCTION_DECL) ! continue; ! cand2 = &cand1->next; ! while (*cand2) ! { ! if (TREE_CODE ((*cand2)->fn) == FUNCTION_DECL ! && equal_functions (fn, (*cand2)->fn)) ! *cand2 = (*cand2)->next; ! else ! cand2 = &(*cand2)->next; ! } ! } ! ! str = "candidates are:"; for (; candidates; candidates = candidates->next) { if (TREE_CODE (candidates->fn) == IDENTIFIER_NODE) *************** print_z_candidates (candidates) *** 2388,2393 **** --- 2544,2578 ---- } } + /* USER_SEQ is a user-defined conversion sequence, beginning with a + USER_CONV. STD_SEQ is the standard conversion sequence applied to + the result of the conversion function to convert it to the final + desired type. Merge the the two sequences into a single sequence, + and return the merged sequence. */ + + static tree + merge_conversion_sequences (tree user_seq, tree std_seq) + { + tree *t; + + my_friendly_assert (TREE_CODE (user_seq) == USER_CONV, + 20030306); + + /* Find the end of the second conversion sequence. */ + t = &(std_seq); + while (TREE_CODE (*t) != IDENTITY_CONV) + t = &TREE_OPERAND (*t, 0); + + /* Replace the identity conversion with the user conversion + sequence. */ + *t = user_seq; + + /* The entire sequence is a user-conversion sequence. */ + ICS_USER_FLAG (std_seq) = 1; + + return std_seq; + } + /* Returns the best overload candidate to perform the requested conversion. This function is used for three the overloading situations described in [over.match.copy], [over.match.conv], and [over.match.ref]. *************** build_user_type_conversion_1 (totype, ex *** 2401,2409 **** { struct z_candidate *candidates, *cand; tree fromtype = TREE_TYPE (expr); ! tree ctors = NULL_TREE, convs = NULL_TREE, *p; tree args = NULL_TREE; - tree templates = NULL_TREE; /* We represent conversion within a hierarchy using RVALUE_CONV and BASE_CONV, as specified by [over.best.ics]; these become plain --- 2586,2593 ---- { struct z_candidate *candidates, *cand; tree fromtype = TREE_TYPE (expr); ! tree ctors = NULL_TREE, convs = NULL_TREE; tree args = NULL_TREE; /* We represent conversion within a hierarchy using RVALUE_CONV and BASE_CONV, as specified by [over.best.ics]; these become plain *************** build_user_type_conversion_1 (totype, ex *** 2426,2432 **** { tree t; ! ctors = TREE_VALUE (ctors); t = build_int_2 (0, 0); TREE_TYPE (t) = build_pointer_type (totype); --- 2610,2616 ---- { tree t; ! ctors = BASELINK_FUNCTIONS (ctors); t = build_int_2 (0, 0); TREE_TYPE (t) = build_pointer_type (totype); *************** build_user_type_conversion_1 (totype, ex *** 2445,2466 **** continue; if (TREE_CODE (ctor) == TEMPLATE_DECL) ! { ! templates = tree_cons (NULL_TREE, ctor, templates); ! candidates = ! add_template_candidate (candidates, ctor, totype, ! NULL_TREE, args, NULL_TREE, flags, ! DEDUCE_CALL); ! } else ! candidates = add_function_candidate (candidates, ctor, totype, ! args, flags); ! if (candidates) ! { ! candidates->second_conv = build1 (IDENTITY_CONV, totype, NULL_TREE); ! candidates->basetype_path = TYPE_BINFO (totype); ! } } if (convs) --- 2629,2648 ---- continue; if (TREE_CODE (ctor) == TEMPLATE_DECL) ! cand = add_template_candidate (&candidates, ctor, totype, ! NULL_TREE, args, NULL_TREE, ! TYPE_BINFO (totype), ! TYPE_BINFO (totype), ! flags, ! DEDUCE_CALL); else ! cand = add_function_candidate (&candidates, ctor, totype, ! args, TYPE_BINFO (totype), ! TYPE_BINFO (totype), ! flags); ! if (cand) ! cand->second_conv = build1 (IDENTITY_CONV, totype, NULL_TREE); } if (convs) *************** build_user_type_conversion_1 (totype, ex *** 2468,2476 **** for (; convs; convs = TREE_CHAIN (convs)) { ! tree fns = TREE_VALUE (convs); int convflags = LOOKUP_NO_CONVERSION; - tree ics; /* If we are called to convert to a reference type, we are trying to find an lvalue binding, so don't even consider temporaries. If --- 2650,2658 ---- for (; convs; convs = TREE_CHAIN (convs)) { ! tree fns; ! tree conversion_path = TREE_PURPOSE (convs); int convflags = LOOKUP_NO_CONVERSION; /* If we are called to convert to a reference type, we are trying to find an lvalue binding, so don't even consider temporaries. If *************** build_user_type_conversion_1 (totype, ex *** 2478,2550 **** look for a temporary binding. */ if (TREE_CODE (totype) == REFERENCE_TYPE) convflags |= LOOKUP_NO_TEMP_BIND; ! if (TREE_CODE (OVL_CURRENT (fns)) != TEMPLATE_DECL) ! ics = implicit_conversion ! (totype, TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns))), 0, convflags); ! else ! /* We can't compute this yet. */ ! ics = error_mark_node; ! ! if (TREE_CODE (totype) == REFERENCE_TYPE && ics && ICS_BAD_FLAG (ics)) ! /* ignore the near match. */; ! else if (ics) ! for (; fns; fns = OVL_NEXT (fns)) ! { ! tree fn = OVL_CURRENT (fns); ! struct z_candidate *old_candidates = candidates; ! ! /* [over.match.funcs] For conversion functions, the function is ! considered to be a member of the class of the implicit object ! argument for the purpose of defining the type of the implicit ! object parameter. ! ! So we pass fromtype as CTYPE to add_*_candidate. */ ! ! if (TREE_CODE (fn) == TEMPLATE_DECL) ! { ! templates = tree_cons (NULL_TREE, fn, templates); ! candidates = ! add_template_candidate (candidates, fn, fromtype, NULL_TREE, ! args, totype, flags, ! DEDUCE_CONV); ! } ! else ! candidates = add_function_candidate (candidates, fn, fromtype, ! args, flags); ! if (candidates != old_candidates) ! { ! if (TREE_CODE (fn) == TEMPLATE_DECL) ! ics = implicit_conversion ! (totype, TREE_TYPE (TREE_TYPE (candidates->fn)), ! 0, convflags); ! candidates->second_conv = ics; ! candidates->basetype_path = TYPE_BINFO (fromtype); ! if (ics == NULL_TREE) ! candidates->viable = 0; ! else if (candidates->viable == 1 && ICS_BAD_FLAG (ics)) ! candidates->viable = -1; ! } ! } } if (! any_viable (candidates)) ! { ! #if 0 ! if (flags & LOOKUP_COMPLAIN) ! { ! if (candidates && ! candidates->next) ! /* say why this one won't work or try to be loose */; ! else ! error ("no viable candidates"); ! } ! #endif ! ! return 0; ! } candidates = splice_viable (candidates); cand = tourney (candidates); --- 2660,2709 ---- look for a temporary binding. */ if (TREE_CODE (totype) == REFERENCE_TYPE) convflags |= LOOKUP_NO_TEMP_BIND; + + for (fns = TREE_VALUE (convs); fns; fns = OVL_NEXT (fns)) + { + tree fn = OVL_CURRENT (fns); + + /* [over.match.funcs] For conversion functions, the function + is considered to be a member of the class of the implicit + object argument for the purpose of defining the type of + the implicit object parameter. ! So we pass fromtype as CTYPE to add_*_candidate. */ ! if (TREE_CODE (fn) == TEMPLATE_DECL) ! cand = add_template_candidate (&candidates, fn, fromtype, NULL_TREE, ! args, totype, ! TYPE_BINFO (fromtype), ! conversion_path, ! flags, ! DEDUCE_CONV); ! else ! cand = add_function_candidate (&candidates, fn, fromtype, ! args, ! TYPE_BINFO (fromtype), ! conversion_path, ! flags); ! if (cand) ! { ! tree ics = implicit_conversion ! (totype, TREE_TYPE (TREE_TYPE (cand->fn)), ! 0, convflags); ! cand->second_conv = ics; ! ! if (ics == NULL_TREE) ! cand->viable = 0; ! else if (cand->viable == 1 && ICS_BAD_FLAG (ics)) ! cand->viable = -1; ! } ! } } if (! any_viable (candidates)) ! return 0; candidates = splice_viable (candidates); cand = tourney (candidates); *************** build_user_type_conversion_1 (totype, ex *** 2561,2583 **** cand = candidates; /* any one will do */ cand->second_conv = build1 (AMBIG_CONV, totype, expr); ICS_USER_FLAG (cand->second_conv) = 1; ! ICS_BAD_FLAG (cand->second_conv) = 1; return cand; } ! for (p = &(cand->second_conv); TREE_CODE (*p) != IDENTITY_CONV; ) ! p = &(TREE_OPERAND (*p, 0)); ! ! *p = build (USER_CONV, (DECL_CONSTRUCTOR_P (cand->fn) ? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))), ! expr, build_ptr_wrapper (cand)); ! ! ICS_USER_FLAG (cand->second_conv) = ICS_USER_FLAG (*p) = 1; if (cand->viable == -1) ! ICS_BAD_FLAG (cand->second_conv) = ICS_BAD_FLAG (*p) = 1; return cand; } --- 2720,2748 ---- cand = candidates; /* any one will do */ cand->second_conv = build1 (AMBIG_CONV, totype, expr); ICS_USER_FLAG (cand->second_conv) = 1; ! if (!any_strictly_viable (candidates)) ! ICS_BAD_FLAG (cand->second_conv) = 1; ! /* If there are viable candidates, don't set ICS_BAD_FLAG; an ! ambiguous conversion is no worse than another user-defined ! conversion. */ return cand; } ! /* Build the user conversion sequence. */ ! convs = build_conv (USER_CONV, (DECL_CONSTRUCTOR_P (cand->fn) ? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))), ! build1 (IDENTITY_CONV, TREE_TYPE (expr), expr)); ! TREE_OPERAND (convs, 1) = build_zc_wrapper (cand); ! ! /* Combine it with the second conversion sequence. */ ! cand->second_conv = merge_conversion_sequences (convs, ! cand->second_conv); ! if (cand->viable == -1) ! ICS_BAD_FLAG (cand->second_conv) = 1; return cand; } *************** build_user_type_conversion (totype, expr *** 2599,2604 **** --- 2764,2836 ---- return NULL_TREE; } + /* Find the possibly overloaded set of functions corresponding to a + call of the form SCOPE::NAME (...). NAME might be a + TEMPLATE_ID_EXPR, OVERLOAD, _DECL, IDENTIFIER_NODE or LOOKUP_EXPR. */ + + tree + resolve_scoped_fn_name (tree scope, tree name) + { + tree fn; + tree template_args = NULL_TREE; + bool is_template_id = TREE_CODE (name) == TEMPLATE_ID_EXPR; + + if (is_template_id) + { + template_args = TREE_OPERAND (name, 1); + name = TREE_OPERAND (name, 0); + } + if (TREE_CODE (name) == OVERLOAD) + name = DECL_NAME (get_first_fn (name)); + else if (TREE_CODE (name) == LOOKUP_EXPR) + name = TREE_OPERAND (name, 0); + + if (TREE_CODE (scope) == NAMESPACE_DECL) + fn = lookup_namespace_name (scope, name); + else + { + if (!TYPE_BEING_DEFINED (scope) + && !COMPLETE_TYPE_P (complete_type (scope))) + { + error ("incomplete type '%T' cannot be used to name a scope", + scope); + return error_mark_node; + } + + if (BASELINK_P (name)) + fn = name; + else + fn = lookup_member (scope, name, /*protect=*/1, /*prefer_type=*/0); + if (fn && current_class_type) + fn = (adjust_result_of_qualified_name_lookup + (fn, scope, current_class_type)); + + /* It might be the name of a function pointer member. */ + if (fn && TREE_CODE (fn) == FIELD_DECL) + fn = resolve_offset_ref (build_offset_ref (scope, fn)); + } + + if (!fn) + { + error ("'%D' has no member named '%E'", scope, name); + return error_mark_node; + } + if (is_template_id) + { + tree fns = fn; + + if (BASELINK_P (fn)) + fns = BASELINK_FUNCTIONS (fns); + fns = build_nt (TEMPLATE_ID_EXPR, fns, template_args); + if (BASELINK_P (fn)) + BASELINK_FUNCTIONS (fn) = fns; + else + fn = fns; + } + + return fn; + } + /* Do any initial processing on the arguments to a function call. */ static tree *************** resolve_args (args) *** 2624,2629 **** --- 2856,2864 ---- } return args; } + + /* Return an expression for a call to FN (a namespace-scope function) + with the ARGS. */ tree build_new_function_call (fn, args) *************** build_new_function_call (fn, args) *** 2633,2638 **** --- 2868,2882 ---- tree explicit_targs = NULL_TREE; int template_only = 0; + /* Check FN and ARGS. */ + my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL + || TREE_CODE (fn) == TEMPLATE_DECL + || TREE_CODE (fn) == OVERLOAD + || TREE_CODE (fn) == TEMPLATE_ID_EXPR, + 20020712); + my_friendly_assert (!args || TREE_CODE (args) == TREE_LIST, + 20020712); + if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) { explicit_targs = TREE_OPERAND (fn, 1); *************** build_new_function_call (fn, args) *** 2640,2669 **** template_only = 1; } ! if (really_overloaded_fn (fn)) { tree t1; - tree templates = NULL_TREE; args = resolve_args (args); if (args == error_mark_node) return error_mark_node; ! for (t1 = fn; t1; t1 = OVL_CHAIN (t1)) { ! tree t = OVL_FUNCTION (t1); if (TREE_CODE (t) == TEMPLATE_DECL) ! { ! templates = tree_cons (NULL_TREE, t, templates); ! candidates = add_template_candidate ! (candidates, t, NULL_TREE, explicit_targs, args, NULL_TREE, ! LOOKUP_NORMAL, DEDUCE_CALL); ! } else if (! template_only) ! candidates = add_function_candidate ! (candidates, t, NULL_TREE, args, LOOKUP_NORMAL); } if (! any_viable (candidates)) --- 2884,2913 ---- template_only = 1; } ! if (really_overloaded_fn (fn) ! || TREE_CODE (fn) == TEMPLATE_DECL) { tree t1; args = resolve_args (args); if (args == error_mark_node) return error_mark_node; ! for (t1 = fn; t1; t1 = OVL_NEXT (t1)) { ! tree t = OVL_CURRENT (t1); if (TREE_CODE (t) == TEMPLATE_DECL) ! add_template_candidate ! (&candidates, t, NULL_TREE, explicit_targs, args, ! NULL_TREE, ! /*access_path=*/NULL_TREE, /*conversion_path=*/NULL_TREE, ! LOOKUP_NORMAL, DEDUCE_CALL); else if (! template_only) ! add_function_candidate ! (&candidates, t, NULL_TREE, args, /*access_path=*/NULL_TREE, ! /*conversion_path=*/NULL_TREE, LOOKUP_NORMAL); } if (! any_viable (candidates)) *************** build_new_function_call (fn, args) *** 2671,2677 **** if (candidates && ! candidates->next) return build_function_call (candidates->fn, args); error ("no matching function for call to `%D(%A)'", ! DECL_NAME (OVL_FUNCTION (fn)), args); if (candidates) print_z_candidates (candidates); return error_mark_node; --- 2915,2921 ---- if (candidates && ! candidates->next) return build_function_call (candidates->fn, args); error ("no matching function for call to `%D(%A)'", ! DECL_NAME (OVL_CURRENT (fn)), args); if (candidates) print_z_candidates (candidates); return error_mark_node; *************** build_new_function_call (fn, args) *** 2690,2696 **** return build_over_call (cand, args, LOOKUP_NORMAL); } ! /* This is not really overloaded. */ fn = OVL_CURRENT (fn); return build_function_call (fn, args); --- 2934,2940 ---- return build_over_call (cand, args, LOOKUP_NORMAL); } ! /* This is not really overloaded. */ fn = OVL_CURRENT (fn); return build_function_call (fn, args); *************** build_object_call (obj, args) *** 2723,2747 **** if (fns) { ! tree base = BINFO_TYPE (TREE_PURPOSE (fns)); mem_args = tree_cons (NULL_TREE, build_this (obj), args); ! for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); if (TREE_CODE (fn) == TEMPLATE_DECL) ! { ! candidates ! = add_template_candidate (candidates, fn, base, NULL_TREE, ! mem_args, NULL_TREE, ! LOOKUP_NORMAL, DEDUCE_CALL); ! } else ! candidates = add_function_candidate ! (candidates, fn, base, mem_args, LOOKUP_NORMAL); ! ! if (candidates) ! candidates->basetype_path = TYPE_BINFO (type); } } --- 2967,2988 ---- if (fns) { ! tree base = BINFO_TYPE (BASELINK_BINFO (fns)); mem_args = tree_cons (NULL_TREE, build_this (obj), args); ! for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); if (TREE_CODE (fn) == TEMPLATE_DECL) ! add_template_candidate (&candidates, fn, base, NULL_TREE, ! mem_args, NULL_TREE, ! TYPE_BINFO (type), ! TYPE_BINFO (type), ! LOOKUP_NORMAL, DEDUCE_CALL); else ! add_function_candidate ! (&candidates, fn, base, mem_args, TYPE_BINFO (type), ! TYPE_BINFO (type), LOOKUP_NORMAL); } } *************** build_object_call (obj, args) *** 2763,2777 **** { tree fn = OVL_CURRENT (fns); if (TREE_CODE (fn) == TEMPLATE_DECL) ! { ! candidates = add_template_conv_candidate (candidates, ! fn, ! obj, ! args, ! totype); ! } else ! candidates = add_conv_candidate (candidates, fn, obj, args); } } --- 3004,3017 ---- { tree fn = OVL_CURRENT (fns); if (TREE_CODE (fn) == TEMPLATE_DECL) ! add_template_conv_candidate ! (&candidates, fn, obj, args, totype, ! /*access_path=*/NULL_TREE, ! /*conversion_path=*/NULL_TREE); else ! add_conv_candidate (&candidates, fn, obj, args, ! /*conversion_path=*/NULL_TREE, ! /*access_path=*/NULL_TREE); } } *************** conditional_conversion (e1, e2) *** 2905,2913 **** } /* Implement [expr.cond]. ARG1, ARG2, and ARG3 are the three ! arguments to the conditional expression. By the time this function ! is called, any suitable candidate functions are included in ! CANDIDATES. */ tree build_conditional_expr (arg1, arg2, arg3) --- 3145,3151 ---- } /* Implement [expr.cond]. ARG1, ARG2, and ARG3 are the three ! arguments to the conditional expression. */ tree build_conditional_expr (arg1, arg2, arg3) *************** build_conditional_expr (arg1, arg2, arg3 *** 2980,2986 **** type of the other and is an rvalue. --Both the second and the third operands have type void; the ! result is of type void and is an rvalue. */ if ((TREE_CODE (arg2) == THROW_EXPR) ^ (TREE_CODE (arg3) == THROW_EXPR)) result_type = ((TREE_CODE (arg2) == THROW_EXPR) --- 3218,3224 ---- type of the other and is an rvalue. --Both the second and the third operands have type void; the ! result is of type void and is an rvalue. */ if ((TREE_CODE (arg2) == THROW_EXPR) ^ (TREE_CODE (arg3) == THROW_EXPR)) result_type = ((TREE_CODE (arg2) == THROW_EXPR) *************** build_conditional_expr (arg1, arg2, arg3 *** 3081,3092 **** args[0] = arg2; args[1] = arg3; args[2] = arg1; ! candidates = add_builtin_candidates (candidates, ! COND_EXPR, ! NOP_EXPR, ! ansi_opname (COND_EXPR), ! args, ! LOOKUP_NORMAL); /* [expr.cond] --- 3319,3330 ---- args[0] = arg2; args[1] = arg3; args[2] = arg1; ! add_builtin_candidates (&candidates, ! COND_EXPR, ! NOP_EXPR, ! ansi_opname (COND_EXPR), ! args, ! LOOKUP_NORMAL); /* [expr.cond] *************** build_conditional_expr (arg1, arg2, arg3 *** 3134,3151 **** We use ocp_convert rather than build_user_type_conversion because the latter returns NULL_TREE on failure, while the former gives an error. */ ! if (IS_AGGR_TYPE (TREE_TYPE (arg2)) && real_lvalue_p (arg2)) ! arg2 = ocp_convert (TREE_TYPE (arg2), arg2, ! CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL); ! else ! arg2 = decay_conversion (arg2); arg2_type = TREE_TYPE (arg2); ! if (IS_AGGR_TYPE (TREE_TYPE (arg3)) && real_lvalue_p (arg3)) ! arg3 = ocp_convert (TREE_TYPE (arg3), arg3, ! CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL); ! else ! arg3 = decay_conversion (arg3); arg3_type = TREE_TYPE (arg3); if (arg2 == error_mark_node || arg3 == error_mark_node) --- 3372,3381 ---- We use ocp_convert rather than build_user_type_conversion because the latter returns NULL_TREE on failure, while the former gives an error. */ ! arg2 = force_rvalue (arg2); arg2_type = TREE_TYPE (arg2); ! arg3 = force_rvalue (arg3); arg3_type = TREE_TYPE (arg3); if (arg2 == error_mark_node || arg3 == error_mark_node) *************** build_conditional_expr (arg1, arg2, arg3 *** 3202,3208 **** qualification conversions (_conv.qual_) are performed to bring them to a common type, whose cv-qualification shall match the cv-qualification of either the second or the third operand. ! The result is of the common type. */ else if ((null_ptr_cst_p (arg2) && (TYPE_PTR_P (arg3_type) || TYPE_PTRMEM_P (arg3_type) || TYPE_PTRMEMFUNC_P (arg3_type))) --- 3432,3438 ---- qualification conversions (_conv.qual_) are performed to bring them to a common type, whose cv-qualification shall match the cv-qualification of either the second or the third operand. ! The result is of the common type. */ else if ((null_ptr_cst_p (arg2) && (TYPE_PTR_P (arg3_type) || TYPE_PTRMEM_P (arg3_type) || TYPE_PTRMEMFUNC_P (arg3_type))) *************** build_new_op (code, flags, arg1, arg2, a *** 3251,3258 **** struct z_candidate *candidates = 0, *cand; tree fns, mem_arglist = NULL_TREE, arglist, fnname; enum tree_code code2 = NOP_EXPR; - tree templates = NULL_TREE; tree conv; if (arg1 == error_mark_node || arg2 == error_mark_node --- 3481,3488 ---- struct z_candidate *candidates = 0, *cand; tree fns, mem_arglist = NULL_TREE, arglist, fnname; enum tree_code code2 = NOP_EXPR; tree conv; + bool viable_candidates; if (arg1 == error_mark_node || arg2 == error_mark_node *************** build_new_op (code, flags, arg1, arg2, a *** 3279,3284 **** --- 3509,3518 ---- if (TREE_CODE (arg1) == OFFSET_REF) arg1 = resolve_offset_ref (arg1); arg1 = convert_from_reference (arg1); + if (CLASS_TYPE_P (TREE_TYPE (arg1)) + && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg1))) + /* Make sure the template type is instantiated now. */ + instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg1))); switch (code) { *************** build_new_op (code, flags, arg1, arg2, a *** 3286,3292 **** case VEC_NEW_EXPR: case VEC_DELETE_EXPR: case DELETE_EXPR: ! /* Use build_op_new_call and build_op_delete_call instead. */ abort (); case CALL_EXPR: --- 3520,3526 ---- case VEC_NEW_EXPR: case VEC_DELETE_EXPR: case DELETE_EXPR: ! /* Use build_op_new_call and build_op_delete_call instead. */ abort (); case CALL_EXPR: *************** build_new_op (code, flags, arg1, arg2, a *** 3301,3312 **** --- 3535,3552 ---- if (TREE_CODE (arg2) == OFFSET_REF) arg2 = resolve_offset_ref (arg2); arg2 = convert_from_reference (arg2); + if (CLASS_TYPE_P (TREE_TYPE (arg2)) + && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg2))) + instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg2))); } if (arg3) { if (TREE_CODE (arg3) == OFFSET_REF) arg3 = resolve_offset_ref (arg3); arg3 = convert_from_reference (arg3); + if (CLASS_TYPE_P (TREE_TYPE (arg3)) + && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg3))) + instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg3))); } if (code == COND_EXPR) *************** build_new_op (code, flags, arg1, arg2, a *** 3340,3355 **** { tree fn = OVL_CURRENT (fns); if (TREE_CODE (fn) == TEMPLATE_DECL) ! { ! templates = tree_cons (NULL_TREE, fn, templates); ! candidates ! = add_template_candidate (candidates, fn, NULL_TREE, NULL_TREE, ! arglist, TREE_TYPE (fnname), ! flags, DEDUCE_CALL); ! } else ! candidates = add_function_candidate (candidates, fn, NULL_TREE, ! arglist, flags); } if (IS_AGGR_TYPE (TREE_TYPE (arg1))) --- 3580,3596 ---- { tree fn = OVL_CURRENT (fns); if (TREE_CODE (fn) == TEMPLATE_DECL) ! add_template_candidate (&candidates, fn, NULL_TREE, NULL_TREE, ! arglist, TREE_TYPE (fnname), ! /*access_path=*/NULL_TREE, ! /*conversion_path=*/NULL_TREE, ! flags, DEDUCE_CALL); else ! add_function_candidate (&candidates, fn, NULL_TREE, ! arglist, ! /*access_path=*/NULL_TREE, ! /*conversion_path=*/NULL_TREE, ! flags); } if (IS_AGGR_TYPE (TREE_TYPE (arg1))) *************** build_new_op (code, flags, arg1, arg2, a *** 3363,3374 **** if (fns) { ! tree basetype = BINFO_TYPE (TREE_PURPOSE (fns)); mem_arglist = tree_cons (NULL_TREE, build_this (arg1), TREE_CHAIN (arglist)); ! for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); tree this_arglist; if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) this_arglist = mem_arglist; --- 3604,3617 ---- if (fns) { ! tree conversion_path = BASELINK_BINFO (fns); ! mem_arglist = tree_cons (NULL_TREE, build_this (arg1), TREE_CHAIN (arglist)); ! for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); tree this_arglist; + tree access_path = TYPE_BINFO (TREE_TYPE (arg1)); if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) this_arglist = mem_arglist; *************** build_new_op (code, flags, arg1, arg2, a *** 3376,3395 **** this_arglist = arglist; if (TREE_CODE (fn) == TEMPLATE_DECL) ! { ! /* A member template. */ ! templates = tree_cons (NULL_TREE, fn, templates); ! candidates ! = add_template_candidate (candidates, fn, basetype, NULL_TREE, ! this_arglist, TREE_TYPE (fnname), ! flags, DEDUCE_CALL); ! } else ! candidates = add_function_candidate ! (candidates, fn, basetype, this_arglist, flags); ! ! if (candidates) ! candidates->basetype_path = TYPE_BINFO (TREE_TYPE (arg1)); } } --- 3619,3635 ---- this_arglist = arglist; if (TREE_CODE (fn) == TEMPLATE_DECL) ! /* A member template. */ ! add_template_candidate (&candidates, fn, ! BINFO_TYPE (conversion_path), ! NULL_TREE, ! this_arglist, TREE_TYPE (fnname), ! access_path, conversion_path, ! flags, DEDUCE_CALL); else ! add_function_candidate ! (&candidates, fn, BINFO_TYPE (conversion_path), this_arglist, ! access_path, conversion_path, flags); } } *************** build_new_op (code, flags, arg1, arg2, a *** 3413,3423 **** args[2] = NULL_TREE; } ! candidates = add_builtin_candidates ! (candidates, code, code2, fnname, args, flags); } ! if (! any_viable (candidates)) { switch (code) { --- 3653,3680 ---- args[2] = NULL_TREE; } ! add_builtin_candidates (&candidates, code, code2, fnname, args, flags); } ! switch (code) ! { ! case COMPOUND_EXPR: ! case ADDR_EXPR: ! /* For these, the built-in candidates set is empty ! [over.match.oper]/3. We don't want non-strict matches ! because exact matches are always possible with built-in ! operators. The built-in candidate set for COMPONENT_REF ! would be empty too, but since there are no such built-in ! operators, we accept non-strict matches for them. */ ! viable_candidates = any_strictly_viable (candidates); ! break; ! ! default: ! viable_candidates = any_viable (candidates); ! break; ! } ! ! if (! viable_candidates) { switch (code) { *************** build_op_delete_call (code, addr, size, *** 3652,3661 **** tree alloc_fn; tree call_expr; ! /* Find the allocation function that is being called. */ call_expr = placement; /* Sometimes we have a COMPOUND_EXPR, rather than a simple ! CALL_EXPR. */ while (TREE_CODE (call_expr) == COMPOUND_EXPR) call_expr = TREE_OPERAND (call_expr, 1); /* Extract the function. */ --- 3909,3918 ---- tree alloc_fn; tree call_expr; ! /* Find the allocation function that is being called. */ call_expr = placement; /* Sometimes we have a COMPOUND_EXPR, rather than a simple ! CALL_EXPR. */ while (TREE_CODE (call_expr) == COMPOUND_EXPR) call_expr = TREE_OPERAND (call_expr, 1); /* Extract the function. */ *************** build_op_delete_call (code, addr, size, *** 3694,3700 **** /* Go through the `operator delete' functions looking for one with a matching type. */ ! for (fn = BASELINK_P (fns) ? TREE_VALUE (fns) : fns; fn; fn = OVL_NEXT (fn)) { --- 3951,3957 ---- /* Go through the `operator delete' functions looking for one with a matching type. */ ! for (fn = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns; fn; fn = OVL_NEXT (fn)) { *************** enforce_access (basetype_path, decl) *** 3774,3782 **** /* Perform the conversions in CONVS on the expression EXPR. FN and ARGNUM are used for diagnostics. ARGNUM is zero based, -1 ! indicates the `this' argument of a method. INNER is non-zero when being called to continue a conversion chain. It is negative when a ! reference binding will be applied, positive otherwise. */ static tree convert_like_real (convs, expr, fn, argnum, inner) --- 4031,4039 ---- /* Perform the conversions in CONVS on the expression EXPR. FN and ARGNUM are used for diagnostics. ARGNUM is zero based, -1 ! indicates the `this' argument of a method. INNER is nonzero when being called to continue a conversion chain. It is negative when a ! reference binding will be applied, positive otherwise. */ static tree convert_like_real (convs, expr, fn, argnum, inner) *************** convert_like_real (convs, expr, fn, argn *** 3820,3827 **** { case USER_CONV: { ! struct z_candidate *cand ! = WRAPPER_PTR (TREE_OPERAND (convs, 1)); tree convfn = cand->fn; tree args; --- 4077,4083 ---- { case USER_CONV: { ! struct z_candidate *cand = USER_CONV_CAND (convs); tree convfn = cand->fn; tree args; *************** convert_like_real (convs, expr, fn, argn *** 3859,3865 **** && (inner >= 0 || !lvalue_p (expr))) { savew = warningcount, savee = errorcount; ! expr = build_new_method_call (NULL_TREE, complete_ctor_identifier, build_tree_list (NULL_TREE, expr), TYPE_BINFO (totype), /* Core issue 84, now a DR, says that we don't allow UDCs --- 4115,4121 ---- && (inner >= 0 || !lvalue_p (expr))) { savew = warningcount, savee = errorcount; ! expr = build_special_member_call (NULL_TREE, complete_ctor_identifier, build_tree_list (NULL_TREE, expr), TYPE_BINFO (totype), /* Core issue 84, now a DR, says that we don't allow UDCs *************** convert_like_real (convs, expr, fn, argn *** 3941,3950 **** type is the same class as, or a derived class of, the class of the destination [is treated as direct-initialization]. [dcl.init] */ savew = warningcount, savee = errorcount; ! expr = build_new_method_call (NULL_TREE, complete_ctor_identifier, ! build_tree_list (NULL_TREE, expr), ! TYPE_BINFO (totype), ! LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING); if (fn) { if (warningcount > savew) --- 4197,4206 ---- type is the same class as, or a derived class of, the class of the destination [is treated as direct-initialization]. [dcl.init] */ savew = warningcount, savee = errorcount; ! expr = build_special_member_call (NULL_TREE, complete_ctor_identifier, ! build_tree_list (NULL_TREE, expr), ! TYPE_BINFO (totype), ! LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING); if (fn) { if (warningcount > savew) *************** convert_like_real (convs, expr, fn, argn *** 3959,3965 **** tree ref_type = totype; /* If necessary, create a temporary. */ ! if (NEED_TEMPORARY_P (convs) || !lvalue_p (expr)) { tree type = TREE_TYPE (TREE_OPERAND (convs, 0)); expr = build_target_expr_with_type (expr, type); --- 4215,4221 ---- tree ref_type = totype; /* If necessary, create a temporary. */ ! if (NEED_TEMPORARY_P (convs) || !non_cast_lvalue_p (expr)) { tree type = TREE_TYPE (TREE_OPERAND (convs, 0)); expr = build_target_expr_with_type (expr, type); *************** convert_like_real (convs, expr, fn, argn *** 3977,3985 **** expr = cp_convert (build_pointer_type (TREE_TYPE (ref_type)), expr); /* Convert the pointer to the desired reference type. */ ! expr = build1 (NOP_EXPR, ref_type, expr); ! ! return expr; } case LVALUE_CONV: --- 4233,4239 ---- expr = cp_convert (build_pointer_type (TREE_TYPE (ref_type)), expr); /* Convert the pointer to the desired reference type. */ ! return build_nop (ref_type, expr); } case LVALUE_CONV: *************** convert_arg_to_ellipsis (arg) *** 4034,4040 **** if (arg != error_mark_node && ! pod_type_p (TREE_TYPE (arg))) { ! /* Undefined behaviour [expr.call] 5.2.2/7. We used to just warn here and do a bitwise copy, but now cp_expr_size will abort if we try to do that. */ warning ("cannot pass objects of non-POD type `%#T' through `...'; \ --- 4288,4294 ---- if (arg != error_mark_node && ! pod_type_p (TREE_TYPE (arg))) { ! /* Undefined behavior [expr.call] 5.2.2/7. We used to just warn here and do a bitwise copy, but now cp_expr_size will abort if we try to do that. */ warning ("cannot pass objects of non-POD type `%#T' through `...'; \ *************** build_x_va_arg (expr, type) *** 4063,4069 **** if (! pod_type_p (type)) { ! /* Undefined behaviour [expr.call] 5.2.2/7. */ warning ("cannot receive objects of non-POD type `%#T' through `...'", type); } --- 4317,4323 ---- if (! pod_type_p (type)) { ! /* Undefined behavior [expr.call] 5.2.2/7. */ warning ("cannot receive objects of non-POD type `%#T' through `...'", type); } *************** build_x_va_arg (expr, type) *** 4071,4094 **** return build_va_arg (expr, type); } ! /* TYPE has been given to va_arg. Apply the default conversions which would ! have happened when passed via ellipsis. Return the promoted type, or ! NULL_TREE, if there is no change. */ tree ! convert_type_from_ellipsis (type) tree type; { tree promote; ! if (TREE_CODE (type) == ARRAY_TYPE) ! promote = build_pointer_type (TREE_TYPE (type)); ! else if (TREE_CODE (type) == FUNCTION_TYPE) ! promote = build_pointer_type (type); ! else ! promote = type_promotes_to (type); ! return same_type_p (type, promote) ? NULL_TREE : promote; } /* ARG is a default argument expression being passed to a parameter of --- 4325,4351 ---- return build_va_arg (expr, type); } ! /* TYPE has been given to va_arg. Apply the default conversions which ! would have happened when passed via ellipsis. Return the promoted ! type, or the passed type if there is no change. */ tree ! cxx_type_promotes_to (type) tree type; { tree promote; ! if (TREE_CODE (type) == ARRAY_TYPE) ! return build_pointer_type (TREE_TYPE (type)); ! ! if (TREE_CODE (type) == FUNCTION_TYPE) ! return build_pointer_type (type); ! ! promote = type_promotes_to (type); ! if (same_type_p (type, promote)) ! promote = type; ! return promote; } /* ARG is a default argument expression being passed to a parameter of *************** convert_default_arg (type, arg, fn, parm *** 4141,4155 **** arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, "default argument", fn, parmnum); ! if (PROMOTE_PROTOTYPES ! && INTEGRAL_TYPE_P (type) ! && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) ! arg = default_conversion (arg); } return arg; } /* Subroutine of the various build_*_call functions. Overload resolution has chosen a winning candidate CAND; build up a CALL_EXPR accordingly. ARGS is a TREE_LIST of the unconverted arguments to the call. FLAGS is a --- 4398,4445 ---- arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, "default argument", fn, parmnum); ! arg = convert_for_arg_passing (type, arg); } return arg; } + /* Returns the type which will really be used for passing an argument of + type TYPE. */ + + tree + type_passed_as (type) + tree type; + { + /* Pass classes with copy ctors by invisible reference. */ + if (TREE_ADDRESSABLE (type)) + type = build_reference_type (type); + else if (PROMOTE_PROTOTYPES + && INTEGRAL_TYPE_P (type) + && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) + type = integer_type_node; + + return type; + } + + /* Actually perform the appropriate conversion. */ + + tree + convert_for_arg_passing (type, val) + tree type, val; + { + if (val == error_mark_node) + ; + /* Pass classes with copy ctors by invisible reference. */ + else if (TREE_ADDRESSABLE (type)) + val = build1 (ADDR_EXPR, build_reference_type (type), val); + else if (PROMOTE_PROTOTYPES + && INTEGRAL_TYPE_P (type) + && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) + val = default_conversion (val); + return val; + } + /* Subroutine of the various build_*_call functions. Overload resolution has chosen a winning candidate CAND; build up a CALL_EXPR accordingly. ARGS is a TREE_LIST of the unconverted arguments to the call. FLAGS is a *************** build_over_call (cand, args, flags) *** 4172,4181 **** /* Give any warnings we noticed during overload resolution. */ if (cand->warnings) for (val = cand->warnings; val; val = TREE_CHAIN (val)) ! joust (cand, WRAPPER_PTR (TREE_VALUE (val)), 1); if (DECL_FUNCTION_MEMBER_P (fn)) ! enforce_access (cand->basetype_path, fn); if (args && TREE_CODE (args) != TREE_LIST) args = build_tree_list (NULL_TREE, args); --- 4462,4471 ---- /* Give any warnings we noticed during overload resolution. */ if (cand->warnings) for (val = cand->warnings; val; val = TREE_CHAIN (val)) ! joust (cand, WRAPPER_ZC (TREE_VALUE (val)), 1); if (DECL_FUNCTION_MEMBER_P (fn)) ! enforce_access (cand->access_path, fn); if (args && TREE_CODE (args) != TREE_LIST) args = build_tree_list (NULL_TREE, args); *************** build_over_call (cand, args, flags) *** 4204,4210 **** { tree parmtype = TREE_VALUE (parm); tree argtype = TREE_TYPE (TREE_VALUE (arg)); ! tree t; if (ICS_BAD_FLAG (TREE_VEC_ELT (convs, i))) pedwarn ("passing `%T' as `this' argument of `%#D' discards qualifiers", TREE_TYPE (argtype), fn); --- 4494,4502 ---- { tree parmtype = TREE_VALUE (parm); tree argtype = TREE_TYPE (TREE_VALUE (arg)); ! tree converted_arg; ! tree base_binfo; ! if (ICS_BAD_FLAG (TREE_VEC_ELT (convs, i))) pedwarn ("passing `%T' as `this' argument of `%#D' discards qualifiers", TREE_TYPE (argtype), fn); *************** build_over_call (cand, args, flags) *** 4216,4225 **** So we can assume that anything passed as 'this' is non-null, and optimize accordingly. */ my_friendly_assert (TREE_CODE (parmtype) == POINTER_TYPE, 19990811); ! t = lookup_base (TREE_TYPE (TREE_TYPE (TREE_VALUE (arg))), ! TREE_TYPE (parmtype), ba_ignore, NULL); ! t = build_base_path (PLUS_EXPR, TREE_VALUE (arg), t, 1); ! converted_args = tree_cons (NULL_TREE, t, converted_args); parm = TREE_CHAIN (parm); arg = TREE_CHAIN (arg); ++i; --- 4508,4529 ---- So we can assume that anything passed as 'this' is non-null, and optimize accordingly. */ my_friendly_assert (TREE_CODE (parmtype) == POINTER_TYPE, 19990811); ! /* Convert to the base in which the function was declared. */ ! my_friendly_assert (cand->conversion_path != NULL_TREE, 20020730); ! converted_arg = build_base_path (PLUS_EXPR, ! TREE_VALUE (arg), ! cand->conversion_path, ! 1); ! /* If fn was found by a using declaration, the conversion path ! will be to the derived class, not the base declaring fn. We ! must convert from derived to base. */ ! base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)), ! TREE_TYPE (parmtype), ba_ignore, NULL); ! ! converted_arg = build_base_path (PLUS_EXPR, converted_arg, ! base_binfo, 1); ! ! converted_args = tree_cons (NULL_TREE, converted_arg, converted_args); parm = TREE_CHAIN (parm); arg = TREE_CHAIN (arg); ++i; *************** build_over_call (cand, args, flags) *** 4235,4244 **** val = convert_like_with_context (conv, TREE_VALUE (arg), fn, i - is_method); ! if (PROMOTE_PROTOTYPES ! && INTEGRAL_TYPE_P (type) ! && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) ! val = default_conversion (val); converted_args = tree_cons (NULL_TREE, val, converted_args); } --- 4539,4545 ---- val = convert_like_with_context (conv, TREE_VALUE (arg), fn, i - is_method); ! val = convert_for_arg_passing (type, val); converted_args = tree_cons (NULL_TREE, val, converted_args); } *************** build_over_call (cand, args, flags) *** 4314,4328 **** else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))) return build_target_expr_with_type (arg, DECL_CONTEXT (fn)); } ! else if ((TREE_CODE (arg) == TARGET_EXPR ! || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))) ! /* Empty classes have padding which can be hidden ! inside an (empty) base of the class. This must not ! be touched as it might overlay things. When the ! gcc core learns about empty classes, we can treat it ! like other classes. */ ! && !(is_empty_class (DECL_CONTEXT (fn)) ! && TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))) { tree address; tree to = stabilize_reference --- 4615,4622 ---- else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))) return build_target_expr_with_type (arg, DECL_CONTEXT (fn)); } ! else if (TREE_CODE (arg) == TARGET_EXPR ! || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))) { tree address; tree to = stabilize_reference *************** build_over_call (cand, args, flags) *** 4344,4367 **** (build_indirect_ref (TREE_VALUE (converted_args), 0)); arg = build_indirect_ref (TREE_VALUE (TREE_CHAIN (converted_args)), 0); ! if (is_empty_class (TREE_TYPE (to))) ! { ! TREE_USED (arg) = 1; ! ! val = build (COMPOUND_EXPR, DECL_CONTEXT (fn), arg, to); ! /* Even though the assignment may not actually result in any ! code being generated, we do not want to warn about the ! assignment having no effect. That would be confusing to ! users who may be performing the assignment as part of a ! generic algorithm, for example. ! ! Ideally, the notions of having side-effects and of being ! useless would be orthogonal. */ ! TREE_SIDE_EFFECTS (val) = 1; ! TREE_NO_UNUSED_WARNING (val) = 1; ! } ! else ! val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg); return val; } --- 4638,4644 ---- (build_indirect_ref (TREE_VALUE (converted_args), 0)); arg = build_indirect_ref (TREE_VALUE (TREE_CHAIN (converted_args)), 0); ! val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg); return val; } *************** build_over_call (cand, args, flags) *** 4371,4377 **** { tree t, *p = &TREE_VALUE (converted_args); tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (*p)), ! DECL_VIRTUAL_CONTEXT (fn), ba_any, NULL); my_friendly_assert (binfo && binfo != error_mark_node, 20010730); --- 4648,4654 ---- { tree t, *p = &TREE_VALUE (converted_args); tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (*p)), ! DECL_CONTEXT (fn), ba_any, NULL); my_friendly_assert (binfo && binfo != error_mark_node, 20010730); *************** build_over_call (cand, args, flags) *** 4390,4399 **** else fn = build_addr_func (fn); /* Recognize certain built-in functions so we can make tree-codes other than CALL_EXPR. We do this when it enables fold-const.c to do something useful. */ - if (TREE_CODE (fn) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL && DECL_BUILT_IN (TREE_OPERAND (fn, 0))) --- 4667,4688 ---- else fn = build_addr_func (fn); + return build_cxx_call (fn, args, converted_args); + } + + /* Build and return a call to FN, using the the CONVERTED_ARGS. ARGS + gives the original form of the arguments. This function performs + no overload resolution, conversion, or other high-level + operations. */ + + tree + build_cxx_call(tree fn, tree args, tree converted_args) + { + tree fndecl; + /* Recognize certain built-in functions so we can make tree-codes other than CALL_EXPR. We do this when it enables fold-const.c to do something useful. */ if (TREE_CODE (fn) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL && DECL_BUILT_IN (TREE_OPERAND (fn, 0))) *************** build_over_call (cand, args, flags) *** 4404,4423 **** return exp; } ! /* Some built-in function calls will be evaluated at ! compile-time in fold (). */ ! fn = fold (build_call (fn, converted_args)); if (VOID_TYPE_P (TREE_TYPE (fn))) return fn; fn = require_complete_type (fn); if (fn == error_mark_node) return error_mark_node; if (IS_AGGR_TYPE (TREE_TYPE (fn))) fn = build_cplus_new (TREE_TYPE (fn), fn); return convert_from_reference (fn); } ! static tree java_iface_lookup_fn; /* Make an expression which yields the address of the Java interface method FN. This is achieved by generating a call to libjava's --- 4693,4724 ---- return exp; } ! fn = build_call (fn, converted_args); ! ! /* If this call might throw an exception, note that fact. */ ! fndecl = get_callee_fndecl (fn); ! if ((!fndecl || !TREE_NOTHROW (fndecl)) ! && at_function_scope_p () ! && cfun) ! cp_function_chain->can_throw = 1; ! ! /* Some built-in function calls will be evaluated at compile-time in ! fold (). */ ! fn = fold (fn); ! if (VOID_TYPE_P (TREE_TYPE (fn))) return fn; + fn = require_complete_type (fn); if (fn == error_mark_node) return error_mark_node; + if (IS_AGGR_TYPE (TREE_TYPE (fn))) fn = build_cplus_new (TREE_TYPE (fn), fn); return convert_from_reference (fn); } ! static GTY(()) tree java_iface_lookup_fn; /* Make an expression which yields the address of the Java interface method FN. This is achieved by generating a call to libjava's *************** build_java_interface_fn_ref (fn, instanc *** 4441,4456 **** java_iface_lookup_fn = builtin_function ("_Jv_LookupInterfaceMethodIdx", build_function_type (ptr_type_node, t), ! 0, NOT_BUILT_IN, NULL); ! ggc_add_tree_root (&java_iface_lookup_fn, 1); } /* Look up the pointer to the runtime java.lang.Class object for `instance'. ! This is the first entry in the vtable. */ klass_ref = build_vtbl_ref (build_indirect_ref (instance, 0), integer_zero_node); ! /* Get the java.lang.Class pointer for the interface being called. */ iface = DECL_CONTEXT (fn); iface_ref = lookup_field (iface, get_identifier ("class$"), 0, 0); if (!iface_ref || TREE_CODE (iface_ref) != VAR_DECL --- 4742,4756 ---- java_iface_lookup_fn = builtin_function ("_Jv_LookupInterfaceMethodIdx", build_function_type (ptr_type_node, t), ! 0, NOT_BUILT_IN, NULL, NULL_TREE); } /* Look up the pointer to the runtime java.lang.Class object for `instance'. ! This is the first entry in the vtable. */ klass_ref = build_vtbl_ref (build_indirect_ref (instance, 0), integer_zero_node); ! /* Get the java.lang.Class pointer for the interface being called. */ iface = DECL_CONTEXT (fn); iface_ref = lookup_field (iface, get_identifier ("class$"), 0, 0); if (!iface_ref || TREE_CODE (iface_ref) != VAR_DECL *************** build_java_interface_fn_ref (fn, instanc *** 4462,4468 **** } iface_ref = build1 (ADDR_EXPR, build_pointer_type (iface), iface_ref); ! /* Determine the itable index of FN. */ i = 1; for (method = TYPE_METHODS (iface); method; method = TREE_CHAIN (method)) { --- 4762,4768 ---- } iface_ref = build1 (ADDR_EXPR, build_pointer_type (iface), iface_ref); ! /* Determine the itable index of FN. */ i = 1; for (method = TYPE_METHODS (iface); method; method = TREE_CHAIN (method)) { *************** in_charge_arg_for_name (name) *** 4506,4648 **** return NULL_TREE; } ! static tree ! build_new_method_call (instance, name, args, basetype_path, flags) ! tree instance, name, args, basetype_path; ! int flags; { struct z_candidate *candidates = 0, *cand; tree explicit_targs = NULL_TREE; ! tree basetype, mem_args = NULL_TREE, fns, instance_ptr; ! tree pretty_name; tree user_args; - tree templates = NULL_TREE; tree call; int template_only = 0; ! if (TREE_CODE (name) == TEMPLATE_ID_EXPR) ! { ! explicit_targs = TREE_OPERAND (name, 1); ! name = TREE_OPERAND (name, 0); ! if (DECL_P (name)) ! name = DECL_NAME (name); ! else ! { ! if (TREE_CODE (name) == COMPONENT_REF) ! name = TREE_OPERAND (name, 1); ! if (TREE_CODE (name) == OVERLOAD) ! name = DECL_NAME (OVL_CURRENT (name)); ! } ! template_only = 1; ! } user_args = args; args = resolve_args (args); - if (args == error_mark_node) return error_mark_node; ! if (instance == NULL_TREE) ! basetype = BINFO_TYPE (basetype_path); ! else { ! if (TREE_CODE (instance) == OFFSET_REF) ! instance = resolve_offset_ref (instance); ! if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE) ! instance = convert_from_reference (instance); ! basetype = TYPE_MAIN_VARIANT (TREE_TYPE (instance)); ! /* XXX this should be handled before we get here. */ ! if (! IS_AGGR_TYPE (basetype)) ! { ! if ((flags & LOOKUP_COMPLAIN) && basetype != error_mark_node) ! error ("request for member `%D' in `%E', which is of non-aggregate type `%T'", ! name, instance, basetype); ! return error_mark_node; ! } } ! if (basetype_path == NULL_TREE) ! basetype_path = TYPE_BINFO (basetype); ! if (instance) { ! instance_ptr = build_this (instance); ! if (! template_only) ! { ! /* XXX this should be handled before we get here. */ ! fns = build_field_call (basetype_path, instance_ptr, name, args); ! if (fns) ! return fns; ! } ! } ! else ! { ! instance_ptr = build_int_2 (0, 0); ! TREE_TYPE (instance_ptr) = build_pointer_type (basetype); } ! /* Callers should explicitly indicate whether they want to construct ! the complete object or just the part without virtual bases. */ ! my_friendly_assert (name != ctor_identifier, 20000408); ! /* Similarly for destructors. */ ! my_friendly_assert (name != dtor_identifier, 20000408); if (IDENTIFIER_CTOR_OR_DTOR_P (name)) { ! int constructor_p; ! ! constructor_p = (name == complete_ctor_identifier ! || name == base_ctor_identifier); ! pretty_name = (constructor_p ! ? constructor_name (basetype) : dtor_identifier); ! ! /* If we're a call to a constructor or destructor for a ! subobject that uses virtual base classes, then we need to ! pass down a pointer to a VTT for the subobject. */ ! if ((name == base_ctor_identifier ! || name == base_dtor_identifier) ! && TYPE_USES_VIRTUAL_BASECLASSES (basetype)) ! { ! tree vtt; ! tree sub_vtt; ! tree basebinfo = basetype_path; ! ! /* If the current function is a complete object constructor ! or destructor, then we fetch the VTT directly. ! Otherwise, we look it up using the VTT we were given. */ ! vtt = IDENTIFIER_GLOBAL_VALUE (get_vtt_name (current_class_type)); ! vtt = decay_conversion (vtt); ! vtt = build (COND_EXPR, TREE_TYPE (vtt), ! build (EQ_EXPR, boolean_type_node, ! current_in_charge_parm, integer_zero_node), ! current_vtt_parm, ! vtt); ! if (TREE_VIA_VIRTUAL (basebinfo)) ! basebinfo = binfo_for_vbase (basetype, current_class_type); ! my_friendly_assert (BINFO_SUBVTT_INDEX (basebinfo), 20010110); ! sub_vtt = build (PLUS_EXPR, TREE_TYPE (vtt), vtt, ! BINFO_SUBVTT_INDEX (basebinfo)); ! ! args = tree_cons (NULL_TREE, sub_vtt, args); ! } } else pretty_name = name; - fns = lookup_fnfields (basetype_path, name, 1); - - if (fns == error_mark_node) - return error_mark_node; if (fns) { ! tree base = BINFO_TYPE (TREE_PURPOSE (fns)); ! tree fn = TREE_VALUE (fns); mem_args = tree_cons (NULL_TREE, instance_ptr, args); ! for (; fn; fn = OVL_NEXT (fn)) { tree t = OVL_CURRENT (fn); tree this_arglist; --- 4806,4995 ---- return NULL_TREE; } ! /* Build a call to a constructor, destructor, or an assignment ! operator for INSTANCE, an expression with class type. NAME ! indicates the special member function to call; ARGS are the ! arguments. BINFO indicates the base of INSTANCE that is to be ! passed as the `this' parameter to the member function called. ! ! FLAGS are the LOOKUP_* flags to use when processing the call. ! ! If NAME indicates a complete object constructor, INSTANCE may be ! NULL_TREE. In this case, the caller will call build_cplus_new to ! store the newly constructed object into a VAR_DECL. */ ! ! tree ! build_special_member_call (tree instance, tree name, tree args, ! tree binfo, int flags) ! { ! tree fns; ! /* The type of the subobject to be constructed or destroyed. */ ! tree class_type; ! ! my_friendly_assert (name == complete_ctor_identifier ! || name == base_ctor_identifier ! || name == complete_dtor_identifier ! || name == base_dtor_identifier ! || name == deleting_dtor_identifier ! || name == ansi_assopname (NOP_EXPR), ! 20020712); ! my_friendly_assert (binfo != NULL_TREE, 20020712); ! ! class_type = BINFO_TYPE (binfo); ! ! /* Handle the special case where INSTANCE is NULL_TREE. */ ! if (name == complete_ctor_identifier && !instance) ! { ! instance = build_int_2 (0, 0); ! TREE_TYPE (instance) = build_pointer_type (class_type); ! instance = build1 (INDIRECT_REF, class_type, instance); ! } ! else if (name == complete_dtor_identifier ! || name == base_dtor_identifier ! || name == deleting_dtor_identifier) ! my_friendly_assert (args == NULL_TREE, 20020712); ! ! my_friendly_assert (instance != NULL_TREE, 20020712); ! ! /* Resolve the name. */ ! if (!complete_type_or_else (BINFO_TYPE (binfo), NULL_TREE)) ! return error_mark_node; ! ! fns = lookup_fnfields (binfo, name, 1); ! ! /* When making a call to a constructor or destructor for a subobject ! that uses virtual base classes, pass down a pointer to a VTT for ! the subobject. */ ! if ((name == base_ctor_identifier ! || name == base_dtor_identifier) ! && TYPE_USES_VIRTUAL_BASECLASSES (class_type)) ! { ! tree vtt; ! tree sub_vtt; ! ! /* If the current function is a complete object constructor ! or destructor, then we fetch the VTT directly. ! Otherwise, we look it up using the VTT we were given. */ ! vtt = TREE_CHAIN (CLASSTYPE_VTABLES (current_class_type)); ! vtt = decay_conversion (vtt); ! vtt = build (COND_EXPR, TREE_TYPE (vtt), ! build (EQ_EXPR, boolean_type_node, ! current_in_charge_parm, integer_zero_node), ! current_vtt_parm, ! vtt); ! if (TREE_VIA_VIRTUAL (binfo)) ! binfo = binfo_for_vbase (class_type, current_class_type); ! my_friendly_assert (BINFO_SUBVTT_INDEX (binfo), 20010110); ! sub_vtt = build (PLUS_EXPR, TREE_TYPE (vtt), vtt, ! BINFO_SUBVTT_INDEX (binfo)); ! ! args = tree_cons (NULL_TREE, sub_vtt, args); ! } ! ! return build_new_method_call (instance, fns, args, binfo, flags); ! } ! ! /* Build a call to "INSTANCE.FN (ARGS)". */ ! ! tree ! build_new_method_call (tree instance, tree fns, tree args, ! tree conversion_path, int flags) { struct z_candidate *candidates = 0, *cand; tree explicit_targs = NULL_TREE; ! tree basetype = NULL_TREE; ! tree access_binfo; ! tree optype; ! tree mem_args = NULL_TREE, instance_ptr; ! tree name, pretty_name; tree user_args; tree call; int template_only = 0; ! my_friendly_assert (instance != NULL_TREE, 20020729); ! if (instance == error_mark_node || fns == error_mark_node ! || args == error_mark_node) ! return error_mark_node; + /* Process the argument list. */ user_args = args; args = resolve_args (args); if (args == error_mark_node) return error_mark_node; ! if (TREE_CODE (instance) == OFFSET_REF) ! instance = resolve_offset_ref (instance); ! if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE) ! instance = convert_from_reference (instance); ! basetype = TYPE_MAIN_VARIANT (TREE_TYPE (instance)); ! instance_ptr = build_this (instance); ! ! if (!BASELINK_P (fns)) { ! call = build_field_call (instance_ptr, fns, args); ! if (call) ! return call; ! error ("call to non-function `%D'", fns); ! return error_mark_node; ! } ! if (!conversion_path) ! conversion_path = BASELINK_BINFO (fns); ! access_binfo = BASELINK_ACCESS_BINFO (fns); ! optype = BASELINK_OPTYPE (fns); ! fns = BASELINK_FUNCTIONS (fns); ! if (TREE_CODE (fns) == TEMPLATE_ID_EXPR) ! { ! explicit_targs = TREE_OPERAND (fns, 1); ! fns = TREE_OPERAND (fns, 0); ! template_only = 1; } ! my_friendly_assert (TREE_CODE (fns) == FUNCTION_DECL ! || TREE_CODE (fns) == TEMPLATE_DECL ! || TREE_CODE (fns) == OVERLOAD, ! 20020712); ! /* XXX this should be handled before we get here. */ ! if (! IS_AGGR_TYPE (basetype)) { ! if ((flags & LOOKUP_COMPLAIN) && basetype != error_mark_node) ! error ("request for member `%D' in `%E', which is of non-aggregate type `%T'", ! fns, instance, basetype); ! return error_mark_node; } ! name = DECL_NAME (get_first_fn (fns)); if (IDENTIFIER_CTOR_OR_DTOR_P (name)) { ! /* Callers should explicitly indicate whether they want to construct ! the complete object or just the part without virtual bases. */ ! my_friendly_assert (name != ctor_identifier, 20000408); ! /* Similarly for destructors. */ ! my_friendly_assert (name != dtor_identifier, 20000408); ! ! if (name == complete_ctor_identifier ! || name == base_ctor_identifier) ! pretty_name = constructor_name (basetype); ! else ! pretty_name = dtor_identifier; } else pretty_name = name; if (fns) { ! tree fn; ! tree class_type = (conversion_path ! ? BINFO_TYPE (conversion_path) ! : NULL_TREE); ! mem_args = tree_cons (NULL_TREE, instance_ptr, args); ! for (fn = fns; fn; fn = OVL_NEXT (fn)) { tree t = OVL_CURRENT (fn); tree this_arglist; *************** build_new_method_call (instance, name, a *** 4658,4677 **** this_arglist = args; if (TREE_CODE (t) == TEMPLATE_DECL) ! { ! /* A member template. */ ! templates = tree_cons (NULL_TREE, t, templates); ! candidates = ! add_template_candidate (candidates, t, base, explicit_targs, ! this_arglist, ! TREE_TYPE (name), flags, DEDUCE_CALL); ! } else if (! template_only) ! candidates = add_function_candidate (candidates, t, base, ! this_arglist, flags); ! ! if (candidates) ! candidates->basetype_path = basetype_path; } } --- 5005,5026 ---- this_arglist = args; if (TREE_CODE (t) == TEMPLATE_DECL) ! /* A member template. */ ! add_template_candidate (&candidates, t, ! class_type, ! explicit_targs, ! this_arglist, optype, ! access_binfo, ! conversion_path, ! flags, ! DEDUCE_CALL); else if (! template_only) ! add_function_candidate (&candidates, t, ! class_type, ! this_arglist, ! access_binfo, ! conversion_path, ! flags); } } *************** build_new_method_call (instance, name, a *** 4681,4687 **** if (flags & LOOKUP_SPECULATIVELY) return NULL_TREE; if (!COMPLETE_TYPE_P (basetype)) ! incomplete_type_error (instance_ptr, basetype); else error ("no matching function for call to `%T::%D(%A)%#V'", basetype, pretty_name, user_args, --- 5030,5036 ---- if (flags & LOOKUP_SPECULATIVELY) return NULL_TREE; if (!COMPLETE_TYPE_P (basetype)) ! cxx_incomplete_type_error (instance_ptr, basetype); else error ("no matching function for call to `%T::%D(%A)%#V'", basetype, pretty_name, user_args, *************** build_new_method_call (instance, name, a *** 4726,4741 **** else { call = build_over_call (cand, args, flags); ! /* Do evaluate the object parameter in a call to a static member ! function. */ ! if (TREE_SIDE_EFFECTS (instance)) call = build (COMPOUND_EXPR, TREE_TYPE (call), instance, call); } return call; } ! /* Returns non-zero iff standard conversion sequence ICS1 is a proper subsequence of ICS2. */ static int --- 5075,5090 ---- else { call = build_over_call (cand, args, flags); ! /* In an expression of the form `a->f()' where `f' turns out to ! be a static member function, `a' is none-the-less evaluated. */ ! if (instance && TREE_SIDE_EFFECTS (instance)) call = build (COMPOUND_EXPR, TREE_TYPE (call), instance, call); } return call; } ! /* Returns nonzero iff standard conversion sequence ICS1 is a proper subsequence of ICS2. */ static int *************** is_subseq (ics1, ics2) *** 4775,4781 **** } } ! /* Returns non-zero iff DERIVED is derived from BASE. The inputs may be any _TYPE nodes. */ int --- 5124,5130 ---- } } ! /* Returns nonzero iff DERIVED is derived from BASE. The inputs may be any _TYPE nodes. */ int *************** compare_ics (ics1, ics2) *** 4873,4879 **** tree deref_to_type2 = NULL_TREE; int rank1, rank2; ! /* REF_BINDING is non-zero if the result of the conversion sequence is a reference type. In that case TARGET_TYPE is the type referred to by the reference. */ tree target_type1; --- 5222,5228 ---- tree deref_to_type2 = NULL_TREE; int rank1, rank2; ! /* REF_BINDING is nonzero if the result of the conversion sequence is a reference type. In that case TARGET_TYPE is the type referred to by the reference. */ tree target_type1; *************** add_warning (winner, loser) *** 5219,5243 **** struct z_candidate *winner, *loser; { winner->warnings = tree_cons (NULL_TREE, ! build_ptr_wrapper (loser), winner->warnings); } - /* Returns true iff functions are equivalent. Equivalent functions are - not '==' only if one is a function-local extern function or if - both are extern "C". */ - - static inline int - equal_functions (fn1, fn2) - tree fn1; - tree fn2; - { - if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2) - || DECL_EXTERN_C_FUNCTION_P (fn1)) - return decls_match (fn1, fn2); - return fn1 == fn2; - } - /* Compare two candidates for overloading as described in [over.match.best]. Return values: --- 5568,5577 ---- struct z_candidate *winner, *loser; { winner->warnings = tree_cons (NULL_TREE, ! build_zc_wrapper (loser), winner->warnings); } /* Compare two candidates for overloading as described in [over.match.best]. Return values: *************** tourney (candidates) *** 5570,5576 **** return champ; } ! /* Returns non-zero if things of type FROM can be converted to TO. */ int can_convert (to, from) --- 5904,5910 ---- return champ; } ! /* Returns nonzero if things of type FROM can be converted to TO. */ int can_convert (to, from) *************** can_convert (to, from) *** 5579,5585 **** return can_convert_arg (to, from, NULL_TREE); } ! /* Returns non-zero if ARG (of type FROM) can be converted to TO. */ int can_convert_arg (to, from, arg) --- 5913,5919 ---- return can_convert_arg (to, from, NULL_TREE); } ! /* Returns nonzero if ARG (of type FROM) can be converted to TO. */ int can_convert_arg (to, from, arg) *************** perform_implicit_conversion (type, expr) *** 5625,5641 **** return convert_like (conv, expr); } /* Convert EXPR to the indicated reference TYPE, in a way suitable for ! initializing a variable of that TYPE. Return the converted ! expression. */ tree ! initialize_reference (type, expr) tree type; tree expr; { tree conv; conv = reference_binding (type, TREE_TYPE (expr), expr, LOOKUP_NORMAL); if (!conv || ICS_BAD_FLAG (conv)) { --- 5959,6020 ---- return convert_like (conv, expr); } + /* DECL is a VAR_DECL whose type is a REFERENCE_TYPE. The reference + is being bound to a temporary. Create and return a new VAR_DECL + with the indicated TYPE; this variable will store the value to + which the reference is bound. */ + + tree + make_temporary_var_for_ref_to_temp (tree decl, tree type) + { + tree var; + + /* Create the variable. */ + var = build_decl (VAR_DECL, NULL_TREE, type); + DECL_ARTIFICIAL (var) = 1; + TREE_USED (var) = 1; + + /* Register the variable. */ + if (TREE_STATIC (decl)) + { + /* Namespace-scope or local static; give it a mangled name. */ + tree name; + + TREE_STATIC (var) = 1; + name = mangle_ref_init_variable (decl); + DECL_NAME (var) = name; + SET_DECL_ASSEMBLER_NAME (var, name); + var = pushdecl_top_level (var); + } + else + { + /* Create a new cleanup level if necessary. */ + maybe_push_cleanup_level (type); + /* Don't push unnamed temps. Do set DECL_CONTEXT, though. */ + DECL_CONTEXT (var) = current_function_decl; + } + + return var; + } + /* Convert EXPR to the indicated reference TYPE, in a way suitable for ! initializing a variable of that TYPE. If DECL is non-NULL, it is ! the VAR_DECL being initialized with the EXPR. (In that case, the ! type of DECL will be TYPE.) ! ! Return the converted expression. */ tree ! initialize_reference (type, expr, decl) tree type; tree expr; + tree decl; { tree conv; + if (type == error_mark_node || error_operand_p (expr)) + return error_mark_node; + conv = reference_binding (type, TREE_TYPE (expr), expr, LOOKUP_NORMAL); if (!conv || ICS_BAD_FLAG (conv)) { *************** initialize_reference (type, expr) *** 5643,5647 **** --- 6022,6102 ---- return error_mark_node; } + /* If DECL is non-NULL, then this special rule applies: + + [class.temporary] + + The temporary to which the reference is bound or the temporary + that is the complete object to which the reference is bound + persists for the lifetime of the reference. + + The temporaries created during the evaluation of the expression + initializing the reference, except the temporary to which the + reference is bound, are destroyed at the end of the + full-expression in which they are created. + + In that case, we store the converted expression into a new + VAR_DECL in a new scope. + + However, we want to be careful not to create temporaries when + they are not required. For example, given: + + struct B {}; + struct D : public B {}; + D f(); + const B& b = f(); + + there is no need to copy the return value from "f"; we can just + extend its lifetime. Similarly, given: + + struct S {}; + struct T { operator S(); }; + T t; + const S& s = t; + + we can extend the lifetime of the returnn value of the conversion + operator. */ + my_friendly_assert (TREE_CODE (conv) == REF_BIND, 20030302); + if (decl) + { + tree var; + tree base_conv_type; + + /* Skip over the REF_BIND. */ + conv = TREE_OPERAND (conv, 0); + /* If the next conversion is a BASE_CONV, skip that too -- but + remember that the conversion was required. */ + if (TREE_CODE (conv) == BASE_CONV && !NEED_TEMPORARY_P (conv)) + { + base_conv_type = TREE_TYPE (conv); + conv = TREE_OPERAND (conv, 0); + } + else + base_conv_type = NULL_TREE; + /* Perform the remainder of the conversion. */ + expr = convert_like (conv, expr); + if (!real_non_cast_lvalue_p (expr)) + { + /* Create the temporary variable. */ + var = make_temporary_var_for_ref_to_temp (decl, TREE_TYPE (expr)); + DECL_INITIAL (var) = expr; + cp_finish_decl (var, expr, NULL_TREE, + LOOKUP_ONLYCONVERTING|DIRECT_BIND); + /* Use its address to initialize the reference variable. */ + expr = build_address (var); + } + else + /* Take the address of EXPR. */ + expr = build_unary_op (ADDR_EXPR, expr, 0); + /* If a BASE_CONV was required, perform it now. */ + if (base_conv_type) + expr = (perform_implicit_conversion + (build_pointer_type (base_conv_type), expr)); + return build_nop (type, expr); + } + + /* Perform the conversion. */ return convert_like (conv, expr); } + + #include "gt-cp-call.h" diff -Nrc3pad gcc-3.2.3/gcc/cp/cfns.gperf gcc-3.3/gcc/cp/cfns.gperf *** gcc-3.2.3/gcc/cp/cfns.gperf 2000-04-04 20:46:23.000000000 +0000 --- gcc-3.3/gcc/cp/cfns.gperf 2003-05-02 21:01:23.000000000 +0000 *************** const char * libc_name_p PARAMS ((const *** 16,24 **** # exception, unless it calls a program-supplied function that # throws an exception. # ! # bsearch and qsort are commented out because they can call such functions. # ! abort abs acos asctime --- 16,24 ---- # exception, unless it calls a program-supplied function that # throws an exception. # ! # Specific functions are commented out for the reason noted in each case. # ! # abort -- synchronous exception from SIGABRT handler abs acos asctime *************** atexit *** 29,35 **** atof atoi atol ! #bsearch btowc calloc ceil --- 29,35 ---- atof atoi atol ! #bsearch -- calls user function which may throw exception btowc calloc ceil *************** div *** 43,83 **** exit exp fabs ! fclose feof ferror ! fflush ! fgetc ! fgetpos ! fgets ! fgetwc ! fgetws floor fmod ! fopen ! fprintf ! fputc ! fputs ! fputwc ! fputws ! fread free ! freopen frexp ! fscanf fseek ! fsetpos ! ftell fwide ! fwprintf ! fwrite ! fwscanf ! getc ! getchar getenv ! gets ! getwc ! getwchar gmtime isalnum isalpha --- 43,83 ---- exit exp fabs ! #fclose -- POSIX thread cancellation point feof ferror ! #fflush -- POSIX thread cancellation point ! #fgetc -- POSIX thread cancellation point ! #fgetpos -- POSIX thread cancellation point ! #fgets -- POSIX thread cancellation point ! #fgetwc -- POSIX thread cancellation point ! #fgetws -- POSIX thread cancellation point floor fmod ! #fopen -- POSIX thread cancellation point ! #fprintf -- POSIX thread cancellation point ! #fputc -- POSIX thread cancellation point ! #fputs -- POSIX thread cancellation point ! #fputwc -- POSIX thread cancellation point ! #fputws -- POSIX thread cancellation point ! #fread -- POSIX thread cancellation point free ! #freopen -- POSIX thread cancellation point frexp ! #fscanf -- POSIX thread cancellation point fseek ! #fsetpos -- POSIX thread cancellation point ! #ftell -- POSIX thread cancellation point fwide ! #fwprintf -- POSIX thread cancellation point ! #fwrite -- POSIX thread cancellation point ! #fwscanf -- POSIX thread cancellation point ! #getc -- POSIX thread cancellation point ! #getchar -- POSIX thread cancellation point getenv ! #gets -- POSIX thread cancellation point ! #getwc -- POSIX thread cancellation point ! #getwchar -- POSIX thread cancellation point gmtime isalnum isalpha *************** memmove *** 125,146 **** memset mktime modf ! perror pow ! printf ! putc ! putchar ! puts ! putwc ! putwchar ! #qsort ! raise rand realloc ! remove ! rename ! rewind ! scanf setbuf setlocale setvbuf --- 125,146 ---- memset mktime modf ! #perror -- POSIX thread cancellation point pow ! #printf -- POSIX thread cancellation point ! #putc -- POSIX thread cancellation point ! #putchar -- POSIX thread cancellation point ! #puts -- POSIX thread cancellation point ! #putwc -- POSIX thread cancellation point ! #putwchar -- POSIX thread cancellation point ! #qsort -- calls user function which may throw exception ! #raise -- synchronous exception from signal handler rand realloc ! #remove -- POSIX thread cancellation point ! #rename -- POSIX thread cancellation point ! #rewind -- POSIX thread cancellation point ! #scanf -- POSIX thread cancellation point setbuf setlocale setvbuf *************** strcmp *** 157,163 **** strcoll strcpy strcspn ! strerror strftime strlen strncat --- 157,163 ---- strcoll strcpy strcspn ! #strerror -- POSIX thread cancellation point strftime strlen strncat *************** strtoul *** 174,198 **** strxfrm swprintf swscanf ! system tan tanh time ! tmpfile ! tmpnam tolower toupper towctrans towlower towupper ! ungetc ! ungetwc ! vfprintf ! vfwprintf ! vprintf vsprintf vswprintf ! vwprintf wcrtomb wcscat wcschr --- 174,198 ---- strxfrm swprintf swscanf ! #system -- POSIX thread cancellation point tan tanh time ! #tmpfile -- POSIX thread cancellation point ! #tmpnam -- POSIX thread cancellation point tolower toupper towctrans towlower towupper ! #ungetc -- POSIX thread cancellation point ! #ungetwc -- POSIX thread cancellation point ! #vfprintf -- POSIX thread cancellation point ! #vfwprintf -- POSIX thread cancellation point ! #vprintf -- POSIX thread cancellation point vsprintf vswprintf ! #vwprintf -- POSIX thread cancellation point wcrtomb wcscat wcschr *************** wmemcmp *** 225,229 **** wmemcpy wmemmove wmemset ! wprintf ! wscanf --- 225,229 ---- wmemcpy wmemmove wmemset ! #wprintf -- POSIX thread cancellation point ! #wscanf -- POSIX thread cancellation point diff -Nrc3pad gcc-3.2.3/gcc/cp/cfns.h gcc-3.3/gcc/cp/cfns.h *** gcc-3.2.3/gcc/cp/cfns.h 2000-04-04 20:46:23.000000000 +0000 --- gcc-3.3/gcc/cp/cfns.h 2003-05-02 21:01:23.000000000 +0000 *************** *** 1,5 **** ! /* C code produced by gperf version 2.7 */ ! /* Command-line: gperf -o -C -E -k 1-6,$ -j1 -D -N libc_name_p ../../../egcs-CVS20000404/gcc/cp/cfns.gperf */ #ifdef __GNUC__ __inline #endif --- 1,5 ---- ! /* C code produced by gperf version 2.7.2 */ ! /* Command-line: gperf -o -C -E -k '1-6,$' -j1 -D -N libc_name_p ../../../src-3.3/gcc/cp/cfns.gperf */ #ifdef __GNUC__ __inline #endif *************** static unsigned int hash PARAMS ((const *** 8,17 **** __inline #endif const char * libc_name_p PARAMS ((const char *, unsigned int)); ! /* maximum key range = 1020, duplicates = 1 */ #ifdef __GNUC__ __inline #endif static unsigned int hash (str, len) --- 8,21 ---- __inline #endif const char * libc_name_p PARAMS ((const char *, unsigned int)); ! /* maximum key range = 480, duplicates = 1 */ #ifdef __GNUC__ __inline + #else + #ifdef __cplusplus + inline + #endif #endif static unsigned int hash (str, len) *************** hash (str, len) *** 20,51 **** { static const unsigned short asso_values[] = { ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 0, 1, ! 0, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 247, 218, 144, ! 0, 0, 40, 7, 126, 184, 2, 15, 146, 67, ! 9, 60, 0, 0, 3, 0, 7, 8, 197, 1, ! 40, 8, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, ! 1038, 1038, 1038, 1038, 1038, 1038 }; register int hval = len; --- 24,55 ---- { static const unsigned short asso_values[] = { ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 0, 0, ! 1, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 106, 76, 0, ! 21, 0, 0, 11, 43, 26, 0, 66, 106, 17, ! 121, 0, 17, 0, 7, 0, 3, 19, 49, 1, ! 3, 41, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, ! 483, 483, 483, 483, 483, 483 }; register int hval = len; *************** libc_name_p (str, len) *** 79,434 **** { enum { ! TOTAL_KEYWORDS = 207, MIN_WORD_LENGTH = 3, MAX_WORD_LENGTH = 10, ! MIN_HASH_VALUE = 18, ! MAX_HASH_VALUE = 1037 }; static const char * const wordlist[] = { ! "gets", ! "puts", ! "sqrt", ! "strerror", ! "strstr", ! "strspn", ! "exp", "free", ! "fgets", ! "fputs", ! "fgetws", ! "fputws", "pow", ! "fseek", ! "perror", ! "strtod", ! "toupper", ! "towupper", ! "frexp", ! "strtok", ! "fsetpos", "ferror", ! "freopen", ! "fgetpos", ! "fopen", "wmemset", "memset", - "system", - "wcsstr", - "wctype", - "strxfrm", - "wcsspn", - "strcspn", - "fmod", - "strcpy", - "strncpy", - "strlen", - "ungetwc", - "feof", - "ldexp", - "isupper", - "rewind", - "iswupper", - "sin", - "cos", - "modf", - "iswpunct", - "wcstod", - "log10", - "log", - "wcsrtombs", - "strcmp", - "fwide", - "towctrans", - "strncmp", - "strtoul", - "fwrite", - "exit", - "swprintf", - "wcstok", "strftime", ! "sprintf", ! "wprintf", ! "strpbrk", "time", ! "rand", ! "srand", "wmemmove", ! "tan", ! "tolower", ! "fwprintf", ! "towlower", ! "wcstombs", ! "printf", ! "fprintf", "strchr", "strrchr", - "wmemcpy", - "fread", - "getwchar", - "putwchar", - "longjmp", - "memcpy", - "wcsxfrm", - "wcscspn", - "getc", - "putc", - "getwc", - "putwc", - "wcscpy", - "wcsncpy", - "wcslen", - "floor", - "setbuf", - "ungetc", - "rename", - "remove", - "gmtime", - "mktime", - "fgetc", - "fputc", - "fgetwc", - "fputwc", - "memcmp", - "iswctype", "wmemcmp", ! "ispunct", ! "mbstowcs", ! "wcscmp", ! "mbsrtowcs", ! "setlocale", ! "wcsncmp", ! "wcstoul", ! "strtol", ! "wcsftime", "iswprint", ! "wcspbrk", ! "iswdigit", ! "isprint", ! "fclose", ! "atof", ! "islower", ! "iswlower", ! "ctime", "wmemchr", "memchr", - "wctrans", - "strcat", - "getenv", - "strncat", - "iswxdigit", - "wcschr", - "wcsrchr", "isxdigit", "vswprintf", - "raise", - "iswspace", - "vsprintf", - "vwprintf", - "vprintf", - "swscanf", - "sinh", - "tmpfile", - "asin", - "mblen", "acos", - "mbrlen", - "cosh", - "difftime", - "memmove", - "abs", - "tmpnam", - "vfwprintf", - "setvbuf", - "vfprintf", - "scanf", - "sscanf", - "wscanf", - "fwscanf", - "ftell", - "fflush", - "atexit", - "iswcntrl", - "iscntrl", "mbrtowc", "wcrtomb", ! "fabs", ! "wcstol", ! "strcoll", ! "atan2", ! "tanh", ! "atan", ! "fscanf", ! "clock", ! "getchar", ! "putchar", ! "abort", ! "clearerr", "wcscat", - "wcsncat", "isdigit", ! "isgraph", ! "iswgraph", ! "btowc", "div", "isspace", ! "atol", ! "labs", ! "ceil", ! "mbtowc", ! "wcscoll", ! "wctob", "asctime", ! "iswalnum", ! "isalnum", ! "mbsinit", "atoi", "wctomb", "ldiv", ! "signal", ! "realloc", "localtime", "iswalpha", "localeconv", "isalpha", ! "malloc", ! "calloc" }; static const short lookup[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, 0, 1, -1, 2, -1, -1, ! -1, -1, -1, 3, -1, 4, -1, -1, ! -1, -1, 5, -1, -1, -1, -1, -1, ! -1, -1, -1, 6, -1, -1, -1, 7, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, 8, 9, 10, 11, -1, ! -1, 12, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, 13, -1, -1, 14, -1, ! -1, -1, -1, 15, -1, 16, -1, 17, ! 18, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, 19, 20, -1, -1, -1, 21, 22, ! -1, 23, -1, 24, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, 25, -1, -1, ! -1, -1, 26, 27, -1, -1, -1, -1, ! -1, -1, -1, -1, 28, -1, 29, 30, ! -1, 31, 32, 33, -1, -1, -1, -1, ! 34, -1, 35, -1, 36, -1, -1, 37, ! 38, -1, -1, -1, -1, -1, -1, 39, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, 40, 41, 42, 43, -1, 44, ! -1, -1, -1, 45, -1, -1, -1, -1, ! -1, 46, 47, 48, -1, -1, -1, 49, ! 50, -1, -1, 51, -1, -1, 52, 53, ! -1, -1, -1, -1, -1, 54, 55, -1, ! -1, 56, 57, -1, -1, 58, -1, -1, ! 59, 60, 61, 62, -1, 63, -1, -1, ! -1, -1, -1, -1, -1, -1, 64, 65, ! 66, -1, -1, -1, -1, -1, 67, -1, ! -1, -1, -1, 68, -1, -1, -1, -1, ! -1, -1, -1, -1, 69, 70, 71, 72, ! -1, 73, 74, -1, 75, 76, 77, 78, ! 79, 80, 81, -1, 82, -1, 83, -1, ! -1, 84, 85, 86, 87, 88, -1, 89, ! -1, 90, -1, 91, -1, 92, -1, 93, ! -1, -1, -1, -1, -1, 94, -1, -1, ! -1, -1, -1, -1, 95, 96, -1, -1, ! -1, -1, 97, -1, -1, -1, -1, -1, ! -1, -1, 98, 99, 100, 101, 102, 103, ! 104, 105, -1, -1, -1, -1, -1, 106, ! -1, 107, 108, -1, 109, -1, 110, -1, ! -1, -1, -1, -1, 111, 112, -1, 113, ! -1, -1, -1, -1, -1, -1, -1, -1, ! 114, -1, -1, 115, 116, -1, -1, 117, ! -1, -1, 118, -1, 119, -1, 120, -1, ! -1, 121, -1, 122, -1, -1, -1, 123, ! -1, -1, -1, -1, -1, -1, -1, 124, ! 125, -1, 126, -1, -1, 127, -1, 128, ! 129, 130, -1, 131, 132, -1, 133, -1, ! -1, -1, 134, -1, -1, -1, -1, 135, ! 136, 137, 138, -1, -1, -1, -1, 139, ! 140, 141, -1, 142, -1, 143, 144, 145, ! -1, -1, 146, -1, 147, -1, -1, 148, ! -1, 149, -1, -1, 150, -1, 151, -1, ! -1, -1, 152, -1, -1, 153, -1, -1, ! -1, 154, -1, -1, -1, 155, 156, 157, ! 158, -1, 159, -1, 160, -1, -1, -1, ! -1, -1, 161, 162, 163, -1, -1, -1, ! -1, -1, -1, -719, -1, 166, 167, -43, ! -2, 168, -1, 169, -1, -1, -1, 170, ! -1, -1, -1, 171, -1, -1, 172, -1, ! -1, 173, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, 174, 175, -1, ! -1, -1, -1, 176, -1, -1, -1, 177, ! -1, -1, -1, -1, 178, -1, -1, 179, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, 180, 181, -1, ! 182, -1, -1, 183, -1, 184, 185, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, 186, -1, -1, -1, -1, 187, ! -1, -1, -1, -1, -1, -1, -1, -1, ! 188, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, 189, ! 190, -1, -1, -1, -1, 191, -1, -1, ! 192, -1, -1, -1, -1, -1, 193, -1, ! -1, -1, -1, -1, 194, -1, -1, -1, ! -1, -1, -1, -1, 195, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, 196, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, 197, -1, -1, -1, -1, -1, -1, ! 198, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, 199, -1, -1, -1, -1, -1, -1, ! -1, 200, -1, -1, -1, -1, -1, 201, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, 202, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 203, -1, - -1, -1, -1, -1, -1, 204, -1, -1, - 205, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, 206 }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) --- 83,318 ---- { enum { ! TOTAL_KEYWORDS = 156, MIN_WORD_LENGTH = 3, MAX_WORD_LENGTH = 10, ! MIN_HASH_VALUE = 3, ! MAX_HASH_VALUE = 482 }; static const char * const wordlist[] = { ! "cos", ! "feof", "free", ! "sqrt", ! "wcsrtombs", "pow", ! "towctrans", ! "wcsstr", ! "wcstombs", ! "strstr", "ferror", ! "wcsxfrm", ! "wcsftime", ! "exit", ! "exp", ! "modf", ! "strxfrm", "wmemset", "memset", "strftime", ! "frexp", "time", ! "ctime", ! "wcstod", ! "fwide", ! "wcscmp", "wmemmove", ! "strtod", ! "fmod", ! "wcschr", ! "wcsrchr", ! "strcmp", ! "wctype", ! "toupper", ! "towupper", "strchr", "strrchr", "wmemcmp", ! "iswctype", ! "gmtime", ! "difftime", ! "btowc", "iswprint", ! "iswxdigit", ! "cosh", ! "memcmp", "wmemchr", + "isupper", + "iswupper", + "iswdigit", "memchr", "isxdigit", + "wmemcpy", + "mbtowc", + "setbuf", + "mbstowcs", + "wcscpy", + "memmove", "vswprintf", "acos", "mbrtowc", "wcrtomb", ! "mbsrtowcs", ! "atof", ! "strcpy", ! "setlocale", "wcscat", "isdigit", ! "log10", ! "tolower", ! "floor", ! "towlower", ! "strcat", ! "log", ! "mktime", ! "wcstoul", ! "fseek", ! "memcpy", ! "wcstok", ! "strtoul", ! "wcscspn", ! "islower", "div", + "iswlower", + "atexit", + "strtok", + "setvbuf", + "strcspn", "isspace", ! "iswspace", "asctime", ! "wctob", ! "wcsncmp", "atoi", + "ldexp", + "strncmp", + "wcspbrk", "wctomb", + "swprintf", + "sprintf", + "strpbrk", + "abs", + "fabs", + "wcsncpy", + "ispunct", + "iswpunct", + "strncpy", + "iswgraph", + "isprint", + "isgraph", + "wcscoll", + "wcstol", + "vsprintf", + "strcoll", + "strtol", + "sscanf", + "clearerr", + "swscanf", + "sinh", + "wcsncat", + "getenv", + "ceil", + "clock", + "wctrans", + "strncat", "ldiv", ! "iswcntrl", ! "wcsspn", ! "iscntrl", ! "sin", ! "strspn", ! "mbsinit", ! "longjmp", ! "rand", ! "srand", ! "labs", ! "tanh", ! "calloc", ! "atol", "localtime", + "realloc", + "malloc", + "atan2", + "tan", + "wcslen", + "strlen", "iswalpha", "localeconv", + "asin", + "iswalnum", + "isalnum", "isalpha", ! "mblen", ! "mbrlen", ! "atan", ! "signal" }; static const short lookup[] = { + -1, -1, -1, 0, 1, -1, -1, -1, + -1, -1, -1, 2, -1, -1, -1, -1, + -1, 3, -1, -1, 4, -1, 5, 6, + 7, -1, -1, -1, -1, 8, -1, -1, + -1, 9, 10, 11, -1, -1, 12, 13, + 14, -1, 15, -1, 16, 17, 18, 19, + -1, 20, 21, 22, 23, 24, -1, -1, + -1, -1, 25, -1, 26, 27, -1, 28, + 29, 30, -1, 31, 32, -1, 33, -1, + 34, 35, 36, -1, 37, -1, -1, 38, + 39, -1, -1, -1, 40, 41, -1, -1, + 42, 43, 44, 45, 46, 47, -1, 48, + 49, 50, 51, -1, 52, -1, -1, 53, + 54, 55, 56, 57, -1, 58, 59, -273, + 62, 63, -1, 64, -96, -2, 65, 66, + 67, -1, 68, -1, 69, 70, 71, -1, + 72, -1, -1, 73, -1, -1, -1, 74, + 75, 76, -1, 77, -1, -1, 78, -1, + -1, 79, 80, 81, 82, 83, 84, 85, + -1, -1, 86, 87, 88, -1, 89, 90, + -1, 91, -1, 92, -1, 93, -1, -1, + -1, 94, -1, -1, 95, -1, 96, -1, + -1, -1, -1, 97, 98, 99, -1, 100, + -1, 101, 102, 103, -1, -1, -1, -1, + -1, 104, -1, 105, 106, -1, -1, -1, + -1, -1, 107, -1, -1, -1, -1, 108, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 109, -1, -1, 110, -1, 111, -1, + -1, -1, -1, -1, 112, 113, -1, 114, + -1, 115, 116, 117, -1, 118, 119, 120, + -1, -1, 121, 122, -1, 123, -1, 124, + -1, -1, -1, -1, -1, -1, -1, 125, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, 126, 127, -1, -1, -1, 128, 129, ! -1, -1, -1, 130, 131, -1, -1, 132, ! 133, 134, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, 135, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 136, -1, -1, -1, 137, 138, -1, -1, + -1, -1, 139, -1, 140, -1, -1, -1, + -1, -1, -1, -1, -1, 141, -1, 142, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 143, 144, -1, -1, -1, -1, + -1, -1, -1, -1, 145, -1, -1, -1, + -1, -1, 146, -1, -1, -1, -1, -1, + -1, 147, 148, -1, -1, -1, -1, -1, + -1, 149, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 150, -1, -1, -1, -1, -1, + -1, -1, -1, 151, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 152, -1, + -1, -1, -1, -1, -1, -1, 153, -1, + -1, -1, -1, -1, -1, 154, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, 155 }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) diff -Nrc3pad gcc-3.2.3/gcc/cp/ChangeLog gcc-3.3/gcc/cp/ChangeLog *** gcc-3.2.3/gcc/cp/ChangeLog 2003-04-22 06:14:55.000000000 +0000 --- gcc-3.3/gcc/cp/ChangeLog 2003-05-14 00:09:54.000000000 +0000 *************** *** 1,35 **** ! 2003-04-22 Release Manager ! * GCC 3.2.3 Released. 2003-04-15 Jason Merrill * decl2.c (mark_used): Don't instantiate anything if skip_evaluation. ! 2003-03-24 Jakub Jelinek ! * Backport from mainline: ! 2002-05-13 Jason Merrill ! * class.c (build_vtbl_ref_1): Use fixed_type_or_null. ! (fixed_type_or_null): See through reference vars. ! (build_base_path): Vtable contents are constant. 2003-03-19 Jason Merrill PR c++/8316, c++/9315, c++/10136 * call.c (joust): Improve wording. 2003-03-17 Jason Merrill * decl.c (finish_function): Don't skip a block. PR c++/9993 * decl.c (finish_function): Only allow the NRVO to use variables declared at function scope. ! 2003-03-16 Kriang Lerdsuwanakij PR c++/6440 * pt.c (maybe_process_partial_specialization): Handle --- 1,266 ---- ! 2003-05-13 Release Manager ! * GCC 3.3 Released. ! ! 2003-05-13 Release Manager ! ! * GCC 3.3 Released. ! ! 2003-05-13 Release Manager ! ! * GCC 3.3 Released. ! ! 2003-05-13 Release Manager ! ! * GCC 3.3 Released. ! ! 2003-05-02 Richard Henderson ! ! PR c++/10570 ! * cfns.gperf: Comment out POSIX thread cancellation points, ! plus abort and raise. ! * cfns.h: Regenerate. ! ! 2003-05-01 Mark Mitchell ! ! * decl2.c (comdat_linkage): Don't externalize explicit ! instantiations. ! ! 2003-04-29 Mark Mitchell ! ! PR c++/10551 ! * pt.c (mark_decl_instantiated): Defer all explicit instantiations ! that have not yet been written out. ! ! PR c++/10549 ! * class.c (layout_class_type): Mark overlong bitfields as having ! the maximum size permitted by their type, after layout. ! ! 2003-04-29 Mark Mitchell ! ! PR c++/10527 ! * error.c (dump_expr): Correctly handling of NEW_EXPR.4 ! ! 2003-04-29 Kriang Lerdsuwanakij ! ! * lang-options.h: Fix typo. ! ! 2003-04-29 Mark Mitchell ! ! PR c++/10515 ! * cp-tree.h (lookup_field_1): Declare it. ! * search.c (lookup_field_1): Make it public. ! * decl.c (reshape_init): Handle designated initializers. ! ! 2003-04-29 Mark Mitchell ! ! * decl.c (maybe_commonize_var): Further tweak support for systems ! without weak symbols. ! ! 2003-04-27 Mark Mitchell ! ! * decl.c (maybe_commonize_var): Fix thinko in last patch. ! ! PR c++/10506 ! * method.c (use_thunk): Decrement immediate_size_expand. ! ! PR c++/10503 ! * cp-tree.h (DECL_VAR_MARKED_P): New macro. ! (DECL_MAYBE_TEMPLATE): Remove. ! * class.c (fixed_type_or_null): Avoid infinite recursion. ! ! 2003-04-27 Mark Mitchell ! ! * decl.c (maybe_commonize_var): Make the code match the comments. ! * pt.c (instantiate_decl): Move call to import_export_decl. ! ! 2003-04-25 Mark Mitchell ! ! * decl2.c (finish_file): Don't call import_export_decl for ! functions that are not defined. ! (handle_class_head): Robustify. ! * pt.c (instantiate_decl): Do not call cp_finish_decl for ! variables that are not defined. ! ! 2003-04-23 Mark Mitchell ! ! PR c++/10471 ! * call.c (build_cxx_call): Robustify. ! ! 2003-04-23 Mark Mitchell ! ! PR c++/10451 ! * decl.c (grokdeclarator): Correct logic for "mutable" errors. ! ! 2003-04-22 Mark Mitchell ! ! PR c++/10446 ! * search.c (lookup_fnfields_1): Handle empty slots in the method ! vector. ! ! 2003-04-22 Mark Mitchell ! ! PR c++/10428 ! * decl.c (check_elaborated_type_specifier): New function, split ! out from ... ! (xref_tag): ... here. Use the new function in more places. ! ! 2003-04-21 Mark Mitchell ! ! * call.c (build_over_call): Use build_cxx_call. ! (build_cxx_call): New method, split out of build_over_call. ! * cp-tree.h (language_function): Add can_throw. ! (build_cxx_call): Declare it. ! * decl.c (finish_function): If a function does not contain any ! calls to functions that can throw an exception, indicate that ! fact. ! * decl2.c (mark_used): Do not defer the instantiation of ! functions, if the current function does not throw. ! * optimize.c (maybe_clone_body): Copy TREE_NOTHROW to the clones. ! * pt.c (instantiate_decl): Make sure import_export_decl is called ! before emitting things. ! * rtti.c (throw_bad_cast): Use build_cxx_call. ! (build_dynamic_cast_1): Likewise. ! * typeck.c (build_function_call): Likewise. ! ! 2003-04-21 Nathan Sidwell ! ! PR c++/9881 ! * typeck.c (build_unary_op): Fold all COMPONENT_REF addr ! expressions. Reverts my 2002-08-08 patch. ! ! 2003-04-20 Nathan Sidwell ! ! PR c++/10405 ! * search.c (lookup_field_1): Final scan goes backwards for ! types, forwards for non-types. 2003-04-15 Jason Merrill * decl2.c (mark_used): Don't instantiate anything if skip_evaluation. ! 2003-04-15 Mark Mitchell ! * init.c (build_new_1): Use nullexp instead of null_node to avoid ! unwanted macro expansion. ! 2003-04-14 Ziemowit Laski ! ! * tree.c (build_cplus_array_type_1): Do not call ! uses_template_parms() on a NULL index_type. ! ! 2003-04-14 Andreas Schwab ! ! * init.c (build_new_1): Test use_cookie instead of cookie_size to ! avoid code-gen bug on ia64. ! ! 2003-04-13 Mark Mitchell ! ! PR c++/10300 ! * init.c (build_new_1): Correct logic for checking whether the ! return value from the allocation function was zero. ! ! 2003-03-31 Mark Mitchell ! ! PR c++/10278 ! * spew.c (yyerror): Avoid crashing at all costs. ! ! 2003-03-31 Jason Merrill ! ! PR java/10145 ! * class.c (check_field_decl): Don't set DECL_ALIGN. ! ! 2003-03-30 Mark Mitchell ! ! PR c++/7647 ! * search.c (lookup_field_1): Add want_type parameter. ! (lookup_field_r): Adjust call to lookup_field_1. ! ! 2003-03-28 Jason Merrill ! ! PR c++/10245 ! * cvt.c (force_rvalue): New fn. ! * call.c (build_conditional_expr): Use it. ! * cp-tree.h: Declare it. ! ! 2003-03-28 Nathan Sidwell ! ! PR c++/10047 ! * decl2.c (finish_file): Don't warn about explicitly instantiated ! inline decls. ! ! 2003-03-27 Nathan Sidwell ! ! PR c++/10158 ! * spew.c (snarf_method):Set DECL_INITIALIZED_IN_CLASS for ! members. ! * pt.c (instantiate_decl): Only reduce the template args for ! friends that are not defined in class. ! ! 2003-03-24 Nathan Sidwell ! ! PR c++/9898, PR c++/383, DR 322 ! * pt.c (maybe_adjust_types_for_deduction) [DEDUCE_CONV]: Look ! through reference types on both PARM and ARG. ! ! PR c++/10199 ! * call.c (build_method_call): Deal with LOOKUP_EXPR. ! * semantics.c (finish_object_call_expr): Use build_method_call ! when in a template decl. ! ! 2003-03-23 Mark Mitchell ! ! PR c++/7086 ! * semantics.c (genrtl_named_return_value): Adjust calls to ! put_var_into_stack. ! * typeck.c (cxx_mark_addressable): Likewise. ! ! 2003-03-20 Mark Mitchell ! ! PR c++/6412 ! * cp/decl2.c (arg_assoc_class): Correct check for namespace-scope ! friends. ! * cp/pt.c (instantiate_class_template): Fix formatting. 2003-03-19 Jason Merrill PR c++/8316, c++/9315, c++/10136 * call.c (joust): Improve wording. + 2003-03-18 Roger Sayle + + PR c++/10031 + * decl.c (duplicate_decls): Use the new type when prototyping + anticipated decls, even when the types match. This defines the + exception list for the built-in function. + 2003-03-17 Jason Merrill + PR c++/10091 + * typeck.c (build_class_member_access_expr): Compare + TYPE_MAIN_VARIANTs. + * decl.c (finish_function): Don't skip a block. PR c++/9993 * decl.c (finish_function): Only allow the NRVO to use variables declared at function scope. ! 2003-03-17 Nathan Sidwell ! ! PR c++/9629 ! * cp-tree.h (struct language_function): Add in_base_initializer. ! (in_base_initializer): define it. ! (expand_member_init): Remove INIT param. ! * init.c (expand_member_init): Remove INIT param, return the member. ! (emit_mem_initializers): Set in_base_initializer. ! * class.c (build_base_path): Check in_base_initializer. ! * parse.y (begin_member_init): New reduction. ! (member_init): Use it. ! * pt.c (tsubst_initializer_list): Set in_base_initializer. ! ! 2003-03-15 Kriang Lerdsuwanakij PR c++/6440 * pt.c (maybe_process_partial_specialization): Handle *************** *** 44,60 **** --- 275,620 ---- * search.c (lookup_conversions): Call complete_type here. * call.c (implicit_conversion): Not here. + 2003-03-13 Jason Merrill + + PR c++/9336 + * decl2.c (lookup_arg_dependent): Handle error_mark_node. + + 2003-03-13 Mark Mitchell + + * decl2.c (do_nonmember_using_decl): Correct handling of + simultaneous type/non-type bindings. + + 2003-03-13 Mark Mitchell + + * call.c (initialize_reference): Remove bogus assertion. + * decl.c (build_ptrmemfunc_type): Revert change of 2003-03-09. + 2003-03-12 Andrew Lewycky PR c++/7050 * expr.c (cxx_expand_expr): Return const0_rtx for throw expressions. + 2003-03-11 Mark Mitchell + + PR c++/9474 + * decl2.c (do_nonmember_using_decl): Do not call duplicate decls + to merge old and new declarations. + + 2003-03-11 Mark Mitchell + + PR c++/9924 + * decl2.c (do_nonmember_using_decl): Ignore anticipated builtins. + + 2003-03-11 Jason Merrill + + PR c++/9820 + * search.c (lookup_member): Fix handling of functions in a class + being defined. + + 2003-03-11 Mark Mitchell + + PR c++/8700 + * call.c (print_z_candidates): Avoid printing duplicates. + + 2003-03-11 Jason Merrill + + PR c++/8660 + * decl2.c (check_classfn): A member template only matches a + member template. + + 2003-03-10 Devang Patel + + PR c++/9394 + * g++spec.c (lang_specific_driver): Use DEFAULT_WORD_SWITCH_TAKES_ARG. + 2003-03-10 Jason Merrill PR c++/9798 * decl.c (push_using_directive): Push before recursing. + PR c++/9868 + * call.c (resolve_scoped_fn_name): Handle the case of a function + pointer member. + * init.c (build_offset_ref): Handle getting a FIELD_DECL for NAME. + + * decl2.c (build_offset_ref_call_from_tree): Only mess with 'this' + argument in the pointer-to-member case. + + 2003-03-09 Mark Mitchell + + PR c++/9373 + * cp-lang.c (cxx_get_alias_set): Use alias set zero for + pointers to member functions. + + PR c++/8534 + * decl.c (build_ptrmemfunc_type): Do not allow default arugments + in pointer-to-member-function types. + + 2003-03-09 Mark Mitchell + + PR c++/9912 + * cp-tree.h (is_ancestor): New function. + * decl2.c (is_namespace_ancestor): Rename to ... + (is_ancestor): ... this. + (namespace_ancestor): Use it. + (set_decl_namespace): Likewise. + (handle_class_head): Check for invalid class definitions. + + 2003-03-10 Gabriel Dos Reis + + Compile-time improvement: 2/n. + * cp-tree.h (struct cxx_binding): New datatype; + (struct lang_identifier): Use it. + (LOCAL_BINDING_P): Adjust definition. + (INHERITED_VALUE_BINDING_P): Likewise. + (BINDING_SCOPE): Likewise. + (BINDING_HAS_LEVEL_P): Likewise. + (BINDING_VALUE): Likewise. + (BINDING_TYPE): Likewise. + (IDENTIFIER_VALUE): Likewise. + (struct tree_binding): Remove. + (TS_CP_BINDING): Likewise. + ((union lang_tree_node): Remove field "binding". + (cxx_binding_clear): New macro. + (binding_for_name): Adjust return type. + (qualified_lookup_using_namespace): Adjust prototype. + (lookup_using_namespace): Adjust prototype. + (cxx_scope_find_binding_for_name): Declare. + * cp-tree.def: Remove CPLUS_BINDING definition. + * parse.y (parse_scoped_id): Don't type-abuse of 'id'. Allocate + temporary cxx_binding on stack. Simplify. + * decl.c (push_binding): Adjust local variable type. + (add_binding): Likewise. + (push_class_binding): Likewise. + (pop_binding): Likewise. + (poplevel): Likewise. + (poplevel_class): Likewise. + (free_bindings): Adjust type. + (find_binding): Adjust return type, add a third parameter. Remove + non-useful assertion now that we use static typing. + (cxx_scope_find_binding_for_name): New function. + (binding_for_name): Use it. Adjust local variable type. Simplify. + (namespace_binding): Simplify. + (set_namespace_binding): Likewise. + (set_identifier_type_value_with_scope): Adjust local variable type. + (lookup_tag): Don't type-abuse of local variable 'old'. + (lookup_namespace_name): Likewise. Allocate binding on stack. + (select_decl): Adjust prototype. + (unqualified_namespace_lookup): Allocate binding on stack. + Don't type-abuse of local variable 'val'. + (lookup_name_real): Likewise. + (maybe_inject_for_scope_var): Adjust local variable type. + (cp_tree_node_structure): Remove CPLUS_BINDING case label. + (namespace_binding): Adjust logic, simplify. + (BINDING_LEVEL): Adjust definition. + (push_class_level_binding): Adjust local variable type. + (struct cxx_saved_binding): Adjust field 'binding' type. + * decl2.c (ambiguous_decl): Adjust prototype. + (lookup_using_namespace): Adjust local variable type. + (qualified_lookup_using_namespace): Catch type error and correct + ensueing logic error. + (do_nonmember_using_decl): Adjust local variable type. Allocate + temporary cxx_binding on stack. + (do_toplevel_using_decl): Adjust local variable type. + * ptree.c (cxx_print_cxx_binding): New function. + (cxx_print_identifier): Use it. + (cxx_print_xnode): Delete CPLUS_BINDING case label. + + 2003-03-09 Kriang Lerdsuwanakij + + PR c++/9970 + * decl.c (duplicate_decls): Only copy DECL_THUNKS for virtual + functions. + + 2003-03-07 Matt Austern + + * cp-tree.h (struct lang_type_class): add field for key method + (cp_global_trees): rename dynamic_classes to keyed_classes + (key_method): add definition + * class.c (finish_struct_1): compute class's key method, and add + the class to keyed_classes list if there is no key method. + * decl.c (finish_function): add class to keyed_classes list if we + see a definition of the class's key method. + * pt.c (instantiate_class_template): add template specialization + of a dynamic class to keyed_classes list. + * decl2.c (key_method): remove + (finish_file): iterate only through keyed_classes list when + deciding whether to emit vtables, remove class from its list after + we do the emission. + + 2003-03-08 Mark Mitchell + + PR c++/9809 + * call.c (add_function_candidate): Skip builtin fuctions that have + not yet been declared. + + 2003-03-07 Mark Mitchell + + * call.c (reference_binding): Remove REF_IS_VAR parameter. + (implicit_conversion): Adjust call to reference_binding. + (make_temporary_var_for_ref_to_type): Add TYPE parameter. + (initialize_reference): Adjust handling for references bound to + rvalues. + * cp-tree.h (make_temporary_var_for_ref_to_temp): Change + prototype. + (real_non_cast_lvalue_p): New method. + * cvt.c (build_up_reference): Adjust use of + make_temporary_var_for_ref_to_temp. + * tree.c (real_non_cast_lvalue_p): New method. + + 2003-03-06 Mark Mitchell + + * call.c (merge_conversion_sequences): New function. + (build_conv): Set ICS_USER_FLAG for USER_CONVs. + (convert_class_to_reference): Correct handling of second + standard conversion sequence in a user-defined conversion + sequence. + (build_user_type_conversion_1): Use merge_conversion_sequences. + * cp-tree.def: Add comments for CONV nodes. + + 2003-03-06 Mark Mitchell + + PR c++/9965 + * call.c (reference_binding): Add ref_is_var parameter. + (implicit_conversion): Adjust call to reference_binding. + (initialize_reference): Likewise. + + PR c++/9400 + * decl.c (pushdecl): Don't check for shadowing of DECL_ARTIFICIAL + PARM_DECLs. + + 2003-03-06 Mark Mitchell + + PR c++/9791 + * class.c (get_basefndecls): Use lookup_fnfields_1. + + 2003-03-02 Matt Austern + + * decl.c (cp_binding_level): Add static_decls varray member. + (add_decl_to_level): Add static/inline namespace scope + declarations to static_decls array. + (wrapup_global_for_namespace): Pass static_decls only, instead of + all decls, to wrapup_global_declarations/check_global_declarations. + (push_namespace): Initialize static_decls for ordinary namespaces. + (cxx_init_decl_processing): Initialize static_decls for global + namespace. + + 2003-03-05 Mark Mitchell + + * class.c (end_of_class): Correct thinko. + + 2003-03-04 Gabriel Dos Reis + + * cp-tree.h (cxx_saved_binding): Declare. + (struct saved_scope): Adjust type of field 'old_binding'. + * decl.c (cxx_saved_binding_make): New macro. + (struct cxx_saved_binding): Define. + (store_bindings): Adjust prototype. Use cxx_saved_binding to save + C++ bindings. + (maybe_push_to_top_level): Adjust local variable type. + (pop_from_top_level): Likewise. + + 2003-03-03 Jason Merrill + + * decl.c (finish_enum): Do set the type in a template. Simplify. + * pt.c (tsubst_enum, tsubst_copy): Revert last patch. + + 2003-03-03 Mark Mitchell + + PR c++/9878 + * call.c (convert_class_to_reference): Correct conversion + sequences. + (reference_binding): Add ref_bound_directly_to_rvalue_p parameter. + (implicit_conversion): Adjust call to reference_binding. + (add_candidate): Change type of candidates parameter. + (add_function_candidate): Likewise. + (add_conv_candidate): Likewise. + (build_builtin_candidate): Likewise. + (add_builtin_candidate): Likewise. + (add_builtin_candidates): Likewise. + (add_template_candidate_real): Likewise. + (add_template_candidate): Likewise. + (add_template_conv_candidate): Likewise. + (build_user_type_conversion_1): Adjust accordingly. + (build_object_call): Likewise. + (build_conditional_expr): Likewise. + (add_candidates): Likewise. + (build_new_op): Likewise. + (convert_like_real): Use USER_CONV_CAND. Use build_nop. + (build_new_method_call): Adjust calls to add_function_candidate. + (make_temporary_var_for_ref_to_temp): New function. + (initialize_reference): Add decl parameter. + * class.c (build_rtti_vtbl_entries): Use build_address and + build_nop. + * cp-tree.h (initialize_reference): Change prototype. + (make_temporary_var_for_ref_to_temp): New function. + (build_type_conversion): Change prototype. + (build_address): New function. + (build_nop): Likewise. + * cvt.c (cp_convert_to_pointer): Adjust call to + build_type_conversion. Avoid indicating redundant NOP_EXPRs. + Use build_nop. + (convert_to_pointer_force): Use build_nop. + (build_up_reference): Use make_temporary_var_for_ref_to_temp. + (convert_to_reference): Adjust call to build_type_conversion. + (ocp_convert): Likewise. + (build_type_conversion): Remove for_sure parameter. + * decl.c (grok_reference_init): Use initialize_reference. + * typeck.c (build_address): New function. + (build_nop): Likewise. + (build_unary_op): Use them. + (build_ptrmemfunc): Tidy slightly. + (convert_for_initialization): Adjust call to + initialize_reference. + * typeck2.c (store_init_value): Remove #if 0'd code. + + 2003-03-02 Ashif Harji + + * lang-specs.h (default_compilers): Add -no-integrated-cpp flag to + invoke an external cpp during compilation. + + 2003-02-28 Mark Mitchell + + PR c++/9892 + * pt.c (instantiate_decl): Clear DECL_RTL for a VAR_DECL when + instantiating it. + + 2003-02-28 Mark Mitchell + + PR c++/9879 + * cp-tree.h (build_zero_init): Add parameter. + * decl.c (cp_finish_decl): Adjust call. + * init.c (build_zero_init): Add nelts parameter. Adjust recursive + calls. + (build_default_init): Add nelts parameter. Adjust calls to + build_zero_init. + (build_new_1): Adjust call to build_default_init. + * typeck2.c (process_init_constructor): Adjust call to build_zero_init. + + 2003-02-27 Devang Patel + + * decl.c (finish_enum): Merge two 'for' loops. Copy value node if required. + Postpone enum setting for template decls. + (build_enumerator): Delay copying value node until finish_enum (). Remove + #if 0'ed code. + * pt.c (tsubst_enum): Set TREE_TYPE and copy value node. + (tsubst_copy): Add check for enum type. + + + 2003-02-25 Mark Mitchell + + PR c++/9829 + * decl.c (grokdeclarator): Handle SCOPE_REFs whose second argument + is a NAMESPACE_DECL. + + 2003-02-24 Gabriel Dos Reis + + * decl.c (add_binding): Time TV_NAME_LOOKUP. + (push_class_binding): Likewise. + (set_namespace_binding): Likewise. + 2003-02-24 Kriang Lerdsuwanakij PR c++/9602 *************** *** 66,105 **** PR c++/7982 * decl.c (warn_about_implicit_typename_lookup): Handle TYPEOF_TYPE. ! 2003-02-19 Kriang Lerdsuwanakij PR c++/9459 * error.c (dump_type_prefix): Handle TYPEOF_TYPE. (dump_type_suffix): Likewise. ! 2003-02-10 Jason Merrill ! * call.c (call_builtin_trap): New fn. ! (convert_arg_to_ellipsis): Use it. Downgrade error to warning. ! (build_call): Don't set current_function_returns_abnormally outside ! a function. ! PR c++/8674 ! * call.c (build_over_call): Check specifically for TARGET_EXPR ! when eliding. ! 2003-02-05 Release Manager ! * GCC 3.2.2 Released. 2003-02-03 Mark Mitchell ! ! PR C++/7129 * operators.def: Add ?=. ! 2003-01-28 Christian Cornelssen * Make-lang.in (c++.install-common, c++.install-man) ! (c++.uninstall): Prepend $(DESTDIR) to destination paths ! in all (un)installation commands. (c++.install-common): Rewrite $(LN) commands to support DESTDIR with "ln" as well as with "ln -s". 2003-01-22 Mark Mitchell PR c++/9328 --- 626,790 ---- PR c++/7982 * decl.c (warn_about_implicit_typename_lookup): Handle TYPEOF_TYPE. ! 2003-02-21 Mark Mitchell ! ! PR c++/9749 ! * decl.c (grokdeclarator): Do not allow parameters with variably ! modified types. ! ! PR c++/9727 ! * decl2.c (push_scope): Don't pushclass for non-class types. ! (pop_scope): Don't popclass either. ! ! PR c++/8906 ! * decl.c (lookup_name_real): Use IMPLICIT_TYPENAME_P. ! * decl2.c (handle_class_head): Check it. ! ! PR c++/8724 ! * call.c (build_method_call): Make sure that the type destroyed in ! an explicit destructor call is complete. ! ! 2003-02-20 Mark Mitchell ! ! PR c++/9729 ! * mangle.c (mangle_conv_op_name_for_type): Issue an error message ! when the G++ 3.2 ABI prevents correct compilation. ! ! 2003-02-18 Mark Mitchell ! ! PR c++/9704 ! * class.c (layout_class_type): In the 3.2 ABI, take into account ! trailing bit fields when computing CLASSTYPE_SIZE_UNIT. ! ! 2003-02-18 Matt Austern ! ! * cp/cp-lang.c: Change lang hooks so that final_write_globals does ! nothing for C++. ! * cp/decl.c (wrapup_globals_for_namespace): Remove special ! handling of global namespace. ! ! 2003-02-18 Jason Merrill ! ! PR c++/9623 ! * decl.c (reshape_init): Don't mess with initializer labels. ! ! 2003-02-18 Kriang Lerdsuwanakij PR c++/9459 * error.c (dump_type_prefix): Handle TYPEOF_TYPE. (dump_type_suffix): Likewise. ! 2003-02-17 Michael Elizabeth Chastain ! PR debug/9717 ! * class.c (build_base_field): Mark fields for base classes with ! DECL_IGNORED_P. ! 2003-02-13 Andrew Pinski ! * decl.c: (define_label): Fix warning for return 0 instead of NULL. ! ! 2003-02-13 Gabriel Dos Reis ! * Make-lang.in (cp/decl2.o): Add dependency on timevar.h ! * decl2.c: Include "timevar.h". ! (namespace_ancestor): Time name lookup. ! (add_using_namespace): Likewise. ! (lookup_using_namespace): Likewise. ! (qualified_lookup_using_namespace): Likewise. ! (decl_namespace): Likewise. ! (lookup_arg_dependent): Likewise. ! * lex.c (do_identifier): Likewise. ! (do_scoped_id): Likewise. ! * pt.c (lookup_template_class): Likewise. ! ! 2003-02-12 Gabriel Dos Reis ! ! * decl.c (define_label): Don't forget to pop TV_NAME_LOOKUP. ! ! 2003-02-11 Gabriel Dos Reis ! ! * decl.c: Include "timevar.h". ! (poplevel): Time name lookup. ! (find_binding): Likewise. ! (push_namespace): Likewise. ! (pop_nested_namespace): Likewise. ! (store_bindings): Likewise. ! (maybe_push_to_top_level): Likewise. ! (pop_from_top_level): Likewise. ! (push_local_name): Likewise. ! (pushtag): Likewise. ! (pushdecl): Likewise. ! (pushdecl_with_scope): Likewise. ! (pushdecl_namespace_level): Likewise. ! (pushdecl_top_level): Likewise. ! (pushdecl_class_level): Likewise. ! (push_class_level_binding): Likewise. ! (push_using_decl): Likewise. ! (push_using_directive): Likewise. ! (push_overloaded_decl): Likewise. ! (lookup_label): Likewise. ! (define_label): Likewise. ! (lookup_tag): Likewise. ! (lookup_tag_reverse): Likewise. ! (lookup_namespace_name): Likewise. ! (select_decl): Likewise. ! (unqualified_namespace_lookup): Likewise. ! (lookup_name_real): Likewise. ! (lookup_name_current_level): Likewise. ! (lookup_type_current_level): Likewise. ! (maybe_inject_for_scope_var): Likewise. ! (xref_tag): Likewise. ! ! * Make-lang.in (cp/decl.o): Add dependency on timevar.h 2003-02-03 Mark Mitchell ! ! PR c++/7129 * operators.def: Add ?=. + + 2003-01-31 Kriang Lerdsuwanakij + + PR c++/8849 + * error.c (dump_expr): Handle BASELINK. + * pt.c (resolve_overloaded_unification): Handle FUNCTION_DECL. + + 2003-01-31 Kriang Lerdsuwanakij + + PR c++/9453 + * friend.c (is_friend): Always accept when SUPPLICANT is still + a TEMPLATE_DECL. + * pt.c (push_access_scope_real): Call push_to_top_level for + function in namespace scope. + (push_access_scope): Remove ARGS argument, all caller adjusted. + (pop_access_scope): Call pop_from_top_level for function in + namespace scope. + (regenerate_decl_from_template): Use push_access_scope_real. ! 2003-01-29 Nathan Sidwell ! ! PR c++/9437 ! * pt.c (unify): Don't unify '*T' with 'U C::*'. ! ! 2003-01-27 Jeffrey D. Oldham ! ! PR c++/47 ! * cp-tree.h (lookup_nested_field): Add declaration. ! * decl.c (lookup_name_real): Call lookup_nested_field. ! * search.c (lookup_nested_field): Add function. ! ! 2003-01-26 Christian Cornelssen * Make-lang.in (c++.install-common, c++.install-man) ! (c++.uninstall): Prepend $(DESTDIR) to destination paths in ! all (un)installation commands. (c++.install-common): Rewrite $(LN) commands to support DESTDIR with "ln" as well as with "ln -s". + 2003-01-24 Kaveh R. Ghazi + + * decl2.c (check_classfn): Fix uninitialized warning. + 2003-01-22 Mark Mitchell PR c++/9328 *************** *** 107,126 **** function; it doesn't make sense to try to print its type. * semantics.c (finish_typeof): Issue errors about invalid uses. ! 2003-01-21 Jeffrey D. Oldham ! PR c++/47 ! * cp-tree.h (lookup_nested_field): Add declaration. ! * decl.c (lookup_name_real): Call lookup_nested_field. ! * search.c (lookup_nested_field): Add function. 2002-12-26 Nathan Sidwell ! PR c++/8503 ! Remove DR 295 implementation. ! * pt.c (check_cv_quals_for_unify): Disable function & method cases. ! * tree.c (cp_build_qualified_type_real): Likewise. Don't warn ! about ignoring volatile qualifiers. 2002-12-18 Kriang Lerdsuwanakij --- 792,936 ---- function; it doesn't make sense to try to print its type. * semantics.c (finish_typeof): Issue errors about invalid uses. ! 2003-01-22 Josef Zlomek ! PR/9386, PR/8801 ! 2002-12-27 Mark Mitchell ! * typeck.c (build_class_member_access_expr): Fix anonymous union ! handling. ! ! 2003-01-17 Jason Merrill ! ! PR c++/9167, c++/9358 ! * decl.c (require_complete_types_for_parms): Also update DECL_ARG_TYPE. ! ! 2003-01-17 Jason Merrill ! ! PR c++/9342 ! * call.c (build_conditional_expr): Always do lvalue-rvalue ! conversion. ! ! 2003-01-16 Jason Merrill ! ! PR c++/8564 ! * init.c (build_vec_init): Re-add maxindex parm. ! (perform_member_init, build_aggr_init): Pass it. ! (build_new_1): Pass it. Use an incomplete array type for full_type. ! * typeck.c (build_modify_expr): Pass it. ! * cp-tree.h: Adjust. ! ! 2003-01-13 Jason Merrill ! ! PR c++/8748 ! * class.c (build_base_path): Take the address before calling save_expr. ! ! * call.c (build_user_type_conversion_1): Do set ICS_BAD_FLAG if ! all the ambiguous conversions are bad. ! ! * class.c (maybe_warn_about_overly_private_class): Don't stop ! searching when we find a nonprivate method. ! ! 2003-01-09 Jakub Jelinek ! ! * decl.c (start_decl): Only check DECL_THREAD_LOCAL for VAR_DECLs. ! ! 2003-01-09 Jakub Jelinek ! ! * decl.c (start_decl): Don't set DECL_COMMON for __thread variables. ! ! 2003-01-07 Kriang Lerdsuwanakij ! ! PR c++/9030 ! * decl.c (make_typename_type): Check access only when tf_error. ! (make_unbound_class_template): Likewise. ! * pt.c (saved_access_scope): New variable. ! (push_access_scope_real): New function. ! (push_access_scope): Likewise. ! (pop_access_scope): Likewise. ! (tsubst_default_argument): Use them. ! (instantiate_template): Likewise. ! (regenerate_decl_from_template): Likewise. ! (instantiate_decl): Likewise. ! (get_mostly_instantiated_function_type): Likewise. ! ! 2003-01-06 Mark Mitchell ! ! PR c++/9165 ! * decl2.c (build_cleanup): Mark the object as used. ! ! 2003-01-03 Nathan Sidwell ! ! PR c++/45, c++/3784 ! * tree.c (cp_tree_equal, TEMPLATE_PARM_INDEX): The types must be ! the same too. ! ! 2002-12-30 Nathan Sidwell ! ! PR c++/9054 ! * class.c (layout_class_type): Set DECL_CONTEXT of type for base. ! * dump.c (cp_dump_tree, RECORD_TYPE): Deal with type for base types. 2002-12-26 Nathan Sidwell ! PR c++/4803 ! * decl2.c (mark_used): Defer inline functions. ! (finish_file): Merge deferred_fns loops. Check all used ! inline functions have a definition. ! * method.c (make_thunk): Thunks are not inline. ! ! PR c++/5116, c++/764 ! * call.c (build_new_op): Make sure template class operands are ! instantiated. ! ! 2002-12-24 Nathan Sidwell ! ! PR C++/7964 ! * cp-tree.h (resolve_scoped_fn_name): Prototype. ! * call.c (resolve_scoped_fn_name): New function. Deal with ! more template expansion. Broken out of ... ! * parse.y (parse_finish_call_expr): ... here. Call it. ! * decl2.c (build_expr_from_tree, CALL_EXPR): Use ! resolve_scoped_fn_name and build_call_from_tree. ! ! PR c++/9053 ! * decl.c (duplicate_decls): Templates may be disambiguated by ! return type. ! ! PR c++/8702 ! * decl2.c (check_classfn): Use lookup_fnfield_1. List all ! conversion operators on failure. ! ! 2002-12-22 Nathan Sidwell ! ! PR c++/8572 ! * cp-tree.h (grokoptypename): Add SCOPE parameter. ! * decl2.c (grokoptypename): Add SCOPE parameter. tsubst the type ! if in a template scope. ! * parse.y (unoperator): Return the scope. ! (operator_name): Adjust grokoptypename call. ! ! 2002-12-22 Kriang Lerdsuwanakij ! ! * cp-tree.h (make_unbound_class_template): Use tsubst_flags_t. ! * decl.c (make_unbound_class_template): Adjust. Check for tf_error. ! * pt.c (tsubst) [OFFSET_TYPE]: Check for tf_error. ! ! 2002-12-18 Kriang Lerdsuwanakij ! ! PR c++/8099 ! * friend.c (make_friend_class): Allow partial specialization ! when declaration is not a template friend. ! ! 2002-12-18 Kriang Lerdsuwanakij ! ! PR c++/3663 ! * pt.c (lookup_template_class): Copy TREE_PRIVATE and ! TREE_PROTECTED to created decl nodes. ! ! 2002-12-18 Mark Mitchell ! ! * class.c (build_base_field): Do not set DECL_PACKED on the ! FIELD_DECL. 2002-12-18 Kriang Lerdsuwanakij *************** *** 134,179 **** * pt.c (convert_template_argument): Fix type or template template parameter decision logic. - 2002-12-13 Joe Buck - - * parse.y (class_head_defn): Set CLASSTYPE_DECLARED_CLASS for - anonymous structs. - 2002-12-13 Gabriel Dos Reis ! ! PR C++/8031 ! * cvt.c (convert_to_pointer_force): Don't try comparing against erronous type. 2002-12-10 Mark Mitchell PR c++/8372 * pt.c (tsubst_copy): Handle destructor names more correctly. 2002-12-05 Kaveh R. Ghazi * error.c (dump_expr): Fix format specifier warning. 2002-12-04 Gabriel Dos Reis PR C++/8799 * error.c (dump_expr): Don't ever try to dump a non-existent ! expression. 2002-12-02 Mark Mitchell PR c++/8615 * error.c (dump_expr): Handle character constants with TREE_OVERFLOW set. 2002-12-01 Mark Mitchell PR c++/5919 * pt.c (unify): Use variably_modified_type_p to test validity of template argument types. ! ! 2002-12-01 Mark Mitchell ! PR c++/8727 * cp-tree.h (lang_type_class): Add typeinfo_var. (CLASSTYPE_TYPEINFO_VAR): New macro. --- 944,1037 ---- * pt.c (convert_template_argument): Fix type or template template parameter decision logic. 2002-12-13 Gabriel Dos Reis ! ! PR C++/8031 ! * cvt.c (convert_to_pointer_force): Don't try comparing against erronous type. + 2002-12-13 Geoffrey Keating + + * cp-tree.h: Have the multiple-include guards around + the entire file. + 2002-12-10 Mark Mitchell PR c++/8372 * pt.c (tsubst_copy): Handle destructor names more correctly. + 2002-12-10 Matt Austern + + * cp-tree.h: get rid of needs_virtual_reinit bit. + + 2002-12-09 Mark Mitchell + + * NEWS: Document removal of in-class initialization extension for + static data members of non-arithmetic, non-enumeration type. + * decl.c (check_static_variable_definition): Do not allow that + extension. + * decl2.c (grokfield): Do not call digest_init when processing + templates. + 2002-12-05 Kaveh R. Ghazi * error.c (dump_expr): Fix format specifier warning. + 2002-12-04 Geoffrey Keating + + * class.c (finish_struct_1): Correct comment. + * cp-tree.c (DECL_SORTED_FIELDS): Likewise. + 2002-12-04 Gabriel Dos Reis PR C++/8799 * error.c (dump_expr): Don't ever try to dump a non-existent ! expression. ! ! 2002-12-03 Jason Merrill ! ! PR c++/8674 ! * call.c (build_over_call): Check specifically for TARGET_EXPR ! when eliding. ! ! PR c++/8461, c++/8625 ! * call.c (convert_for_arg_passing): Don't mess with error_mark_node. ! (cp_convert_parm_for_inlining): Remove. ! * cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING): ! Remove. ! * cp-tree.h (ADDR_IS_INVISIREF): Remove. ! * except.c (stabilize_throw_expr): Remove ADDR_IS_INVISIREF code. ! ! * call.c (build_user_type_conversion_1): Don't set ICS_BAD_FLAG on ! an ambiguous conversion. ! ! 2002-12-03 Mark Mitchell ! ! PR c++/8688 ! * decl.c (reshape_init): Handle erroneous initializers. 2002-12-02 Mark Mitchell + PR c++/8720 + * spew.c (remove_last_token): Make sure that last_chunk is set + correctly. + PR c++/8615 * error.c (dump_expr): Handle character constants with TREE_OVERFLOW set. + + 2002-12-02 Kriang Lerdsuwanakij + + DR 180 + * decl.c (grokdeclarator): Require class-key for all friend class. + Output the correct type and context in the error message. 2002-12-01 Mark Mitchell PR c++/5919 * pt.c (unify): Use variably_modified_type_p to test validity of template argument types. ! PR c++/8727 * cp-tree.h (lang_type_class): Add typeinfo_var. (CLASSTYPE_TYPEINFO_VAR): New macro. *************** *** 191,223 **** c_size_type_node. * decl2.c (coerce_new_type): Likewise. * except.c (do_allocate_exception): Likewise. - * typeck.c (c_sizeof): Likewise. - (c_sizeof_nowarn): Likewise. 2002-11-30 Mark Mitchell PR c++/8214 * typeck.c (convert_for_assignment): Do not use decl_constant_value on the operand. ! 2002-11-19 Release Manager ! * GCC 3.2.1 Released. ! 2002-11-11 Nathan Sidwell ! PR c++/7788 ! * rtti.c (unemitted_tinfo_decl_p): Check it has a field. ! 2002-11-02 Zack Weinberg PR c/7353 redux * decl2.c (grokfield): Reject TYPE_DECLs with initializers. ! 2002-11-01 Gabriel Dos Reis ! PR C++/2521 ! * typeck.c (build_x_unary_op): Handle pointer-to-member. 2002-10-30 Mark Mitchell --- 1049,1252 ---- c_size_type_node. * decl2.c (coerce_new_type): Likewise. * except.c (do_allocate_exception): Likewise. 2002-11-30 Mark Mitchell + PR c++/8227 + * decl.c (layout_var_decl): Deal gracefully with erroneous types. + (check_initializer): Validate the type of the initialized + variable, even if the initializer is absent. + * typeck.c (cp_type_quals): Deal gracefully with erroneous types. + PR c++/8214 * typeck.c (convert_for_assignment): Do not use decl_constant_value on the operand. ! PR c++/8511 ! * pt.c (instantiate_decl): Handle template friends defined outside ! of the class correctly. ! 2002-11-29 Joe Buck ! * parse.y (class_head_defn): Set CLASSTYPE_DECLARED_CLASS for ! anonymous structs. ! ! 2002-11-29 Mark Mitchell ! * class.c (walk_subobject_offsets): Recur on binfos as well as on ! types. ! (layout_nonempty_base_or_field): Pass it a binfo when processing a ! base class. ! (layout_empty_base): Likewise. ! (build_base_field): Likewise. ! ! 2002-11-27 Mark Mitchell ! * class.c (build_base_field): Make sure we get the canonical base ! when descending through primary bases. ! ! 2002-11-26 Geoffrey Keating ! ! * decl.c (check_initializer): Don't error on initialisation of ! a scalar with a brace-enclosed expression. ! ! 2002-11-26 Nathan Sidwell ! ! * cp-tree.h (DECL_LANG_FLAG_4): Document more uses. ! (template_parms_equal): Remove prototype. ! * typeck.c (buuld_indirect_ref): Reformat. ! ! 2002-11-25 Mark Mitchell ! ! * tree.c (cp_build_qualified_type_real): Correct handling of ! array types. ! * class.c (walk_subobject_offsets): Fix thinko. ! (build_base_field): Record offsets of empty bases in primary ! virtual bases. ! (layout_class_type): Record offsets of empty bases in fields. ! ! * search.c (is_subobject_of_p_1): Fix thinko. ! (lookup_field_queue_p): Likewise. ! ! 2002-11-24 Mark Mitchell ! ! * class.c (layout_class_type): Reuse tail padding when laying out ! virtual bases. ! ! 2002-11-22 Mark Mitchell ! ! * rtti.c (qualifier_flags): Fix thinko. ! ! 2002-11-21 Glen Nakamura ! ! PR c++/8342 ! * typeck.c (get_member_function_from_ptrfunc): Make sure that a ! SAVE_EXPR for instance_ptr doesn't get evaluated first inside one ! of the branches of a COND_EXPR. ! ! 2002-11-19 Mark Mitchell ! ! * pt.c (for_each_template_parm): Free allocated memory. ! * search.c (is_subobject_of_p_1): New function. ! (is_subobject_of_p): Avoid walking virtual bases multiple times. ! ! 2002-11-19 Jason Thorpe ! ! * g++spec.c (lang_specific_spec_functions): New. ! ! 2002-11-15 Kazu Hirata ! ! * ChangeLog: Follow spelling conventions. ! * class.c: Likewise. ! * decl2.c: Likewise. ! ! 2002-11-14 Zack Weinberg ! ! * search.c (dfs_push_decls): Do not try to reorder elements ! 3..n of method_vec if method_vec has only two elements. ! Reverse order of two tests to avoid accessing unallocated ! memory. ! ! 2002-11-14 Mark Mitchell ! ! * class.c (dfs_find_final_overrider): Adjust so that the most ! derived object is a binfo, rather than a class type. ! (find_final_overrider): Likewise. ! (add_vcall_offset_vtbl_entries_1): Simplify accordingly. ! (add_vcall_offset): Likewise. ! ! 2002-11-09 Kriang Lerdsuwanakij ! ! PR c++/8389 ! * pt.c (instantiate_template): Push class scope for member ! functions. ! (get_mostly_instantiated_function_type): Likewise. Don't call ! tsubst on context. Remove CONTEXTP and TPARMSP parameters. ! * cp-tree.h (get_mostly_instantiated_function_type): Adjust. ! * mangle.c (write_encoding, write_unqualified_name): Adjust. ! ! 2002-11-07 Mark Mitchell ! ! * class.c (add_vcall_offset_vtbl_entries_1): Correct ordering of ! vcall offfsets. Split out ... ! (add_vcall_offset): ... new function. ! ! PR c++/8338 ! * pt.c (for_each_template_parm): Add htab parameter. ! (process_partial_specialization): Adjust call. ! (push_template_decl_real): Likewise. ! (pair_fn_data): Add visited. ! (for_each_template_parm_r): Avoid walking duplicates more than ! once. ! (uses_template_parms): Adjust call to for_each_template_parm. ! ! 2002-11-07 Mark Mitchell ! ! * class.c (add_implicitly_declared_members): Put implicitly ! declared functions at the end of TYPE_METHODs when -fabi-version ! is at least 2. ! ! 2002-11-05 Geoffrey Keating ! ! * decl2.c (finish_file): Correct spelling. ! ! 2002-11-03 Mark Mitchell ! ! * call.c (build_special_member_call): Do not try to lookup VTTs by ! name. ! * class.c (vtbl_init_data): Add generate_vcall_entries. ! (get_vtable_decl): Do not look up virtual tables by name. ! (copy_virtuals): Do not use BV_USE_VCALL_INDEX_P. ! (set_primary_base): Do not set CLASSTYPE_RTTI. ! (determine_primary_base): Likewise. ! (get_matching_virtual): Remove. ! (get_vcall_index): New function. ! (update_vtable_entry_for_fn): Do not try to use virtual thunks ! when they are not required. Assign vcall indices at this point. ! (finish_struct_1): Do not set CLASSTYPE_NEEDS_VIRTUAL_REINIT. ! Do update dynamic_classes. ! (build_vtt): Do not add VTTs to the symbol table. ! (build_ctor_vtbl_group): Likewise. ! (build_vtbl_initializer): Simplify handling of vcall indices. ! (build_vcall_offset_vtbl_entries): Pretend to build vcall offsets ! for the most derived class. ! (add_vcall_offset_vtbl_entries_1): But do not actually add them to ! the vtable. ! * cp-tree.h (dynamic_classes): New macro. ! (lang_type_class): Remove rtti. Add vtables. Add vcall_indices. ! (CLASSTYPE_RTTI): Remove. ! (CLASSTYPE_NEEDS_VIRTUAL_REINIT): Remove. ! (CLASSTYPE_VCALL_INDICES): New macro. ! (CLASSTYPE_VTABLES): Likewise. ! (BV_USE_VCALL_INDEX_P): Remove. ! (build_vtable_path): Remove. ! * decl2.c (finish_vtable_vardecl): Remove. ! (key_method): Remove #if 0'd code. ! (finish_vtable_vardecl): Rename to ... ! (maybe_emit_vtables): ... this. ! (finish_file): Use it. ! * search.c (look_for_overrides_here): Update comment. ! ! 2002-11-01 Zack Weinberg PR c/7353 redux * decl2.c (grokfield): Reject TYPE_DECLs with initializers. ! 2002-10-30 Jason Merrill ! PR c++/8186 ! * cp-tree.h (ADDR_IS_INVISIREF): New macro. ! * call.c (convert_for_arg_passing): Set it. ! * except.c (stabilize_throw_expr): Recurse for such an arg. ! ! 2002-10-31 Mark Mitchell ! ! * cp-tree.h (lang_decl_flags): Remove init_priority. ! (lang_decl): Add delta. ! (GLOBAL_INIT_PRIORITY): Remove. ! (THUNK_DELTA): Revise definition. ! * decl2.c (start_objects): Don't set GLOBAL_INIT_PRIORITY. ! * dump.c (cp_dump_tree): Don't dump it. 2002-10-30 Mark Mitchell *************** *** 227,232 **** --- 1256,1280 ---- PR c++/8149 * decl.c (make_typename_type): Issue errors about invalid results. + 2002-10-30 Kriang Lerdsuwanakij + + Core issue 287, PR c++/7639 + * cp-tree.h (lang_type_class): Add decl_list field. + (CLASSTYPE_DECL_LIST): New macro. + (maybe_add_class_template_decl_list): Add declaration. + * class.c (duplicate_tag_error): Initialize CLASSTYPE_DECL_LIST. + (unreverse_member_declarations): Reverse CLASSTYPE_DECL_LIST. + (maybe_add_class_template_decl_list): New function. + (add_implicitly_declared_members): Use it. + * decl.c (maybe_process_template_type_declaration): Likewise. + (pushtag): Likewise. + * friend.c (add_friend): Likewise. + (make_friend_class): Likewise. + * semantics.c (finish_member_declaration): Likewise. + (begin_class_definition): Initialize CLASSTYPE_DECL_LIST. + * pt.c (instantiate_class_template): Use CLASSTYPE_DECL_LIST + to process members and friends in the order of declaration. + 2002-10-29 Mark Mitchell PR c++/8287 *************** *** 234,261 **** when returning from a destructor here. (finish_function_body): Rather than here. - * semantics.c (finish_alignof): Call complete_type before calling - c_alignof. - * decl2.c (build_expr_from_tree): Use - finish_sizeof/finish_alignof. - - 2002-10-10 Jim Wilson - - * decl.c (duplicate_decls): Don't call decl_attributes. - 2002-10-25 Zack Weinberg - PR middle-end/6994 - * cp-lang.c (cp_var_mod_type_p): New: C++ hook for - variably_modified_type_p. - * cp-tree.h: Remove prototype of variably_modified_type_p. - * tree.c (variably_modified_type_p): Remove; now implemented - in language-independent code. - PR c++/7266 * decl.c (grokdeclarator): Check that TREE_OPERAND 0 of a SCOPE_REF is not null before dereferencing it. 2002-10-24 David Edelsohn PR c++/7228 --- 1282,1326 ---- when returning from a destructor here. (finish_function_body): Rather than here. 2002-10-25 Zack Weinberg PR c++/7266 * decl.c (grokdeclarator): Check that TREE_OPERAND 0 of a SCOPE_REF is not null before dereferencing it. + 2002-10-25 Mark Mitchell + + * call.c (build_over_call): Use DECL_CONTEXT, not + DECL_VIRTUAL_CONTEXT. + * class.c (modify_vtable_entry): Don't mess with + DECL_VIRTUAL_CONTEXT. + (set_vindex): Remove. + (set_primary_base): Remove vfuns_p parameter. + (determine_primary_base): Likewise. + (modify_all_vtables): Likewise. + (layout_class_type): Likewise. Adjust calls to other functions + accordingly. + (finish_struct_1): Adjust calls to modified functions. Set + DECL_VINDEX here. + * cp-tree.h (lang_type_class): Remove vsize. + (CLASSTYPE_VSIZE): Remove. + (lang_decl): Remove thunks. + (DECL_THUNKS): Adjust. + (DECL_VIRTUAL_CONTEXT): Remove. + (duplicate_decls): Don't copy it. + * pt.c (build_template_decl): Don't set it. + (tsubst_decl): Likewise. + * typeck.c (expand_ptrmemfunc_cst): Don't use it. + + * class.c (build_vtbl_initializer): Don't use build_vtable_entry. + (build_vtable_entry): Remove. + * cp-tree.h (BINFO_VIRTUALS): Expand documentation. + (lang_decl): Add thunks. + (DECL_THUNKS): New macro. + * decl.c (duplicate_decls): Copy it. + * method.c (make_thunk): Simplify, and add thunks to DECL_THUNKS. + * semantics.c (emit_associated_thunks): Simplify. + 2002-10-24 David Edelsohn PR c++/7228 *************** *** 268,281 **** * typeck2.c (process_init_constructor): Remove redundant check for existence of lang_type structure. 2002-10-23 Mark Mitchell PR c++/8067 * decl.c (maybe_inject_for_scope_var): Ignore __FUNCTION__ and related variables. - 2002-10-23 Mark Mitchell - PR c++/7679 * spew.c (next_token): Do not return an endless stream of END_OF_SAVED_INPUT tokens. --- 1333,1351 ---- * typeck2.c (process_init_constructor): Remove redundant check for existence of lang_type structure. + 2002-10-24 Mark Mitchell + + * class.c (end_of_base): New method. + (end_of_class): Use it. Check indirect virtual bases. + + * class.c (check_field_decls): Fix typo. + 2002-10-23 Mark Mitchell PR c++/8067 * decl.c (maybe_inject_for_scope_var): Ignore __FUNCTION__ and related variables. PR c++/7679 * spew.c (next_token): Do not return an endless stream of END_OF_SAVED_INPUT tokens. *************** *** 283,306 **** the cached token stream. (snarf_defarg): Likewise. 2002-10-22 Mark Mitchell PR c++/6579 * spew.c (snarf_parenthesized_expression): New function. (snarf_block): Use it. ! 2002-10-21 Matthias Klose ! * Backport, without whitespace change: ! 2002-06-19 Akim Demaille ! * parse.y (TYPENAME): Rename as tTYPENAME to avoid the clash with ! decl.h's TYPENAME. ! * spew.c, lex.c: Adjust. ! * parse.y (explicit_instantiation): Add empty action to override ! the default $$ = $1 where it introduces a type clash. 2002-10-21 Mark Mitchell PR c++/8218 * cp-tree.h (lang_type_class): Add contains_empty_class_p. (CLASSTYPE_CONTAINS_EMPTY_CLASS_P): New macro. --- 1353,1391 ---- the cached token stream. (snarf_defarg): Likewise. + 2002-10-23 Zack Weinberg + + * cp-lang.c (cp_var_mod_type_p): New: C++ hook for + variably_modified_type_p. + * cp-tree.h: Remove prototype of variably_modified_type_p. + * tree.c (variably_modified_type_p): Remove; now implemented + in language-independent code. + 2002-10-22 Mark Mitchell PR c++/6579 * spew.c (snarf_parenthesized_expression): New function. (snarf_block): Use it. ! 2002-10-22 Richard Henderson ! * method.c (use_thunk): Always compute vcall_value; assert that ! it is not zero. Use can_output_mi_thunk; use output_mi_thunk ! for vcall thunks as well. 2002-10-21 Mark Mitchell + * class.c (empty_base_at_nonzero_offset_p): New function. + (layout_nonempty_base_or_field): Do not check for conflicts when + laying out a virtual base using the GCC 3.2 ABI. + (build_base_field): Correct checking for presence of empty classes + at nonzero offsets when clearing CLASSTYPE_NEARLY_EMPTY_P. + + * class.c (include_empty_classes): Use normalize_rli. + (layout_class_type): Likewise. + + * decl.c (reshape_init): Tweak handling of character arrays. + PR c++/8218 * cp-tree.h (lang_type_class): Add contains_empty_class_p. (CLASSTYPE_CONTAINS_EMPTY_CLASS_P): New macro. *************** *** 310,364 **** (finish_struct_1): Initialize it. (walk_subobject_offsets): Use it to prune searches. 2002-10-18 Zack Weinberg * decl.c (start_decl): Point users of the old initialized- typedef extension at __typeof__. ! 2002-10-18 Nathan Sidwell - PR c++/7676 * class.c (add_method): Compare template parms too. 2002-10-17 Mark Mitchell - * mangle.c (globals): Add entity and need_abi_warning. - (write_prefix): Likewise. - (write_template_prefix): Likewise. - (start_mangling): Add entity parameter. - (finish_mangling): Warn about names whose mangling will change. - (mangle_decl_string): Adjust. - (mangle_type_string): Likewise. - (mangle_special_for_type): Likewise. - (mangle_ctor_vtbl_for_type): Likewise. - (mangle_thunk): Likewise. - (mangle_guard_variable): Likewise. - (mangle_ref_init_variable): Likewise. - PR c++/7584 * class.c (handle_using_decl): Allow the declaration used to be from an ambiguous base. 2002-10-16 Mark Mitchell PR c++/7478 * cvt.c (convert_to_reference): Allow references as the incoming type. ! PR c++/8134 ! * tree.c (zero_init_p): Always return 1. PR c++/7524 * method.c (do_build_assign_ref): Use cp_build_qualified_type, not build_qualified_type. 2002-10-14 Mark Mitchell PR c++/7176 * lex.c (do_identifier): Add another option for the parsing parameter. * parse.y (do_id): Use it. 2002-10-11 Mark Mitchell PR c++/5661 --- 1395,1539 ---- (finish_struct_1): Initialize it. (walk_subobject_offsets): Use it to prune searches. + 2002-10-20 Mark Mitchell + + * method.c (use_thunk): Compute the vcall index as a HOST_WIDE_INT. + * optimize.c (optimize_function): Replace ASM_OUTPUT_MI_THUNK with + TARGET_ASM_OUTPUT_MI_THUNK in comments. + 2002-10-18 Zack Weinberg * decl.c (start_decl): Point users of the old initialized- typedef extension at __typeof__. ! 2002-10-18 Mark Mitchell ! ! * Make-lang.in (method.o): Depend on TARGET_H. ! * method.c (target.h): Include it. ! (use_thunk): Use target hooks. Use vcall thunks, if available. ! ! 2002-10-18 Mark Mitchell ! ! * class.c (base_derived_from): Make sure return value is a bool. ! ! 2002-10-18 Mark Mitchell ! ! * class.c (find_final_overrider_data_s): Remove overriding_fn and ! overriding_base. ! (dfs_base_derived_from): New function. ! (base_derived_from): Likewise. ! (dfs_find_final_overrider): Use base_derived_from. ! (find_final_overrider): Adjust. ! ! 2002-10-18 Jason Merrill ! ! PR c++/8080 ! * semantics.c (finish_for_cond, finish_while_cond): Don't mess ! with condition decls in a template. ! ! 2002-10-17 Nathan Sidwell * class.c (add_method): Compare template parms too. 2002-10-17 Mark Mitchell PR c++/7584 * class.c (handle_using_decl): Allow the declaration used to be from an ambiguous base. + * pt.c (convert_template_argument): Revert this change: + 2002-10-16 Mark Mitchell + * pt.c (convert_template_argument): Do not fold non-type + template rguments when inside a template. + + * init.c (expand_default_init): Handle brace-enclosed initializers + correctly. + 2002-10-16 Mark Mitchell + * mangle.c (write_expression): Correct handling of enumeration + constants. + (write_template_arg): Likewise. + * pt.c (convert_template_argument): Do not fold non-type template + arguments when inside a template. + PR c++/7478 * cvt.c (convert_to_reference): Allow references as the incoming type. ! 2002-10-16 Mark Mitchell PR c++/7524 * method.c (do_build_assign_ref): Use cp_build_qualified_type, not build_qualified_type. + 2002-10-15 Richard Henderson + + * error.c (dump_expr): Use real_to_decimal directly, and with + the new arguments. + + 2002-10-15 Mark Mitchell + + * decl.c (reshape_init): Fix typo. + + * cp-tree.h (operator_name_info_t): Add arity. + * lex.c (init_operators): Initialize it. + * mangle.c (write_conversion_operator_name): New function. + (write_unqualified_name): Use it. + (write_template_args): Accept template arguments as a TREE_LIST. + (write_expression): Adjust handling of qualified names to match + specification. + + 2002-10-15 Jason Merrill + + * call.c (call_builtin_trap): New fn. + (convert_arg_to_ellipsis): Use it. Downgrade error to warning. + (build_call): Don't set current_function_returns_abnormally outside + a function. + 2002-10-14 Mark Mitchell + * class.c (check_field_decls): Remove empty_p parameter. Instead, + clear CLASSTYPE_EMPTY_P. + (build_base_field): Likewise. + (build_base_fields): Likewise. + (check_bases_and_members): Likewise. + (create_vtbl_ptr): Likewise. + (layout_class_type): Likewise. Ensure that empty classes have + size zero when used as base classes in the 3.2 ABI. + (finish_struct_1): Initialize CLASSTYPE_EMPTY_P and + CLASSTYPE_NEARLY_EMPTY_P. Adjust calls to avoid passing empty_p + parameter. + (is_empty_class): Correct definition when using post-3.2 ABI. + * cp-tree.h (lang_type_class): Add empty_p. + (CLASSTYPE_EMPTY_P): New macro. + + 2002-10-12 Nathan Sidwell + + * init.c (build_delete): Do not apply save_expr for arrays. + (build_vec_delete): Likewise. + + 2002-10-14 Mark Mitchell + + * decl.c (layout_var_decl): Call layout_decl even for variables + whose type is an array with unspecified bounds. + PR c++/7176 * lex.c (do_identifier): Add another option for the parsing parameter. * parse.y (do_id): Use it. + 2002-10-11 Gabriel Dos Reis + + PRs C++/6803, C++/7721 and C++/7803 + * decl.c (grokdeclarator): Gracefully handle template-name as + decl-specifier. + + 2002-10-11 Jason Molenda + + * init.c (build_field_list): Provide uses_unions_p with a default + value. + 2002-10-11 Mark Mitchell PR c++/5661 *************** *** 369,384 **** types as template arguments. * tree.c (variably_modified_type_p): New function. ! 2002-10-11 Jason Molenda ! * init.c (build_field_list): Provide uses_unions_p with a default ! value. ! 2002-10-10 Gabriel Dos Reis ! PRs C++/6803, C++/7721 and C++/7803 ! * decl.c (grokdeclarator): Gracefully handle template-name as ! decl-specifier. 2002-10-09 Zack Weinberg --- 1544,1587 ---- types as template arguments. * tree.c (variably_modified_type_p): New function. ! * NEWS: Document removal of "new X = ..." extension. ! * class.c (initialize_array): Set TREE_HAS_CONSTRUCTOR on ! brace-enclosed initializers. ! * cp-tree.h (CP_AGGREGATE_TYPE_P): New macro. ! (initialize_local_var): Remove declaration. ! (expand_static_init): Likewise. ! * decl.c (next_initializable_field): New function. ! (reshape_init): Likewise. ! (check_initializer): Use them. Build dynamic initializer for ! aggregates here too. ! (initialize_local_var): Simplify, and incorporate cleanup ! insertion code as well. ! (destroy_local_var): Remove. ! (cp_finish_decl): Tidy. ! (expand_static_init): Fold checks for whether or not a variable ! needs initialization into this function. Simplify. ! * decl2.c (do_static_initialization): Simplify. ! * init.c (build_init): Do not set TREE_SIDE_EFFECTS when it will ! be done for us automatically. ! (expand_default_init): Handle brace-enclosed initializers ! correctly. ! (expand_aggr_init_1): Remove RTL-generation code. ! (build_vec_init): Remove "new X = ..." support. ! * parse.y (new_initializer): Likewise. ! * rtti.c (get_pseudo_ti_init): Set TREE_HAS_CONSTRUCTOR on ! brace-enclosed initializer. ! (create_pseudo_type_info): Likewise. ! * typeck2.c (store_init_value): Don't try to handle digest_init ! being called more than once. ! (digest_init): Tidy handling of brace-enclosed initializers. ! 2002-10-10 Kaveh R. Ghazi ! * decl.c (typename_hash): Use htab_hash_pointer. ! 2002-10-10 Jim Wilson ! ! * decl.c (duplicate_decls): Don't call decl_attributes. 2002-10-09 Zack Weinberg *************** *** 388,393 **** --- 1591,1600 ---- (cp_finish_decl): Remove special case for TYPE_DECL with initializer. (grokdeclarator): Remove redundant error for 'typedef foo = bar'. + 2002-10-09 Kaveh R. Ghazi + + * decl2.c (prune_vtable_vardecl): Delete unused function. + 2002-10-03 Mark Mitchell PR c++/7754 *************** *** 399,421 **** 2002-10-07 Richard Henderson ! * decl2.c: Complete reversion of c++/7754. ! ! 2002-10-06 Roger Sayle ! PR optimization/6627 ! * cp/cp-tree.h (enum ptrmemfunc_vbit_where_t): Delete definition ! from here, and move it to tree.h. ! * cp/decl.c (cxx_init_decl_processing): If storing the vbit ! in function pointers, ensure that force_align_functions_log ! is atleast one. ! 2002-10-04 H.J. Lu (hjl@gnu.org) ! * pt.c (tsubst_decl, case VAR_DECL): Back out the last change. ! (tsubst_expr, case DECL_STMT): Likewise. ! 2002-10-02 Mark Mitchell PR c++/7754 * decl2.c (finish_anon_union): Do not expand anonymous unions when --- 1606,1622 ---- 2002-10-07 Richard Henderson ! * decl2.c, pt.c: Revert c++/7754 fix. ! 2002-10-05 Kriang Lerdsuwanakij ! PR c++/7804 ! * error.c (dump_expr) [REAL_CST]: Output in decimal format. ! 2002-10-03 Mark Mitchell ! PR c++/7931 ! * pt.c (for_each_template_parm_r): Handle BASELINKs. PR c++/7754 * decl2.c (finish_anon_union): Do not expand anonymous unions when *************** *** 424,477 **** type. Call layout_decl. (tsubst_expr, case DECL_STMT): Handle anonymous unions. 2002-10-02 Mark Mitchell PR c++/7188. ! * init.c (expand_member_init): Allow a FIELD_DECL to be passed in ! directly. ! * pt.c (tsubst_initializer_list): Use expand_member_init. 2002-09-04 Jakub Jelinek * decl.c (start_cleanup_fn): Clear interface_only before start_function, restore it afterwards. ! 2002-09-01 Alexandre Oliva ! * parse.y (sizeof, alignof, typeof): New non-terminals to ! increment skip_evaluation. Replace terminals with them and ! decrement skip_evaluation at the end of rules using them. ! * decl2.c (mark_used): Don't assemble_external if ! skipping evaluation. ! 2002-08-31 Jason Merrill ! * cp-lang.c (cp_expr_size): Don't abort. 2002-08-27 Mark Mitchell - * cp-tree.h (warn_abi): Declare it. - * decl.c (warn_abi): Define it. - (cxx_decode_option): Set it. * class.c (layout_virtual_bases): Warn about bugs in G++ that result in incorrect object layouts. (layout_class_type): Likewise. 2002-08-22 Jason Merrill ! PR c++/5607 ! * search.c (check_final_overrider): No longer static. ! * class.c (update_vtable_entry_for_fn): Call it. ! * cp-tree.h: Adjust. ! * cp-lang.c (LANG_HOOKS_EXPR_SIZE): Define. ! (cp_expr_size): New fn. ! * call.c (convert_arg_to_ellipsis): Promote non-POD warning to error. ! * typeck.c (build_modify_expr): Don't use save_expr on an lvalue. ! 2002-08-14 Release Manager ! * GCC 3.2 Released. 2002-08-03 Nathan Sidwell --- 1625,2268 ---- type. Call layout_decl. (tsubst_expr, case DECL_STMT): Handle anonymous unions. + 2002-10-03 Mark Mitchell + + PR c++/8006 + * mangle.c (CLASSTYPE_TEMPLATE_ID_P): Handle instances of template + template parameters. + (globals): Add entity and need_abi_warning. + (decl_is_template_id): Use TYPE_TEMPLATE_INFO, not + CLASSTYPE_TEMPLATE_INFO. + (is_std_substitution): Use CLASSTYPE_TI_TEMPLATE, not + TYPE_TI_TEMPLATE. + (write_prefix): Handle typename types correctly. + (write_template_prefix): Handle template template parameters + correctly. + (start_mangling): Add entity parameter. + (finish_mangling): Warn about names whose mangling will change. + (mangle_decl_string): Adjust. + (mangle_type_string): Likewise. + (mangle_special_for_type): Likewise. + (mangle_ctor_vtbl_for_type): Likewise. + (mangle_thunk): Likewise. + (mangle_guard_variable): Likewise. + (mangle_ref_init_variable): Likewise. + 2002-10-02 Mark Mitchell PR c++/7188. ! * cp-tree.def (CTOR_INITIALIZER): Use one slot, not two. ! * cp-tree.h (emit_base_init): Rename to .... ! (emit_mem_initializers): ... this. ! (expand_member_init): Change prototype. ! * init.c (perform_member_init): Compute explicit, rather than ! requiring it as a parameter. ! (sort_member_init): Rename to ... ! (sort_mem_initializers): ... this. Process bases and data members ! together. ! (sort_base_init): Remove. ! (emit_base_init): Rename to ... ! (emit_mem_initializers): ... this. ! (expand_aggr_vbase_init_1): Remove. ! (construct_virtual_bases): Rename to ... ! (construct_virtual_base): ... this. ! (expand_member_init): Rework handling of base initializers. ! * method.c (do_build_copy_constructor): Use ! finish_mem_initializers. ! * parse.y (member_init): Adjust calls to expand_member_init. ! * pt.c (tsubst_expr): Simplify CTOR_INITIALIZER case. ! (tsubst_initializer_list): Use expand_member_init. ! * semantics.c (finish_mem_intiailizers): Simplify. ! ! 2002-10-02 Matt Austern ! * decl.c (walk_vtables_r): Fixed typo that caused result to ! never get a nonzero value. ! ! 2002-10-02 Roger Sayle ! ! PR optimization/6627 ! * cp-tree.h (enum ptrmemfunc_vbit_where_t): Delete definition ! from here, and move it to tree.h. ! * decl.c (cxx_init_decl_processing): If storing the vbit ! in function pointers, ensure that force_align_functions_log ! is atleast one. ! ! 2002-10-02 Matt Austern ! ! * class.c (check_field_decls): Changed warning about const member ! variables so that it doesn't get issued for a class aggregate. ! ! 2002-10-01 Mark Mitchell ! ! * decl.c (cp_finish_decl): Make sure array types are laid out, ! even if the array bounds are unknown. ! ! 2002-10-01 Steve Ellcey ! ! * class.c (build_vtbl_initializer): Change build_c_cast ! to build1. ! ! 2002-10-01 Mark Mitchell ! ! * decl.c (cp_finish_decl): Make sure array types are laid out, ! even if the array bounds are unknown. ! ! * decl.c (cp_finish_decl): Correct check for dynamic ! initialization of thread-local storage. ! ! 2002-09-30 Nathan Sidwell ! ! * tree.c (really_overloaded_fn): TEMPLATE_ID_EXPRs are also ! overloaded. ! ! 2002-09-30 Steve Ellcey ! ! * class.c (build_vtbl_initializer): Add cast. ! (add_vcall_offset_vtbl_entries_1): ! Use TARGET_VTABLE_DATA_ENTRY_DISTANCE for offset. ! ! 2002-09-30 Mark Mitchell ! ! * class.c (walk_subobject_offsets): Correct the calculation of ! offsets for virtual bases. Correct the counting of array ! elements. ! (layout_nonempty_base_or_field): Simplify. Correct the ! calculation of offsets to be propagated through the binfo ! hierarchy. ! (build_base_field): Avoid creating a FIELD_DECL for empty bases. ! Add the FIELD_DECL to TYPE_FIELDS. ! (build_base_fields): Adjust accordingly. ! (layout_virtual_bases): Use build_base_field. ! (end_of_class): Return a tree, not an integer. ! (warn_about_ambiguous_direct_bases): Rename to ... ! (warn_about_ambiguous_bases): ... this. ! (include_empty_classes): New function. ! (layout_class_type): Create an alternative version of the type to ! be used when as a base class type. Do not call ! finish_record_layout until we are done laying out the class. ! * cp-tree.h (lang_type_class): Remove size, size_unit. Add ! as_base. ! (CLASSTYPE_SIZE): Reimplement. ! (CLASSTYPE_SIZE_UNIT): Likewise. ! (CLASSTYPE_ALIGN): Likweise. ! (CLASSTYPE_USER_ALIGN): Likewise. ! (CLASSTYPE_AS_BASE): New macro. ! (DECL_INITIALIZED_P): Likewise. ! (extract_init): Remove prototype. ! (build_forced_zero_init): Rename to ... ! (build_zero_init): ... this. ! (force_store_init_value): Remove. ! * decl.c (obscure_complex_init): Remove. ! (duplicate_decls): Copy DECL_INITIALIZED_P. ! (check_initializer): Do not leave junk in DECL_INITIAL. ! (cp_finish_decl): Handle zero-initialization of entities with ! static storage duration. ! * expr.c (extract_init): Remove. ! * init.c (build_forced_zero_init): Remove. ! (build_zero_init): New function. ! (build_default_init): Use it. ! (build_field_list): Skip FIELD_DECLs for base subobjects. ! (push_base_cleanups): Likewise. ! * method.c (do_build_assign_ref): Likewise. ! (synthesize_exception_spec): Likewise. ! * pt.c (tsubst_decl): Clear DECL_INITIALIZED_P. ! (regenerate_decl_from_template): To not set DECL_INITIAL for a ! static data member whose initialization took place in its class. ! (instantiate_decl): Do not pass an initializer to cp_finish_decl ! in that situation. ! * search.c (dfs_push_decls): Skip FIELD_DECLs for base subobjects. ! (dfs_unuse_fields): Likewise. ! * tree.c (pod_type_p): Handle error_mark_node. ! (zero_init_p): Likewise. ! * typeck.c (lookup_anon_field): Skip FIELD_DECLs for base ! subobjects. ! * typeck2.c (store_init_value): Remove #if 0'd code. ! (force_store_init_value): Remove. ! (process_init_constructor): Use build_zero_init. ! ! 2002-09-29 Nathan Sidwell ! ! PR c++/7788 ! * rtti.c (unemitted_tinfo_decl_p): Check it has a field. ! ! 2002-09-29 Kazu Hirata ! ! * cp-tree.h: Fix comment typos. ! * decl.c: Likewise. ! * pt.c: Likewise. ! ! 2002-09-25 Mark Mitchell ! ! * cp/class.c (contains_empty_class_p): New method. ! (walk_subobject_offsets): Correct computation of field offset. ! (layout_empty_base): Correct placement of emtpy base classes. ! (layout_class_type): Warn about ABI changes. ! ! 2002-09-23 Mark Mitchell ! ! * cp/class.c (layout_virtual_bases): Do not round the size of the ! type to a multiple of the alignment before laying out virtual bases. ! (layout_class_type): Correct handling of bit-fields that are wider ! than their type inside unions. Round the size of the type to a ! even number of bytes when computing the size without virtual ! bases. ! * cp/cp-tree.h (abi_version_at_least): New macro. ! ! 2002-09-21 Kazu Hirata ! ! * ChangeLog: Follow spelling conventions. ! * ChangeLog.2: Likewise. ! * call.c: Likewise. ! * class.c: Likewise. ! * cp-tree.h: Likewise. ! * cvt.c: Likewise. ! * decl.c: Likewise. ! * decl2.c: Likewise. ! * except.c: Likewise. ! * friend.c: Likewise. ! * g++spec.c: Likewise. ! * init.c: Likewise. ! * lex.c: Likewise. ! * mangle.c: Likewise. ! * method.c: Likewise. ! * operators.def: Likewise. ! * optimize.c: Likewise. ! * pt.c: Likewise. ! * rtti.c: Likewise. ! * search.c: Likewise. ! * semantics.c: Likewise. ! * spew.c: Likewise. ! * tree.c: Likewise. ! * typeck.c: Likewise. ! ! 2002-09-18 Devang Patel ! ! * cp/cp-tree.h: New prototype for walk_vtabls(). ! * cp/decl.c (walk_vtables_r): New function. ! (struct cp_binding_level): Add new members, namespaces, ! names_size and vtables. ! (add_decl_to_level): Add decl in namespaces or vtables ! chain, if conditions match. ! (walk_vtables): New function. ! (walk_namespaces_r): Travers separate namespace chain ! for namespace decls. ! (wrapup_globals_for_namespace): Use names_size instead ! of list_length(). ! * cp/decl2.c (finish_file): Use walk_vtables() instead of ! walk_globals() to walk vtable decls. ! ! 2002-09-18 Nathan Sidwell ! ! * decl.c (grokdeclarator): Use assert, not internal_error. Don't ! ICE with invalid pointers & references. ! ! 2002-09-17 Zack Weinberg ! ! * Make-lang.in: Remove all references to the demangler. ! * cxxfilt.c: Moved to binutils. ! ! 2002-09-16 Nathan Sidwell ! ! PR c++/7718 ! * pt.c (tsubst_decl): Remove assert. ! ! Remove DR 295 implementation. ! * pt.c (check_cv_quals_for_unify): Disable function & method cases. ! * tree.c (cp_build_qualified_type_real): Likewise. Don't warn ! about ignoring volatile qualifiers. ! ! * search.c (lookup_member): Correct documentation. ! ! 2002-09-16 Geoffrey Keating ! ! * cp-tree.h (union lang_tree_node): Add chain_next option. ! ! 2002-09-16 Nathan Sidwell ! ! * parse.y (parse_finish_call_expr): Check lookup_member result. ! ! PR c++/7015 ! * semantic.c (finish_asm_stmt): Fix operand/output_operands ! thinko. ! * typeck.c (c_expand_asm_operands): Protect from error_mark_node. ! ! 2002-09-15 Nathan Sidwell ! ! PR c++/7919 ! * call.c (build_over_call): Convert this pointer for fns found by ! using decls. ! ! 2002-09-15 Kazu Hirata ! ! * ChangeLog: Follow spelling conventions. ! * ChangeLog.1: Likewise. ! ! 2002-09-14 Nathan Sidwell ! ! PR c++/7768 ! * pt.c (build_template_decl): Copy DECL_DESTRUCTOR_P. ! ! 2002-09-14 Kazu Hirata ! ! * error.c: Fix comment formatting. ! * except.c: Likewise. ! * expr.c: Likewise. ! * friend.c: Likewise. ! * g++spec.c: Likewise. ! * init.c: Likewise. ! * lex.c: Likewise. ! * mangle.c: Likewise. ! * method.c: Likewise. ! * optimize.c: Likewise. ! * pt.c: Likewise. ! * rtti.c: Likewise. ! * search.c: Likewise. ! * semantics.c: Likewise. ! * spew.c: Likewise. ! * tree.c: Likewise. ! * typeck.c: Likewise. ! * typeck2.c: Likewise. ! ! 2002-09-13 Matt Austern ! ! PR C++/7828 ! * cp/cp-tree.h, cp/tree.c: New function non_cast_lvalue_p. ! * cp/call.c: Change call-by-const-reference mechanism to use ! non_cast_lvalue_p when deciding whether the create a temporary. ! We need a temporary when passing, e.g. (long) x by const ref. ! ! 2002-09-13 Nathan Sidwell ! ! * pt.c (unify, ARRAY_TYPE): Element type can be more qualified. ! ! 2002-09-13 Kazu Hirata ! ! * decl.c: Fix comment formatting. ! * decl2.c: Likewise. ! ! 2002-09-12 Kazu Hirata ! ! * call.c: Fix comment formatting. ! * class.c: Likewise. ! * cp-lang.c: Likewise. ! * cp-tree.h: Likewise. ! * cvt.c: Likewise. ! ! 2002-09-11 Zack Weinberg ! ! * Make-lang.in: Build cp/cxxfilt.o from $(srcdir)/cp/cxxfilt.c, ! and c++filt from cxxfilt.o + version.o + $(LIBDEPS). ! * cxxfilt.c: New file: split from libiberty/cplus-dem.c, with ! minor adjustments (use version_string, eliminate yet another ! duplicate of xmalloc) ! ! 2002-09-08 Kaveh R. Ghazi ! ! * cp-tree.h (require_complete_eh_spec_types): Add prototype. ! ! 2002-09-05 Jason Merrill ! ! * typeck2.c (add_exception_specifier): Only pedwarn for an ! incomplete type. ! (require_complete_eh_spec_types): New fn. ! (cxx_incomplete_type_diagnostic): Also support pedwarning. ! * typeck.c (complete_type_or_diagnostic): Likewise. ! * call.c (build_call): Call require_complete_eh_spec_types. ! * rtti.c (get_pseudo_ti_desc): Give an error rather than aborting ! on an incomplete type. 2002-09-04 Jakub Jelinek * decl.c (start_cleanup_fn): Clear interface_only before start_function, restore it afterwards. ! 2002-08-31 Jason Merrill ! * cp-lang.c (cp_expr_size): Allow initialization from a ! CONSTRUCTOR. ! 2002-08-30 Richard Henderson ! PR opt/7515 ! * tree.c: Include target.h. ! (cp_cannot_inline_tree_fn): Don't auto-inline functions that ! don't bind locally. ! * Makefile.in (tree.o): Update. 2002-08-27 Mark Mitchell * class.c (layout_virtual_bases): Warn about bugs in G++ that result in incorrect object layouts. (layout_class_type): Likewise. + 2002-08-24 Matt Austern + + * tree.c (lvalue_p_1): Add argument for whether casts of lvalues + are allowable. + (real_lvalue_p): Update caller. + (lvalue_p): Ditto. + (non_cast_lvalue_or_else): New. + * tree.h: Declare it. + * typeck.c (build_unary_op): Use non_cast_lvalue_or_else. + + 2002-08-22 Mark Mitchell + + * typeck.c (build_class_member_access_expr): Handle COMPOUND_EXPR + and COND_EXPR specially; fix error message output. + 2002-08-22 Jason Merrill ! * pt.c (tsubst_expr): RETURN_EXPR is now RETURN_STMT_EXPR. ! * semantics.c (nullify_returns_r): Likewise. ! 2002-08-17 Gabriel Dos Reis ! Fix PR/7621 ! * typeck.c (finish_class_member_access_expr): Diagnose cases where ! name lookup finds nothing. ! 2002-08-15 Jason Merrill ! ! * semantics.c (finish_then_clause): Remove redundant assignment. ! (finish_if_stmt, begin_switch_stmt, finish_switch_stmt): Move the ! extra binding level outside the if/switch statement. ! (finish_while_cond, finish_for_cond): Rewrite complex condition ! into the loop body. ! ! 2002-08-15 Alexandre Oliva ! ! * parse.y (sizeof, alignof, typeof): New non-terminals to ! increment skip_evaluation. Replace terminals with them and ! decrement skip_evaluation at the end of rules using them. ! * decl2.c (mark_used): Don't assemble_external if ! skipping evaluation. ! ! 2002-08-15 Gabriel Dos Reis ! ! Fix PR/7504 ! * parse.y (parse_finish_call_expr): Handle incomplete ! type used to name a scope. ! ! 2002-08-15 Nathan Sidwell ! ! PR c++/7598 ! * typeck.c (build_unary_op): Fold offsetof idiom. Fixes ! regression caused by my 2002-08-08 patch. ! ! 2002-08-13 Mark Mitchell ! ! * decl.c (pushdecl_class_level): Honor requests to bind names to ! OVERLOADs. ! ! 2002-08-11 Kaveh R. Ghazi ! ! * decl2.c (build_call_from_tree): Fix uninitialized variable. ! * parse.y (parse_finish_call_expr): Likewise. ! * repo.c (old_args, old_dir, old_main): Const-ify. ! ! 2002-08-11 Gabriel Dos Reis ! ! * decl.c (duplicate_decls): Replace DECL_SOURCE_FILE + ! DECL_SOURCE_LINE with DECL_SOURCE_LOCATION. ! * optimize.c (maybe_clone_body): Likewise. ! * pt.c (tsubst_enum): Likewise. ! (lookup_template_class): Likewise. ! * tree.c (cp_copy_res_decl_for_inlining): Likewise. ! ! 2002-08-10 Neil Booth ! ! * lang-specs.h: Remove -ansi. ! ! 2002-08-10 Nathan Sidwell ! ! * tree.c (maybe_dummy_object): Replace // with /* */ ! ! 2002-08-09 Mark Mitchell ! ! * call.c (standard_conversion): Use build_ptrmem_type. ! * cp-tree.h (build_ptrmem_type): New function. ! (adjust_result_of_qualified_name_lookup): Likewise. ! * decl.c (grokvardecl): Do not look for OFFSET_TYPEs to indicate ! static data members. ! (build_ptrmem_type): New function. ! (grokdeclarator): Do not use build_offset_type when encountering a ! qualified name. ! * parse.y (parse_finish_call_expr): Use ! adjust_result_of_qualified_name_lookup. ! * search.c (adjust_result_of_qualified_name_lookup): New function. ! * typeck.c (qualify_type_recursive): Use TYPE_PTRMEM_* rather than ! accessing OFFSET_TYPEs directly. ! ! 2002-08-08 Mike Stump ! ! * call.c (add_builtin_candidate): legal -> valid, illegal -> invalid. ! (type_decays_to): Likewise. ! * class.c (find_final_overrider): Likewise. ! (maybe_note_name_used_in_class): Likewise. ! * decl.c (current_tmpl_spec_kind): Likewise. ! (add_binding): Likewise. ! (push_class_binding): Likewise. ! (duplicate_decls): Likewise. ! (layout_var_decl): Likewise. ! (grokfndecl): Likewise. ! (grokdeclarator): Likewise. ! (check_default_argument): Likewise. ! * decl2.c (handle_class_head): Likewise. ! * error.c (dump_template_decl): Likewise. ! * init.c (build_offset_ref): Likewise. ! * pt.c (check_specialization_scope): Likewise. ! (determine_specialization): Likewise. ! (check_explicit_specialization): Likewise. ! (maybe_check_template_type): Likewise. ! (process_partial_specialization): Likewise. ! (check_default_tmpl_args): Likewise. ! (push_template_decl_real): Likewise. ! (convert_template_argument): Likewise. ! (try_class_unification): Likewise. ! (get_bindings_real): Likewise. ! (do_decl_instantiation): Likewise. ! * semantics.c (begin_function_definition): Likewise. ! (finish_member_declaration): Likewise. ! (check_multiple_declarators): Likewise. ! * typeck.c (comp_array_types): Likewise. ! (comptypes): Likewise. ! (expr_sizeof): Likewise. ! (build_binary_op): Likewise. ! (dubious_conversion_warnings): Likewise. ! (check_return_expr): Likewise. ! ! 2002-08-08 Mark Mitchell ! ! * typeck.c (build_class_member_access_expr): Do not return ! error_mark_node when no error has occurred. ! ! 2002-08-08 Nathan Sidwell ! ! * typeck.c (build_component_addr): Remove. ! (build_unary_op): Just check it's not a bitfield, and then build ! an ADDR_EXPR. ! ! 2002-08-08 Nathan Sidwell ! ! * class.c (convert_to_base): Correct check for error_mark_node. ! (create_vtable_ptr): Remove unused VFUNS_P parm. ! ! 2002-08-08 Nathan Sidwell ! ! * cp/Make-lang.in (c++.mostlyclean): Remove coverage files. ! ! 2002-08-07 Mark Mitchell ! ! Rework build_component_ref. ! * call.c (build_vfield_ref): Do not go through build_component_ref. ! (build_field_call): Use build_class_member_access_expr. ! (build_user_type_conversion_1): Use BASELINK_FUNCTIONS. ! (build_object_call): Likewise. ! * class.c (convert_to_base): New function. ! (type_requires_array_cookie): Use BASELINK_FUNCTIONS. ! (instantiate_type): Handle BASELINKs. ! * cp-tree.def (BASELINK): New tree code. ! * cp-tree.h (BASELINK_P): Reimplement. ! (SET_BASELINK_P): Remove. ! (BASELINK_BINFO): Reimplement. ! (BASELINK_FUNCTIONS): Likewise. ! (BASELINK_ACCESS_BINFO): Likewise. ! (BASELINK_OPTYPE): Likewise. ! (convert_to_base): New function. ! (name_p): Likewise. ! (build_object_ref): Remove. ! (build_component_ref_1): Likewise. ! (build_component_ref): Likewise. ! (build_x_component_ref): Likewise. ! (build_class_member_access_expr): New function. ! (finish_class_member_access_expr): Likewise. ! (build_ptrmemfunc_access_expr): Likewise. ! * decl.c (grokdeclarator): Handle BASELINKs. ! * decl2. (build_expr_from_tree): Handle COMPONENT_REFs by using ! finish_class_member_access_expr. ! (arg_assoc): Handle BASELINKs. ! (do_class_using_decl): Likewise. ! * error.c (dump_decl): Likewise. ! (dump_expr): Use build_ptrmemfunc_access_expr. ! * except.c (dtor_nothrow): Use CLASSTYPE_DESTRUCTORS to find ! destructors. ! (build_throw): Use BASELINK_FUNCTIONS. ! * init.c (perform_member_init): Use ! build_class_member_access_expr. ! (build_offset_ref): Handle BASELINKs. Use ! build_class_member_access_expr. ! * method.c (hack_identifier): Likewise. ! * parse.y (do_id): Use BASELINK, not TREE_LIST. ! (primary): Remove uses of build_object_ref. ! * pt.c (lookup_template_function): Handle BASELINKs. ! (resolve_overloaded_unification): Likewise. ! * search.c (build_baselink): Build a BASELINK, not a TREE_LIST. ! (lookup_field): Use BASELINK, not TREE_LIST. ! (lookup_fnfiels): Likewise. ! (setup_class_bindings): Likewise. ! * semantics.c (finish_object_call_expr): Do not use ! build_method_call when we already know what function is being ! called. ! * spew.c (identifier_type): Use BASELINK, not TREE_LIST. ! * tree.c (really_overloaded_fn): Use OVL_CHAIN for OVERLOADs, not ! TREE_CHAIN. ! (name_p): New function. ! * typeck.c (build_object_ref): Remove. ! (build_component_ref_1): Likewise. ! (build_x_component_ref): Likewise. ! (build_class_member_access_expr): New function. ! (finish_class_member_access_expr): Likewise. ! (build_ptrmemfunc_access_expr): Likewise. ! (get_member_function_from_ptrfunc): Use ! build_ptrmemfunc_access_expr. ! (build_binary_op): Likewise. ! (build_unary_op): Likewise. ! (build_ptrmemfunc): Likewise. ! (pfn_from_ptrmemfunc): Likewise. ! * typeck2.c (build_m_component_ref): Adjust comment. ! ! 2002-08-07 Neil Booth ! ! * Make-lang.in (CXX_C_OBJS): Update. ! * cp-lang.c (LANG_HOOKS_DECODE_OPTION): Use c_common_decode_option. ! * cp-tree.h (cxx_decode_option): Remove. ! * decl2.c (compare_options, lang_f_options, unsupported_options, ! cxx_decode_option): Remove. ! ! 2002-08-06 Gabriel Dos Reis ! ! * typeck.c (build_x_unary_op): Handle pointer-to-member. ! ! 2002-08-05 Geoffrey Keating ! ! * class.c: Don't include obstack.h. ! (popclass): ! * decl2.c: Delete bogus comment. ! * error.c: Don't include obstack.h. ! * except.c: Likewise. ! (dump_type): Correct comment. ! * method.c: Don't include obstack.h. ! * tree.c: Likewise. ! ! 2002-08-04 Gabriel Dos Reis ! ! Fix PR/2213 ! * cvt.c (cp_convert_to_pointer): Reject conversions from integral ! expressions to pointer-to-data-member of pointer-to-member-functions. ! ! 2002-08-04 Geoffrey Keating ! ! * cvt.c (ocp_convert): Delete obsolete code. ! * parse.y (permanent_obstack): Delete declaration. ! * pt.c (permanent_obstack): Delete declaration. ! * repo.c (permanent_obstack): Delete declaration. ! (open_repo_file): Use xmalloc instead of permanent_obstack. ! (init_repo): Use xstrdup instead of permanent_obstack. ! ! 2002-08-04 Nathan Sidwell ! ! * cp-tree.h (VF_DERIVED_VALUE): Remove. ! * class.c (finish_struct_1): Use VF_BINFO_VALUE not VF_DERIVED_VALUE. 2002-08-03 Nathan Sidwell *************** *** 486,567 **** (layout_class_type): Take single list of virtuals. Adjust. (finish_struct_1): Keep virtuals on single list. Adjust. 2002-07-30 Franz Sirl * lang-specs.h: Remove __GXX_ABI_VERSION, moved to gcc.c. ! 2002-07-17 Scott Snyder ! PR c++/7320 ! * rtti.c (get_tinfo_decl): Set DECL_COMDAT. ! 2002-07-05 Nathan Sidwell ! Repair damage on weak-impared targets caused by my previous patch. ! * cp-tree.h (import_export_tinfo): Add parameter. ! * decl2.c (import_export_tinfo): Add parameter, post adjust ! DECL_COMDAT. ! * rtti.c (emit_tinfo_decl): DECL_COMDAT is (nearly) always setup by ! import_export_tinfo. ! 2002-06-30 Nathan Sidwell ! * cp-tree.h (CPTI_TINFO_DECL_TYPE): Replace with ... ! (CPTI_TYPE_INFO_PTR_TYPE): ... this. ! (tinfo_decl_type): Replace with ... ! (type_info_ptr_type): ... this. ! (import_export_tinfo): Declare. ! (tinfo_decl_p): Rename to ... ! (unemitted_tinfo_decl_p): ... this. ! * decl2.c (import_export_decl): Break out tinfo handling into ... ! (import_export_tinfo): ... here. New function. ! (finish_file): Adjust. ! * rtti.c (TINFO_REAL_NAME): New macro. ! (init_rtti_processing): Create the tinfo types. ! (get_tinfo_decl_dynamic): Use type_info_ptr_type, get_tinfo_ptr. ! (get_tinfo_decl): Adjust. ! (get_tinfo_ptr): New function. ! (get_type_id): Use it. ! (tinfo_base_init): Create vtable decl here, if it doesn't exist. ! (ptr_initializer): Use get_tinfo_ptr. ! (ptm_initializer): Likewise. ! (synthesize_tinfo_var): Break into ... ! (get_pseudo_ti_init): ... this. Just create the initializer. ! (get_pseudo_ti_desc): .. and this. ! (create_real_tinfo_var): Remove. ! (create_pseudo_type_info): Don't create the vtable decl here. ! (get_vmi_pseudo_type_info): Remove. ! (create_tinfo_types): Adjust. ! (tinfo_decl_p): Rename to ... ! (unemitted_tinfo_decl_p): ... here. Adjust. ! (emit_tinfo_decl): Adjust. Create the initializer. ! 2002-06-14 Jason Merrill ! C++ ABI changes. ! * class.c (build_base_field): Set DECL_PACKED. ! (layout_class_type): Don't use tail padding of PODs. ! * mangle.c (write_unqualified_name): Fix template conversion op ! mangling. ! 2002-05-18 Jason Merrill ! PR c++/6611 ! * decl2.c (import_export_decl): If we clear ! DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set. ! 2002-05-14 Jason Merrill ! * rtti.c (get_tinfo_decl): Don't call comdat_linkage. ! Do set DECL_COMDAT. ! (synthesize_tinfo_var): Take the public decl. ! (create_real_tinfo_var): Likewise. Check DECL_COMDAT. ! (emit_tinfo_decl): Adjust. Call import_export_decl. ! * decl2.c (import_export_decl): Simplify tinfo decl handling. ! 2002-07-25 Release Manager ! * GCC 3.1.1 Released. 2002-07-12 Mark Mitchell --- 2277,2560 ---- (layout_class_type): Take single list of virtuals. Adjust. (finish_struct_1): Keep virtuals on single list. Adjust. + 2002-08-02 Mark Mitchell + + * init.c (build_member_call): Use build_new_method_call, not + build_method_call. + + 2002-08-02 Krister Walfridsson + + * Make-lang.in (spew.o, lex.o, pt.o): Add path to parse.h dependencies. + + 2002-08-02 Mark Mitchell + + * call.c (build_method_call): Issue a more helpful error message + about ambiguous method names. + + 2002-08-02 Nathan Sidwell + + * tree.c (build_shared_int_cst): Make cache file scope, and + GTY it. + + 2002-08-02 Jason Merrill + + * cp-lang.c (LANG_HOOKS_EXPR_SIZE): Define. + (cp_expr_size): New fn. + * call.c (build_over_call): Lose empty class hackery. + (convert_arg_to_ellipsis): Promote non-POD warning to error. + * typeck.c (build_modify_expr): Don't use save_expr on an lvalue. + + * semantics.c (expand_body): Do tree optimization in the function + context, too. + + 2002-08-01 Neil Booth + + * cp-tree.h: Move all warning and flag declarations to c-common.h. + * decl.c: Move all warning and flag variables to c-common.c. + * decl2.c: Move all warning and flag variables to c-common.c. + * lex.c (flag_digraphs): Remove. + (warn_traditional): Now in c-common.c. + + 2002-07-31 Mark Mitchell + + * call.c (build_field_call): Do not look up the field by name. + (build_method_call): Simplify. + (struct z_candidate): Add access_path and conversion_path. Remove + basetype_path. + (convert_class_to_reference): Adjust use of + add_function_candidate. + (add_candidate): Add conversion_path argument. + (add_function_candidate): Use it. + (add_conv_dndidate): Likewise. + (build_builtin_candidate): Likewise. + (add_template_candidate_real): Add conversion_path argument. + (add_template_conv_candidate): Likewise. + (add_template_candidate): Likewise. + (build_user_type_conversion_1): Use it. + (build_new_function_call): Remove name lookup code. Adjust use of + add_template_candidate and add_function_candidate. + (build_new_op): Likewise. + (convert_like_real): Use build_special_member_call. + (build_over_call): Use cand->conversion_path. + (build_special_member_call): New method. + (build_new_method_call): Remove name lookup code. + * cp-tree.def (OFFSET_REF): Update documentation. + (TEMPLATE_ID_EXPR): Likewise. + * cp-tree.h (BASELINK_ACCESS_BINFO): New macro. + (BASELINK_OPTYPE): Likewise. + (build_new_method_call): Adjust prototype. + (build_special_member_call): New method. + (build_baselink): New method. + (build_offset_ref_call_from_tree): Likewise. + (build_call_from_tree): Likewise. + (finish_qualified_call_expr): Remove. + (finish_call_expr): Adjust prototype. + (build_x_function_call): Remove. + * cvt.c (ocp_convert): Use build_special_member_call. + * decl2.c (reparse_absdcl_as_expr): Use finish_call_expr. + (build_expr_from_tree): Adjust handling for TEMPLATE_ID_EXPR and + CALL_EXPR. + (build_offset_ref_call_from_tree): New function. + (build_call_from_tree): Likewise. + * init.c (expand_cleanup): Use build_special_member_call. + (expand_default_init): Likewise. + (build_member_call): Use finish_call_expr. + (build_new_1): Use build_special_member_call. + (push_base_cleanups): Likewise. + * method.c (do_build_assign_ref): Likewise. + * parse.y (template_id): Do not pass a COMPONENT_REF to + lookup_template_function. + (primary): Use parse_finish_call_epxr, not finish_call_expr. + (parse_finish_call_expr): New function. + * pt.c (lookup_template_function): Add assertions. + * search.c (lookup_base): Allow T to be a binfo. + (build_baselink): New function. + (lookup_member): Use it. + * semantics.c (finish_call_expr): Do not do name lookup. + (finish_object_call_expr): Remove #if 0'd code. + (finish_qualified_call_expr): Remove. + * typeck.c (build_x_function_call): Remove. + (build_static_case): Use build_special_member_call. + * typeck2.c (build_functional_cast): Likewise. + 2002-07-30 Franz Sirl * lang-specs.h: Remove __GXX_ABI_VERSION, moved to gcc.c. ! 2002-07-30 Gabriel Dos Reis ! * cp-tree.h (VF_DERIVED_VALUE): Restore from previous deletion. ! 2002-07-30 Nathan Sidwell ! * cp-tree.h (CLASSTYPE_VFIELDS, VF_*, BV_*): Add more ! documentation. ! 2002-07-29 Alan Modra ! * cp-tree.h: Comment typo fix. ! 2002-07-29 Richard Earnshaw ! * spew.c (space_for_token): Allocate zeroed memory for a new token ! chunk. ! 2002-07-27 Roger Sayle ! * decl.c (builtin_function_1): No need to explicitly mark ! BUILT_IN_RETURN and BUILT_IN_EH_RETURN as noreturn. ! 2002-07-27 Roger Sayle ! * decl2.c (cxx_decode_option): Support -fno-builtin-foo. ! 2002-07-26 Jason Merrill ! * call.c (build_over_call): Likewise. ! (cp_convert_parm_for_inlining): New fn. ! (convert_for_arg_passing): New fn. ! (convert_default_arg, build_over_call): Use it. ! (type_passed_as): New fn. ! * pt.c (tsubst_decl): Use it. ! * decl2.c (cp_build_parm_decl): New fn. ! (build_artificial_parm): Use it. ! (start_static_storage_duration_function): Likewise. ! * decl.c (start_cleanup_fn, grokdeclarater): Likewise. ! (grokparms): Don't mess with DECL_ARG_TYPE. ! * typeck.c (convert_arguments): Use convert_for_arg_passing. ! * cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING): ! Define. ! * cp-tree.h: Declare new fns. ! ! 2002-07-26 Neil Booth ! ! * cp-tree.h (flag_operator_names): Remove. ! * decl2.c (flag_operator_names): Remove. ! (lang_f_options): Remove operator-names. ! * lex.c (D_OPNAME): Remove. ! (reswords): Remove operator names. ! (rid_to_yy): Remove operator names. ! (init_reswords): No need to handle D_OPNAME. ! * spew.c (read_process_identifier): There are no operator ! names. ! ! 2002-07-26 Jason Merrill ! ! * dump.c (cp_dump_tree): Call c_dump_tree. ! * Make-lang.in (CXX_C_OBJS): Add c-dump.o. ! ! 2002-07-25 Neil Booth ! ! * error.c (print_whitespace): Remove. ! * g++spec.c (LIBUNWIND): Move. ! * mangle.c (mangled_position, write_signed_number): Remove. ! ! 2002-07-25 Neil Booth ! ! * decl2.c (cxx_decode_option): Similarly. ! ! 2002-07-25 Gabriel Dos Reis ! ! * cp-tree.h (cxx_sizeof_nowarn): Now a macro. ! (cxx_sizeof_or_alignof_type): Take a third argument. ! (cxx_sizeof): Adjust definition. ! (cxx_alignof): Likewise. ! * init.c (build_delete): Use cxx_sizeof_nowarn to reflect reality. ! * typeck.c (cxx_sizeof_or_alignof_type): Take a third argument for ! complaining. ! (c_sizeof_nowarn): Remove definition. ! (build_unary_op): Use cxx_sizeof_nowarn. ! ! 2002-07-24 Geoffrey Keating ! ! * tree.c (cp_build_qualified_type_real): When copying ! pointer-to-method types, unshare the record that holds ! the cached pointer-to-member-function type. ! ! 2002-07-23 Neil Booth ! ! * cp-tree.h (FILE_FUNCTION_PREFIX_LEN): Remove. ! ! 2002-07-23 Gabriel Dos Reis ! ! Fix PR/7363: ! * typeck.c (cxx_sizeof_or_alignof_type): New function. ! (c_sizeof): Remove definition. ! (expr_sizeof): Use cxx_sizeof. ! * decl2.c (build_expr_from_tree): Use cxx_sizeof_or_alignof_type. ! * decl.c (finish_destructor_body): Use cxx_sizeof. ! * semantics.c (finish_alignof): Likewise. ! (finish_alignof): Use cxx_alignof. ! * cp-tree.h (cxx_sizeof, cxx_alignof): New macros. ! (cxx_sizeof_or_alignof_type): Declare. ! (my_friendly_assert): Move to ../c-common.h. ! ! 2002-07-23 Neil Booth ! ! * class.c, method.c, pt.c, search.c: Don't define obstack macros. ! ! 2002-07-22 Kriang Lerdsuwanakij ! ! PR c++/7347, c++/7348 ! * cp-tree.h (tsubst_flags_t): Add tf_parsing. ! * decl.c (make_typename_type): Use it. ! (make_unbound_class_template): Likewise. ! (lookup_name_real): Don't call type_access_control if scope is ! template parameter dependent. ! * parse.y (template_arg): Call make_unbound_class_template with ! tf_parsing set. ! (nest_name_specifier): Call make_typename_type with tf_parsing set. ! (typename_sub0): Likewise. ! (typename_sub1): Likewise. ! (instantiate_decl): Push class scope. ! * pt.c (regenerate_decl_from_template): Call pushclass and popclass ! for both static variable and member function template. ! (instantiate_decl) Call pushclass and popclass when tsubst'ing type ! and arguments. ! * search.c (type_access_control): Do type access for TEMPLATE_DECL ! too. ! ! 2002-07-20 Roger Sayle ! ! * decl2.c (cxx_decode_option): Simplify -fhandle-exceptions ! test by using positive_option. Make whitespace consistent. ! ! 2002-07-20 Gabriel Dos Reis ! ! * spew.c (struct unparsed_test): Replace 'filename' and 'lineno' ! members with 'locus'. Adjust use throughout. ! (struct feed): Likewise. ! (alloc_unparsed_test): Change prototype, take a 'const location_t *'. ! Adjust use. ! (snarf_defarg): Use error(), not error_with_file_and_line(). ! ! 2002-07-19 Chris Demetriou ! ! * lang-specs.h (@c++): Include "%2" (cc1plus_spec) wherever ! cpp_options is included. ! ! 2002-07-17 Kriang Lerdsuwanakij ! ! PR c++/2862, c++/2863 ! * pt.c (determine_specialization): Compare the length of ! TYPE_ARG_TYPES. Tidy. ! ! 2002-07-17 Kriang Lerdsuwanakij ! ! PR c++/3797 ! * decl.c (duplicate_decls): Don't propagate inlining parameters from ! olddecl to newdecl when newdecl is a specialization of the ! instantiation olddecl. ! ! 2002-07-17 Kriang Lerdsuwanakij ! ! PR c++/4802, c++/5387 ! * decl.c (make_typename_type): Use enforce_access. ! ! 2002-07-17 Scott Snyder ! ! PR c++/7320 ! * rtti.c (get_tinfo_decl): Set DECL_COMDAT. 2002-07-12 Mark Mitchell *************** *** 578,598 **** * tree.c (cp_copy_res_decl_for_inlining): Also copy TREE_ADDRESSABLE. 2002-07-10 Jason Merrill PR c++/6255 * decl.c (lookup_name_real): Build a new TYPENAME_TYPE rather than modifying the old one. 2002-07-08 Kriang Lerdsuwanakij * pt.c (can_complete_type_without_circularity): Add static to function definition. ! 2002-07-05 Jim Wilson ! * decl.c (mark_named_label_lists): Add missing & in call to ! mark_binding_level. 2002-07-05 Jason Merrill --- 2571,2647 ---- * tree.c (cp_copy_res_decl_for_inlining): Also copy TREE_ADDRESSABLE. + 2002-07-10 Graham Stott + + * pt.c (template_parm_this_level_p, push_template_decl_real): + Pass depth as int pointer. + + 2002-07-11 Tim Josling + + Remove front end hard coding from gengtype.c. + + * config-lang.in (gtfiles): Add files needed for this front end. + + 2002-07-10 Mark Mitchell + + * cp-tree.h (unqualified_name_lookup_error): Declare it. + (begin_function_definition): Adjust prototype. + * lex.c (unqualified_name_lookup_error): New function, split out + from ... + (do_identifier): ... here. + * parse.y (parse_begin_function_definition): New function. + (fn.def1): Use it. + * semantics.c (begin_function_definition): Accept decl-specifiers + and attributes as separate parameters. + 2002-07-10 Jason Merrill PR c++/6255 * decl.c (lookup_name_real): Build a new TYPENAME_TYPE rather than modifying the old one. + 2002-07-09 Mark Mitchell + + * cp-tree.h (constructor_name_p): Declare it. + (check_template_template_default_arg): Likewise. + * class.c (handle_using_decl): Use constructor_name_p. + * decl.c (grokdeclarator): Likewise. + * decl2.c (constructor_name_p): Define it. + * init.c (build_member_call): Use constructor_name_p. + * parse.y (template_parm): Use check_template_template_default_arg. + * pt.c (check_explicit_specialization): Use constructor_name_p. + * semantics.c (check_template_template_default_arg): New function. + 2002-07-08 Kriang Lerdsuwanakij * pt.c (can_complete_type_without_circularity): Add static to function definition. ! 2002-07-08 Mark Mitchell ! * cp-tree.h (have_extern_spec): Declare it ! * decl.c (have_extern_spec): Define it. ! (start_decl): Eliminate use of used_extern_spec. ! (start_function): Likewise. ! * parse.y (have_extern_spec): Remove declaration. ! (used_extern_spec): Likewise. ! (frob_specs): Eliminate use of used_extern_spec. ! (.hush_warning): Likewise. ! ! 2002-07-07 Mark Mitchell ! ! * Make-lang.in (cp/parse.o): Depend on decl.h. ! * cp-tree.h (do_decl_instantiation): Change prototype. ! * parse.y: Include decl.h. ! (parse_decl_instantiation): New function. ! (explicit_instantiation): Use it. ! * pt.c (do_decl_instantiation): Accept a DECL, not a DECLARATOR ! and DECLSPECS. ! ! 2002-07-07 Roger Sayle ! ! * error.c (dump_function_name): Use DECL_TEMPLATE_RESULT for ! constructor and destructor tests when passed a TEMPLATE_DECL. 2002-07-05 Jason Merrill *************** *** 602,612 **** PR optimization/7145 * tree.c (cp_copy_res_decl_for_inlining): Also copy DECL_INITIAL. ! 2002-05-18 Jason Merrill ! PR c++/6611 ! * decl2.c (import_export_decl): If we clear ! DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set. 2002-07-03 Kriang Lerdsuwanakij --- 2651,2664 ---- PR optimization/7145 * tree.c (cp_copy_res_decl_for_inlining): Also copy DECL_INITIAL. ! 2002-07-05 Nathan Sidwell ! Repair damage on weak-impared targets caused by my previous patch. ! * cp-tree.h (import_export_tinfo): Add parameter. ! * decl2.c (import_export_tinfo): Add parameter, post adjust ! DECL_COMDAT. ! * rtti.c (emit_tinfo_decl): DECL_COMDAT is (nearly) always setup by ! import_export_tinfo. 2002-07-03 Kriang Lerdsuwanakij *************** *** 616,628 **** (build_vec_init): Flatten multi-dimensional array during cleanup. (build_vec_delete_1): Abort if the type of each element is array. 2002-07-02 Kriang Lerdsuwanakij PR c++/6716 * pt.c (can_complete_type_without_circularity): New function. (instantiate_class_template): Use it. ! * typeck2.c (incomplete_type_error): Improve error message ! due to incomplete fields. 2002-07-01 Mark Mitchell --- 2668,2689 ---- (build_vec_init): Flatten multi-dimensional array during cleanup. (build_vec_delete_1): Abort if the type of each element is array. + 2002-07-03 Graham Stott + + * pt.c (instantiate_class_template): Fix typo. + + 2002-07-02 Kriang Lerdsuwanakij + + * typeck2.c (cxx_incomplete_type_diagnostic): Fix typo caused + by CVS conflict in my last patch. + 2002-07-02 Kriang Lerdsuwanakij PR c++/6716 * pt.c (can_complete_type_without_circularity): New function. (instantiate_class_template): Use it. ! * typeck2.c (cxx_incomplete_type_diagnostic): Improve error ! message due to incomplete fields. 2002-07-01 Mark Mitchell *************** *** 631,653 **** --- 2692,2828 ---- applied to a type. * operators.def: Remove stale comment. + 2002-06-30 Nathan Sidwell + + * cp-tree.h (CPTI_TINFO_DECL_TYPE): Replace with ... + (CPTI_TYPE_INFO_PTR_TYPE): ... this. + (tinfo_decl_type): Replace with ... + (type_info_ptr_type): ... this. + (import_export_tinfo): Declare. + (tinfo_decl_p): Rename to ... + (unemitted_tinfo_decl_p): ... this. + * decl2.c (import_export_decl): Break out tinfo handling into ... + (import_export_tinfo): ... here. New function. + (finish_file): Adjust. + * rtti.c (TINFO_REAL_NAME): New macro. + (init_rtti_processing): Create the tinfo types. + (get_tinfo_decl_dynamic): Use type_info_ptr_type, get_tinfo_ptr. + (get_tinfo_decl): Adjust. + (get_tinfo_ptr): New function. + (get_type_id): Use it. + (tinfo_base_init): Create vtable decl here, if it doesn't exist. + (ptr_initializer): Use get_tinfo_ptr. + (ptm_initializer): Likewise. + (synthesize_tinfo_var): Break into ... + (get_pseudo_ti_init): ... this. Just create the initializer. + (get_pseudo_ti_desc): .. and this. + (create_real_tinfo_var): Remove. + (create_pseudo_type_info): Don't create the vtable decl here. + (get_vmi_pseudo_type_info): Remove. + (create_tinfo_types): Adjust. + (tinfo_decl_p): Rename to ... + (unemitted_tinfo_decl_p): ... here. Adjust. + (emit_tinfo_decl): Adjust. Create the initializer. + 2002-06-27 Mark Mitchell PR c++/6695 * pt.c (tsubst_friend_class): Substitute into the context of the friend before using it. + 2002-06-26 Mark Mitchell + + * cp-tree.h (xref_tag): Change prototype. + (handle_class_head): Likewise. + (build_x_component_ref): Likewise. + * decl.c (cxx_init_decl_processing): Adjust call to xref_tag. + (xref_tag): Take attributes as a separate parameter. + (xref_tag_from_type): Adjust call to xref_tag. + * decl2.c (build_expr_from_tree): Adjust call to + build_x_component_ref. + (handle_class_head): Take attributes as a separate parameter. + * parse.y (parse_xref_tag): New function. + (parse_handle_class_head): Likewise. + (primary): Use parse_xref_tag. + (class_head_decl): Use parse_handle_class_head. + (class_head_defn): Likewise. + * rtti.c (init_rtti_processing): Adjust call to xref_tag. + (build_dynamic_cast_1): Likewise. + (create_pseudo_type_info): Likewise. + (emit_support_tinfos): Likewise. + * typeck.c (build_object_ref): Adjust call to + build_x_component_ref. + (build_x_component_ref): Remove protect parameter. + + 2002-06-25 Mark Mitchell + + * call.c (build_op_delete_call): Use BASELINK_FUNCTIONS. + * class.c (handle_using_decl): Likewise. + (instantiate_type): Likewise. + * cp-tree.h (BASELINK_FUNCTIONS): New macro. + (xref_basetypes): Change prototype. + (begin_mem_initializers): New function. + (get_overloaded_fn): Likewise. + * decl.c (xref_basetypes): Simplify. + * error.c (dump_expr): Use BASELINK_FUNCTIONS. + * init.c (build_offset_ref): Likewise. + * parse.y (base_init): Use begin_mem_initializers(). + (structsp): Adjust call to xref_basetypes. + * pt.c (determine_specialization): Use BASELINK_FUNCTIONS. + (instantiate_class_template): Adjust call to xref_basetypes. + * semantics.c (begin_mem_initializers): New function. + * tree.c (is_overloaded_fn): Use BASELINK_FUNCTIONS. + (really_overlaoded_fn): Likewise. + (get_overloaded_fn): New function.' + (get_first_fn): USe BASELINK_FUNCTIONS. + + 2002-06-24 Mark Mitchell + + * cp-tree.h (SCALAR_TYPE_P): New macro. + (check_for_out_of_scope_variable): New function. + (at_class_scope_p): Likewise. + (finish_fname): Likewise. + * class.c (finish_struct): Use at_function_scope_p. + * decl.c (check_for_out_of_scope_variable): New function, split + out from do_identifier. + (finish_enum): Use at_function_scope_p. + * lex.c (do_identifier): Use check_for_out_of_scope_variable. + * parse.y (VAR_FUNC_NAME): Give it . Use finish_fname. + (primary): Use at_function_scope_p. + * search.c (at_class_scope_p): New function. + * semantics.c (finish_fname): Likewise. + (check_multiple_declarators): Use at_function_scope_p. + + 2002-06-23 Mark Mitchell + + * parse.y (parse_scoped_id): New function. + (primary): Use it. + * cp-tree.h (do_scoped_id): Adjust declaration. + * lex.c (do_scoped_id): Remove call to yylex. + * decl2.c (build_expr_from_tree): Adjust use of do_scoped_id. + * typeck2.c (add_exception_specifier): Use tree_cons, rather than + expanding it inline. + 2002-06-23 Matt Thomas * decl.c (finish_function): Change "#ifdef VMS_TARGET" to "#if VMS_TARGET". + 2002-06-21 Kaveh R. Ghazi + + * mangle.c (integer_type_codes): Const-ify. + 2002-06-20 Richard Henderson PR c++/6747 * typeck.c (mark_addressable): Don't test TREE_ADDRESSABLE early. Call put_var_into_stack. + 2002-06-20 Kaveh R. Ghazi + + * spew.c (remove_last_token): Use ARRAY_SIZE in lieu of explicit + array size calculation. + 2002-06-20 Kriang Lerdsuwanakij PR c++/6892 *************** *** 660,681 **** --- 2835,3183 ---- BOUND_TEMPLATE_TEMPLATE_PARM if appeared as a default template argument. + 2002-06-19 Akim Demaille + + * parse.y (TYPENAME): Rename as tTYPENAME to avoid the clash with + decl.h's TYPENAME. + * spew.c, lex.c: Adjust. + * parse.y (explicit_instantiation): Add empty action to override + the default $$ = $1 where it introduces a type clash. + + 2002-06-14 Jason Merrill + + * semantics.c (begin_for_stmt): Push the 'for' scope before + adding the FOR_STMT. + + C++ ABI changes. + * class.c (build_base_field): Set DECL_PACKED. + (layout_class_type): Don't use tail padding of PODs. + * mangle.c (write_unqualified_name): Fix template conversion op + mangling. + 2002-06-16 Richard Henderson PR opt/6793 * tree.c (cp_cannot_inline_tree_fn): Don't short-circuit test after template instantiation. + 2002-06-16 Richard Henderson + + * cp-tree.h, decl2.c (flag_ms_extensions): Move to c-common. + + 2002-06-15 Gabriel Dos Reis + + * cp-tree.h (compiler_error): Remove declaration. + * lex.c (compiler_error): Remove definition. + + 2002-06-14 Steve Ellcey + + * g++spec.c (LIBUNWIND): New. + (lang_specific_driver): Add it if USE_UNWIND_EXCEPTIONS is set. + + 2002-06-13 Jessica Han + + * class.c (build_vtable): Use TARGET_VTABLE_ENTRY_ALIGN. + (build_vtbl_initializer): Honor TARGET_VTABLE_DATA_ENTRY_DISTANCE. + (build_vbase_offset_vtbl_entries): Likewise. + * rtti.c (build_headof): Likewise. + (get_tinfo_decl_dynamic): Likewise. + (create_pseudo_type_info): Likewise. + + 2002-06-12 Stan Shebs + + * mpw-config.in: Remove file, no longer used. + * mpw-make.sed: Ditto. + + 2002-06-07 Zack Weinberg + + * decl2.c: Update call to cpp_handle_option. + 2002-06-07 H.J. Lu (hjl@gnu.org) * decl2.c (flag_use_cxa_atexit): Set to DEFAULT_USE_CXA_ATEXIT. + 2002-06-06 Gabriel Dos Reis + + * error.c (cp_error_at): Fix typo. + + 2002-06-04 Gabriel Dos Reis + + * error.c (cp_diagnostic_starter): Adjust call. + (maybe_print_instantiation_context): Change prototype to take a + 'diagnostic_info *'. + (print_instantiation_full_context): Likewise. + (print_instantiation_partial_context): Likewise. + (cp_diagnostic_starter): Likewise. + (cp_diagnostic_finalizer): Likewise. + (cp_print_error_function): Likewise. + (cp_printer): Take a secondary parameter as a 'text_info *'. + Remove output_state savings. Adjust calls. + + 2002-06-03 Geoffrey Keating + + * pt.c (inline_parm_levels): Mark for GC. + + * mangle.c (start_mangling): Allocate G.substitutions here... + (init_mangle): ... rather than here. + (finish_mangling): Clear the varray pointer when done with it. + * spew.c (yylexstring): Don't use VARRAY_FREE. + * search.c (bfs_walk): Don't use VARRAY_FREE. + * decl2.c (pending_statics): Use gengtype to mark. + (deferred_fns): Likewise. + (ssdf_decls): Likewise. + (init_decl2): Delete. + * decl.c (pop_from_top_level): Don't use VARRAY_FREE. + (cxx_init_decl_processing): Don't call init_decl2. + (cxx_pop_function_context): Don't use VARRAY_FREE. + * cp-tree.h (struct saved_scope): No need for special marking + of varrays. + (struct language_function): Likewise. + (local_classes): Use gengtype to mark. + (init_decl2): Delete prototype. + * class.c (init_class_processing): Don't use + ggc_add_tree_varray_root. + (build_vtbl_initializer): Don't use VARRAY_FREE. + + * decl.c (typename_compare): Don't use same_type_p. + + * decl.c: Include hashtab.h instead of hash.h. + (typename_hash): Update to use htab_h. + (typename_compare): Likewise. + (typename_htab): Use gengtype to mark. + (build_typename_type): Update to use htab_h. + * Make-lang.in (cp/decl.o): Use HASHTAB_H instead of hash.h. + + * Make-lang.in (gt-cp-tree.h): New rule. + (cp/tree.o): Depend on gt-cp-tree.h. + * config-lang.in (gtfiles): Add cp/tree.c. + * tree.c: Include gt-cp-tree.h. + (list_hash_table): Use gengtype to mark. + (init_tree): Use gengtype to mark trees. + + * Make-lang.in (cp/decl.o): Add debug.h dependency. + * call.c (struct z_candidate): Use gengtype. + (USER_CONV_CAND): Use WRAPPER_ZC. + (convert_class_to_reference): Use build_zc_wrapper. + (build_type_conversion_1): Likewise. + (build_over_call): Use WRAPPER_ZC. + (add_warning): Use build_zc_wrapper. + * cp-lang.c (LANG_HOOKS_MARK_TREE): Delete. + * cp-tree.h (struct lang_identifier): Use gengtype. + (struct template_parm_index_s): Likewise. + (struct ptrmem_cst): Likewise. + (struct tree_binding): Likewise. + (struct tree_overload): Likewise. + (struct tree_srcloc): Likewise. + (struct tree_wrapper): Likewise. Also modify to have a pointer + to struct z_candidate rather than void. + (enum cp_tree_node_structure_enum): New. + (union lang_tree_node): New. + (cxx_mark_tree): Delete prototype. + (cp_tree_node_structure): New prototype. + (build_ptr_wrapper): Delete prototype. + (build_int_wrapper): Delete prototype. + (build_zc_wrapper): New prototype. + * decl.c: Include debug.h + (cxx_mark_tree): Delete. + (cp_tree_node_structure): New. + * tree.c (build_ptr_wrapper): Delete. + (build_int_wrapper): Delete. + (build_zc_wrapper): New. + + * cp-tree.h [! ENABLE_TREE_CHECKING] (LANG_TYPE_PTRMEM_CHECK): + Correct typo. Patch from k_fukui@highway.ne.jp. + + * semantics.c (current_stmt_tree): Update for change to + struct language_function. + (finish_mem_initializers): Likewise. + * decl.c (cxx_init_decl_processing): Don't set mark_lang_status. + * cp-tree.h (struct language_function): Rename from + cp_language_function. Change all uses. + (cp_function_chain): Don't need to cast. + + * class.c (duplicate_tag_error): Reset discriminator. + (check_bases_and_members): Update for data structure changes. + * cp-tree.h (struct lang_id2): Use gengtype. + (flagged_type_tree): Likewise. + (SET_LANG_ID): Use GGC on struct lang_id2. + (struct cp_language_function): Use gengtype. Remove field + 'x_vcalls_possible_p'. + (current_vcalls_possible_p): Delete. + (struct lang_type_header): New. + (struct lang_type_class): Rename from struct lang_type. Include + struct lang_type_header. + (struct lang_type_ptrmem): New. + (struct lang_type): New. + (LANG_TYPE_CLASS_CHECK): New. Use it in all the appropriate macros. + (LANG_TYPE_PTRMEM_CHECK): New. Use it in all the appropriate macros. + (TYPE_SET_PTRMEMFUNC_TYPE): Set discriminator, update for changes. + (struct lang_decl_flags): Use gengtype. Add discriminators. + (struct lang_decl): Use gengtype. Add and use discriminators. + Update the macros that reference moved fields. + (LANG_DECL_U2_CHECK): New function. Use it when appropriate. + (SET_DECL_THUNK_P): Set discriminator too. + (clear_inline_text_obstack): Delete prototype. + (finish_inline_definitions): Delete prototype. + (mark_pending_inlines): Delete prototype. + (lang_check_failed): New prototype. + * decl.c (struct named_label_use_list): Use gengtype. + (struct named_label_list): Likewise. + (mark_binding_level): Delete. + (mark_named_label_lists): Delete. + (push_local_name): Set discriminator on DECL_LANG_SPECIFIC. + (cxx_init_decl_processing): Use generated marker routine. + (begin_destructor_body): Delete dead set to + current_vcalls_possible_p. + (mark_lang_function): Delete. + (mark_cp_function_context): Delete. + (lang_mark_tree): Use generated marker routines. + * decl2.c (start_objects): Set discriminator when setting + GLOBAL_INIT_PRIORITY. + * lex.c (retrofit_lang_decl): Set discriminators. + (copy_lang_type): Update for changes to lang_type structure. + (cp_make_lang_type): Set discriminator. + * parse.y: Use gengtype on YYLVAL. Don't use dots in identifiers. + * search.c: Include ggc.h. + * semantics.c (anon_aggr_type_p): Use the macro, don't hand-code it. + (finish_inline_definitions): Delete. + * spew.c (struct token): Use gengtype. + (struct token_chunk): New. + (struct unparsed_text): Use gengtype. Store tokens in chunks. + (struct feed): Use gengtype. + (feed_obstack): Delete. + (feed): Mark as GC root. + (pending_inlines): Mark as GC root. + (pending_inlines_tail): Likewise. + (processing_these_inlines): Likewise. + (token_obstack): Make static. + (first_token): Likewise. + (init_spew): Don't initialize deleted things; use gengtype for roots. + (clear_inline_text_obstack): Delete. + (feed_input): Use GC for struct feed. Update for changes to + struct unparsed_text. + (mark_pending_inlines): Delete. + (next_token): Rename from add_token. Change all callers. Update + for changes to struct unparsed_text. + (space_for_token): New. + (remove_last_token): New. + (alloc_unparsed_text): New. + (snarf_block): Take an unparsed_text. Update for changes to struct + unparsed_text. + (snarf_method): Update for changes to struct unparsed_text. + (snarf_defarg): Update for changes to struct unparsed_text. + * tree.c (lang_check_failed): New. + + * Make-lang.in (gt-cp-call.h gt-cp-decl2.h gt-cp-parse.h + gt-cp-pt.h gt-cp-repo.h gt-cp-spew.h): New rules. + (cp/spew.o): Add dependency on gt-.h. + (cp/decl2.o): Add dependency on gt-.h. + (cp/call.o): Add dependency on gt-.h. + (cp/pt.o): Add dependency on gt-.h. + (cp/repo.o): Add dependency on gt-.h. + (cp/parse.o): Add dependency on gt-.h. + * call.c: Use gengtype for roots. + * config-lang.in (gtfiles): Add cp-tree.h decl.h lex.h call.c + decl2.c parse.y pt.c repo.c spew.c. + * cp-tree.h: Use gengtype for roots. + (struct saved_scope): Use GGC, gengtype. + (cp_parse_init): Delete prototype. + (init_pt): Delete prototype. + * decl.c: Use gengtype for roots. + (mark_saved_scope): Delete. + (cxx_init_decl_processing): Don't call deleted initilisation + routines. + (signed_size_zero_node): Delete, unused. + * decl.h: Use gengtype for roots. + * decl2.c: Use gengtype for roots. + * lex.h: Use gengtype for roots. + * parse.y: Use gengtype for roots. + (cp_parse_init): Delete. + * pt.c: Use gengtype for roots. + (init_pt): Delete. + * repo.c: Use gengtype for roots. + * spew.c: Use gengtype for roots. + + * Make-lang.in: Allow for filename changes. Add gtype-cp.h. + (cp/decl.o): Add dependency on gtype-cp.h. + * decl.c: Remove use of add_deletable_root, use GTY marker instead. + Include gtype-cp.h. Allow for filename changes. + + * Make-lang.in (cp/gt-decl.h): Generate using gengtype. + (cp/decl.o): Add cp/gt-decl.h dependency. + * config-lang.in (gtfiles): New. + * tree.h: Rename struct binding_level to struct cp_binding_level. + * decl.c: Rename struct binding_level to struct cp_binding_level. + Include cp/gt-decl.h. + (struct cp_binding_level): Use gengtype. + (make_binding_level): Use GGC on struct cp_binding_level. + (mark_binding_level): Use gt_ggc_m_cp_binding_level. + (cxx_init_decl_processing): Mark free_binding_level as + deletable. + + * decl.c (mark_cp_function_context): Update calling sequence. + + * decl.c (start_function): Don't free 'struct + cp_language_function'. + (pop_cp_function_context): Likewise. + (save_function_data): Allocate it using GC. + * semantics.c (genrtl_start_function): Don't free 'struct + cp_language_function'. + + 2002-05-31 Matthew Woodcraft + + * lang-specs.h: Use cpp_debug_options. + + 2002-05-28 Zack Weinberg + + * mangle.c, tree.c: Include real.h. + * Make-lang.in: Update dependency lists. + + 2002-05-25 Neil Booth + + * lex.c: Don't include c-lex.h. + * parse.y, spew.c: Don't include c-lex.h; include c-pragma.h. + 2002-05-23 Neil Booth + * spew.c (yyungetc, snarf_block): Remove indent_level handling. + + 2002-05-22 Richard Henderson + + * decl.c (obscure_complex_init): Check for VAR_DECL + before using DECL_THREAD_LOCAL. + + 2002-05-22 Richard Henderson + + * decl.c (check_tag_decl): Handle RID_THREAD. + (obscure_complex_init): Reject run-time init of tls. + (grokvardecl, grokdeclarator): Handle RID_THREAD. + * lex.c (reswords): Add __thread. + (rid_to_yy): Map RID_THREAD to SCSPEC. + + 2002-05-22 Neil Booth + * cp-lang.c (LANG_HOOKS_POST_OPTIONS): Use c_common_post_options. * cp-tree.h (cxx_post_options): Kill. * cp-lex.c (cxx_post_options): Kill. + 2002-05-21 Richard Henderson + + * lex.c (rid_to_yy): Add RID_THREAD. + + 2002-05-21 Alexandre Oliva + + * init.c (build_vec_init): Test for trivial copy-assignment when + copy-assigning arrays. + + 2002-05-20 Andreas Jaeger + + * init.c (build_default_init): Remove unused variable. + + 2002-05-20 Alexandre Oliva + + * call.c (any_strictly_viable): New. + (build_new_op): Use it for COMPOUND_EXPR and ADDR_EXPRs. + 2002-05-19 Kriang Lerdsuwanakij * error.c (dump_type) [TYPEOF_TYPE]: Fix parenthesis printing. *************** *** 687,697 **** instantiation after explicit specialization. (do_type_instantiation): Likewise. ! 2002-05-09 Jason Merrill ! * pt.c (tsubst_expr) [ASM_STMT]: Copy ASM_INPUT_P. ! 2002-05-15 Alexandre Oliva * cp-tree.h (struct lang_type): Added non_zero_init. (CLASSTYPE_NON_ZERO_INIT_P): New macro. --- 3189,3235 ---- instantiation after explicit specialization. (do_type_instantiation): Likewise. ! 2002-05-19 Alexandre Oliva ! * cp-tree.h (complete_type_or_diagnostic): Changed prototype, ! renamed from... ! (complete_type_or_else): ... this. Redefined as macro. ! (cxx_incomplete_type_diagnostic): Declare. ! (cxx_incomplete_type_error): Define as macro. ! * init.c (build_delete): Warn about incomplete types other than ! void, and use the built-in operator delete for them. ! * typeck.c (complete_type_or_diagnostic): Renamed from ! complete_type_or_else. Added warn_only argument, passed to... ! * typeck2.c (cxx_incomplete_type_diagnostic): ... this. Print ! warnings or errors depending on new warn_only argument. Renamed ! from... ! (cxx_incomplete_type_error): ... this. New implementation in ! terms of cxx_incomplete_type_diagnostic. ! 2002-05-18 Jason Merrill ! ! PR c++/6611 ! * decl2.c (import_export_decl): If we clear ! DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set. ! ! 2002-05-15 Kriang Lerdsuwanakij ! ! PR c++/6620 ! * pt.c (verify_class_unification): Don't check if PARM is template ! parameter dependent. Simplify. ! (unify) [TEMPLATE_PARM_INDEX]: Handle when ARG is a template ! parameter dependent expression. ! ! 2002-05-14 Jason Merrill ! ! * rtti.c (get_tinfo_decl): Don't call comdat_linkage. ! Do set DECL_COMDAT. ! (synthesize_tinfo_var): Take the public decl. ! (create_real_tinfo_var): Likewise. Check DECL_COMDAT. ! (emit_tinfo_decl): Adjust. Call import_export_decl. ! * decl2.c (import_export_decl): Simplify tinfo decl handling. ! ! 2002-05-14 Alexandre Oliva * cp-tree.h (struct lang_type): Added non_zero_init. (CLASSTYPE_NON_ZERO_INIT_P): New macro. *************** *** 710,737 **** (process_init_constructor): Create non-trivial zero-initializers for array members and class fields. ! 2002-05-14 Release Manager ! * GCC 3.1 Released. ! 2002-05-03 Jason Merrill ! * decl.c (BOOL_TYPE_SIZE): Move default to defaults.h. ! 2002-05-02 Mark Mitchell ! * init.c (perform_base_cleanups): Correct order of base class ! cleanups. ! 2002-05-01 Mark Mitchell ! PR c++/6527 ! * init.c (perform_base_cleanups): Emit cleanups in reverse order ! of construction. ! 2002-05-01 Gabriel Dos Reis ! * error.c (dump_type): Be careful about implicit typenames. 2002-04-30 Mark Mitchell --- 3248,3296 ---- (process_init_constructor): Create non-trivial zero-initializers for array members and class fields. ! 2002-05-14 Neil Booth ! * lang-specs.h: Remove redundant -lang-c++. ! 2002-05-13 Jason Merrill ! * class.c (build_vtbl_ref_1): Use fixed_type_or_null. ! (fixed_type_or_null): See through reference vars. ! (build_base_path): Vtable contents are constant. ! * typeck.c (get_member_function_from_ptrfunc): Likewise. ! 2002-05-12 Jason Merrill ! * cp-lang.c (ok_to_generate_alias_set_for_type): Backend-created ! structs are safe. ! 2002-05-09 Neil Booth ! * cp-tree.h (flag_ansi): Remove. ! * decl2.c (flag_ansi): Remove. ! (cxx_decode_option): Set flag_iso and flag_undef. ! 2002-05-09 Jason Merrill ! * typeck.c (get_member_function_from_ptrfunc): Reorganize. ! Use subtraction rather than a bitmask to get the index. ! * cvt.c (cp_convert_to_pointer): Bail on an error_mark_node. ! ! * pt.c (tsubst_expr) [ASM_STMT]: Copy ASM_INPUT_P. ! ! 2002-05-07 Neil Booth ! ! * Make-lang.in (decl2.o): Update. ! * cp-tree.h (warn_multichar): Remove. ! * decl2.c: Include c-common.h. ! (warn_multichar): Remove. ! ! 2002-05-03 Jason Merrill ! ! * tree.c (build_cplus_array_type): Only const and volatile get ! special handling. ! ! * decl.c (BOOL_TYPE_SIZE): Move default to defaults.h. 2002-04-30 Mark Mitchell *************** *** 777,798 **** PR c/6343 * decl.c (duplicate_decls): Call merge_weak. 2002-04-26 Mark Mitchell ! PR c++/6479 * method.c (do_build_assign_ref): Pass a derivation to build_method_call when calling base class assignment operators. ! 2002-04-24 Mark Mitchell ! * mangle.c (write_type): Don't use TYPE_MAIN_VARIANT when writing ! out an array type. ! (write_CV_qualifiers_for_type): Use TYPE_QUALS, not cp_type_quals, ! to determine qualifiers. * cvt.c (convert_to_void): Don't unconditionally make COND_EXPRs void. 2002-04-24 Jason Merrill PR c++/6331 --- 3336,3404 ---- PR c/6343 * decl.c (duplicate_decls): Call merge_weak. + 2002-04-26 Richard Henderson + + * parse.y (malloced_yyss, malloced_yyvs): New. + (yyoverflow): Re-add. Set them. + (free_parser_stacks): New. + 2002-04-26 Mark Mitchell ! PR c++/6497 * method.c (do_build_assign_ref): Pass a derivation to build_method_call when calling base class assignment operators. ! 2002-04-26 Richard Henderson ! * parse.y (yyoverflow): Revert. ! ! 2002-04-26 Richard Henderson ! ! PR c/3581 ! * parse.y (string): Remove. Update all uses to use STRING ! instead, and not call combine_strings. ! * rtti.c (tinfo_name): Use fix_string_type. ! * semantics.c (finish_asm_stmt): Don't call combine_strings. ! * spew.c (yylexstring): New. ! (read_token): Use it. ! ! 2002-04-25 Richard Henderson ! ! PR c/2161 ! * parse.y (yyoverflow): New. ! ! 2002-04-25 Jason Merrill ! ! PR c++/5607 ! * search.c (check_final_overrider): No longer static. ! * class.c (update_vtable_entry_for_fn): Call it. ! * cp-tree.h: Adjust. ! ! 2002-04-25 Neil Booth ! ! * cp-lang.c (LANG_HOOKS_SET_YYDEBUG): Remove. ! * cp-tree.h (cxx_set_yydebug): Die. ! * lex.c (YYDEBUG): Get from c-lex.h. ! (cxx_set_yydebug): Remove. ! * parse.y: Include c-lex.h. ! (YYDEBUG): Get from c-lex.h. ! ! 2002-04-24 Mark Mitchell + PR c++/6438. * cvt.c (convert_to_void): Don't unconditionally make COND_EXPRs void. + 2002-04-24 Neil Booth + + * cp-lang.c (LANG_HOOKS_COMMON_ATTRIBUTE_TABLE, + LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE, LANG_HOOKS_ATTRIBUTE_TABLE): + Redefine. + * cp-tree.h (cp_attribute_table): Rename. + * decl.c (lang_attribute_table): Remove declaration. + (cxx_init_decl_processing): Don't set it. + * tree.c (cp_attribute_table): Rename. + 2002-04-24 Jason Merrill PR c++/6331 *************** *** 806,820 **** * decl.c (make_rtl_for_nonlocal_decl): Don't mess with #pragma i/i stuff for comdats. - 2002-04-23 Jason Merrill - - PR c++/5504 - but re-breaks c++/411 - * init.c (push_base_cleanups): Rename to perform_base_cleanups. - Expand base cleanups now rather than pushing them. - * decl.c (begin_destructor_body): Don't call push_base_cleanups. - (finish_destructor_body): Call perform_base_cleanups. - * cp-tree.h: Adjust prototype. - 2002-04-23 Jakub Jelinek * parse.y (check_class_key): Allow KEY to be union/enum/struct/class --- 3412,3417 ---- *************** *** 835,840 **** --- 3432,3467 ---- * typeck.c (merge_types): Remember the cv-qualification of pointer types when merging them. + 2002-04-20 Neil Booth + + * cp-lang.c (LANG_HOOKS_FUNCTION_INIT, + LANG_HOOKS_FUNCTION_FREE, LANG_HOOKS_FUNCTION_MARK): Redefine. + * cp-tree.h (cxx_push_function_context, cxx_pop_function_context, + cxx_mark_function_context): New. + * decl.c (push_cp_function_context, pop_cp_function_context, + mark_cp_function_context): Rename for consistency. + (cxx_init_decl_processing): Don't set old hooks. + + 2002-04-19 Neil Booth + + * call.c (convert_type_from_ellipsis): Rename, update. + * cp-lang.c (LANG_HOOKS_TYPE_PROMOTES_TO): Redefine. + * cp-tree.h (convert_type_from_ellipsis): Rename. + * decl.c (cxx_init_decl_processing): Don't set hook. + + 2002-04-18 Neil Booth + + * call.c (build_new_method_call): Update. + * cp-lang.c (LANG_HOOKS_INCOMPLETE_TYPE_ERROR): Redefine. + * cp-tree.h (cxx_incomplete_type_error): New. + * decl.c (grokdeclarator, grokparms): Update. + * decl2.c (check_classfn): Update. + * pt.c (tsubst): Update. + * typeck.c (complete_type_or_else, expr_sizeof, + decay_conversion): Update. + * typeck2.c (incomplete_type_error): Rename. + (add_exception_specifier): Update. + 2002-04-18 Jason Merrill PR c++/5658 *************** *** 859,883 **** --- 3486,3532 ---- * decl.c (register_dtor_fn): Pass the address of dso_handle, not dso_handle itself, to __cxa_atexit. + 2002-04-15 Gabriel Dos Reis + + * error.c (cxx_print_error_function): Adjust call to macros. + 2002-04-14 Jakub Jelinek * class.c (layout_virtual_bases): Do all dsize computation on trees. + 2002-04-14 Jason Merrill + + * typeck.c (get_member_function_from_ptrfunc): Don't do + gratuitious division and multiplication on + ptrmemfunc_vbit_in_delta targets. + 2002-04-12 Mark Mitchell PR c++/5373. * semantics.c (finish_expr_stmt): Remember the type of the expression before any conversions are performed. + 2002-04-12 Mark Mitchell + PR c++/5189. * call.c (add_template_candidate_real): Do not treat member templates as copy constructors. + 2002-04-12 Mark Mitchell + * decl.c (duplicate_decls): Do not copy the RTL for a variable declaration if the old variable had an incomplete type and the new variable does not. (complete_vars): Do not call layout_decl for completed variables. + 2002-04-12 Richard Sandiford + + * decl.c (duplicate_decls): Don't try to unify an implicit typedef + with an explicit one. + (follow_tag_typedef): New. + (lookup_tag): Use it to extract the tag of an explicit typedef. + (xref_tag): Likewise. + 2002-04-11 Andrew Haley * typeck.c (type_after_usual_arithmetic_conversions): *************** *** 887,900 **** if neither operand is one of the standard types, return the type of the first operand. - 2002-04-12 Richard Sandiford - - * decl.c (duplicate_decls): Don't try to unify an implicit typedef - with an explicit one. - (follow_tag_typedef): New. - (lookup_tag): Use it to extract the tag of an explicit typedef. - (xref_tag): Likewise. - 2002-04-10 Nathan Sidwell PR c++/5507 --- 3536,3541 ---- *************** *** 906,911 **** --- 3547,3555 ---- * semantics.c (genrtl_start_function): Don't free DECL_SAVED_FUNCTION_DATA for inline functions. + * init.c (build_member_call): For now, don't convert to + intermediate base if it would cause an error. + 2002-04-08 Paolo Carlini * parse.y (namespace_qualifier, maybe_identifier, *************** *** 943,957 **** * error.c (dump_expr) [CONVERT_EXPR]: Make sure TREE_TYPE (t) is set before checking it. PR c++/6179 * method.c (implicitly_declare_fn): Pass unqualified type to synthesize_exception_spec. ! 2002-04-03 Jason Merrill ! PR c++/525 ! * init.c (build_member_call): Convert to intermediate base even ! with -pedantic. PR c++/5636 * semantics.c (nullify_returns_r): Just set CLEANUP_EH_ONLY on --- 3587,3631 ---- * error.c (dump_expr) [CONVERT_EXPR]: Make sure TREE_TYPE (t) is set before checking it. + PR c++/525 + * init.c (build_member_call): Use build_scoped_ref. + (resolve_offset_ref): Likewise. + * call.c (build_scoped_method_call): Likewise. + * tree.c (maybe_dummy_object): Kludge around current_class_type being + wrong. + * typeck2.c (build_scoped_ref): Return the binfo via binfo_p parm. + * cp-tree.h: Adjust. + + * init.c (push_base_cleanups): Just use build_scoped_method_call. + PR c++/6179 * method.c (implicitly_declare_fn): Pass unqualified type to synthesize_exception_spec. ! 2002-04-04 Neil Booth ! * cp-lang.c (LANG_HOOKS_TRUTHVALUE_CONVERSION): Redefine. ! * cvt.c: Update comment. ! * init.c (expand_cleanup_for_base): Update. ! * semantics.c (finish_parenthesized_expr): Update. ! * typeck.c (cp_truthvalue_conversion): Update. ! ! 2002-04-04 Jason Merrill ! ! * semantics.c (finish_eh_cleanup): New fn. ! * cp-tree.h: Add prototype. ! * init.c (perform_member_init, expand_cleanup_for_base): Use ! finish_eh_cleanup. ! * cp-tree.def (SUBOBJECT, CTOR_STMT): Remove. ! * cp-tree.h: Remove references. ! * decl.c (begin_constructor_body, end_constructor_body): Likewise. ! * dump.c (cp_dump_tree): Likewise. ! * pt.c (tsubst_expr): Likewise. ! * semantics.c (genrtl_ctor_stmt, genrtl_subobject): Remove. ! (cp_expand_stmt): Remove handling of CTOR_STMT and SUBOBJECT. ! * tree.c (cp_statement_code_p): Likewise. ! ! * init.c (build_new_1): Set CLEANUP_EH_ONLY on deleting cleanup. PR c++/5636 * semantics.c (nullify_returns_r): Just set CLEANUP_EH_ONLY on *************** *** 962,973 **** --- 3636,3673 ---- specifiers. [METHOD_TYPE]: Use same code as FUNCTION_TYPE. + 2002-04-03 Richard Henderson + + * cp-lang.c (cxx_warn_unused_global_decl): New. + (LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL): New. + + 2002-04-03 Neil Booth + + * cp-lang.c (LANG_HOOKS_SET_DECL_ASSEMBLER_NAME): Redefine. + * tree.c (init_tree): Don't set hook. + 2002-04-03 Roger Sayle PR c++/5998: * decl.c (duplicate_decls): Don't mess with assembler names when redeclaring builtin functions as static. + 2002-04-01 Neil Booth + + * call.c (build_addr_func): Update. + * class.c (resolve_address_of_overloaded_function): Update. + * cp-lang.c (LANG_HOOKS_MARK_ADDRESSABLE): Redefine. + * cp-tree.h (cxx_mark_addressable): New. + * decl.c (register_dtor_fn, cxx_maybe_build_cleanup): Update. + * decl2.c (build_cleanup): Update. + * except.c (build_throw): Update. + * init.c (resolve_offset_ref): Update. + * pt.c (convert_nontype_argument): Update. + * semantics.c (finish_asm_stmt, simplify_affr_init_exprs_r): Update. + * typeck.c (decay_conversion, build_array_ref, build_unary_op, + unary_complex_lvalue): Update. + (mark_addressable): Rename. + 2002-04-01 Roger Sayle PR c++/5998: *************** *** 975,980 **** --- 3675,3714 ---- when) overwriting a built-in function. Don't use COPY_DECL_RTL, but follow the SET_DECL_RTL idiom used elsewhere in the function. + 2002-04-01 Neil Booth + + * cp-lang.c (LANG_HOOKS_SIGNED_TYPE, LANG_HOOKS_UNSIGNED_TYPE, + LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE): New. + * decl.c (grokdeclarator): Update. + * mangle.c (write_integer_cst): Update. + * typeck.c (build_binary_op): Update. + + 2002-03-31 Neil Booth + + * cp-lang.c (LANG_HOOKS_UNSAFE_FOR_REEVAL): Redefine. + * lex.c (cxx_init): Don't set hook. + + 2002-03-31 Neil Booth + + * Make-lang.in (error.o): Update. + * cp-lang.c (LANG_HOOKS_PRINT_ERROR_FUNCTION): Redefine. + * cp-tree.h (struct diagnostic_context): Predeclare. + (cxx_print_error_function): New. + * error.c: Include langhooks-def.h. + (lang_print_error_function): Rename. Update. + (init_error): Don't set hook. + + 2002-03-29 Neil Booth + + * cp-lang.c (LANG_HOOKS_TYPE_FOR_MODE, LANG_HOOKS_TYPE_FOR_SIZE): + Redefine. + * cvt.c (cp_convert_to_pointer, type_promotes_to): Use new hooks. + * decl.c (finish_enum): Similarly. + * error.c (dump_type): Similarly. + * lex.c (cxx_init): Similarly. + * mangle.c (write_builtin_type): Similarly. + * typeck.c (comptypes): Similarly. + 2002-03-28 Roger Sayle PR c++/5998: *************** *** 998,1015 **** --- 3732,3779 ---- * lex.c (do_scoped_id): Fail to find an identifier in the global namespace if its still anticipated. + 2002-03-29 Neil Booth + + * cp-lang.c (LANG_HOOKS_MAKE_TYPE): Redefine. + * cp-tree.h (cp_make_lang_type): Rename. + * lex.c (cp_make_lang_type): Rename. + (make_aggr_type): Update. + * tree.c (init_tree): Don't set make_lang_type_fn. + 2002-03-29 Jakub Jelinek PR c++/6073 * class.c (finish_struct_1): Update static field's DECL_MODE even if its type is a variant of t. + 2002-03-27 Neil Booth + + * cp-lang.c (LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES): Redefine. + * cp-tree.h (cxx_insert_default_attributes): New. + * decl.c (insert_default_attributes): Rename. + 2002-03-27 Mark Mitchell PR c++/4884 * call.c (build_op_delete_call): Allow for the fact the placement may be a COMPOUND_EXPR. + 2002-03-27 Neil Booth + + * cp-lang.c (LANG_HOOKS_EXPAND_EXPR): Redefine. + * cp-tree.h (init_cplus_expand): Remove. + (cxx_expand_expr): New. + * expr.c (cplus_expand_expr): Rename cxx_expand_expr, + fix prototype. + (init_cplus_expand): Remove. + * lex.c (cxx_init): Don't call init_cplus_expand. + + 2002-03-26 Mark Mitchell + + PR c++/4884. + * init.c (build_new_1): Allow for the fact the result of + build_function_call may be a COMPOUND_EXPR. + 2002-03-26 Nathan Sidwell PR c++/5682 *************** *** 1022,1048 **** (dfs_unmarked_real_bases_queue_p): Just get the canonical binfo. (dfs_marked_real_bases_queue_p): Likewise. ! 2002-03-26 Mark Mitchell ! PR c++/4884 ! * init.c (build_new_1): Allow for the fact the result of ! build_function_call may be a COMPOUND_EXPR. ! 2002-03-25 Jakub Jelinek PR c++/6037 * decl.c (start_enum): Don't set TREE_ADDRESSABLE on TREE_LIST node. 2002-03-22 Jeff Knaggs ! * typeck.c (expand_ptrmemfunc_cst): Scale idx down to an index ! into the vtable_entry array regardless of TARGET_PTRMEMFUNC_VBIT_LOCATION. 2002-03-21 Aldy Hernandez * tree.c (cp_cannot_inline_tree_fn): Same. 2002-03-20 Jason Merrill PR c++/2136 --- 3786,3853 ---- (dfs_unmarked_real_bases_queue_p): Just get the canonical binfo. (dfs_marked_real_bases_queue_p): Likewise. ! 2002-03-26 Neil Booth ! * cp-lang.c (LANG_HOOKS_MARK_TREE): Redefine. ! * cp-tree.h (cxx_mark_tree): New. ! * decl.c (lang_mark_tree): Rename cxx_mark_tree. ! 2002-03-25 Neil Booth ! ! * cp-tree.h (cxx_maybe_build_cleanup): New. ! * decl.c (destroy_local_var, hack_incomplete_structures): Update. ! (maybe_build_cleanup): Rename cxx_maybe_build_cleanup. ! * tree.c (build_target_expr): Update. ! * cp-lang.c (LANG_HOOKS_MAYBE_BUILD_CLEANUP): Redefine. ! ! 2002-03-24 Neil Booth ! ! * decl2.c (cxx_decode_option): Handle -E. ! * lang-specs.h (default_compilers): Preprocess with cc1plus. ! * lex.c (cxx_init): Exit quickly if c_common_init returns NULL. ! ! 2002-03-23 Jakub Jelinek PR c++/6037 * decl.c (start_enum): Don't set TREE_ADDRESSABLE on TREE_LIST node. + 2002-03-23 Gabriel Dos Reis + + * error.c (dump_type): Be careful about implicit typenames. + + 2002-03-21 Gabriel Dos Reis + + PR C++/3656 + * semantics.c (finish_base_specifier): Handle erronous base + classes. + + 2002-03-22 Zack Weinberg + + * error.c: Always use REAL_VALUE_TO_DECIMAL; don't test + REAL_IS_NOT_DOUBLE. + 2002-03-22 Jeff Knaggs ! * typeck.c (get_member_function_from_ptrfunc): Scale idx down to ! an index into the vtable_entry array regardless of TARGET_PTRMEMFUNC_VBIT_LOCATION. 2002-03-21 Aldy Hernandez * tree.c (cp_cannot_inline_tree_fn): Same. + 2002-03-21 Neil Booth + + * cp-tree.h (pushdecl, pushlevel, poplevel, set_block, + insert_block, getdecls, global_bindings_p): New. + + 2002-03-20 Nathan Sidwell + + PR c++/4361 + * mangle.c (struct globals) Add internal_mangling_p member. + (write_template_param): Do internal mangling, if needed. + (mangle_conv_op_name_for_type): Request internal mangling. + 2002-03-20 Jason Merrill PR c++/2136 *************** *** 1054,1059 **** --- 3859,3873 ---- PR c++/5118 * class.c (get_vfield_name): Use the constructor_name. + 2002-03-20 Neil Booth + + * cp-lang.c (LANG_HOOKS_DECL_PRINTABLE_NAME): Redefine. + * cp-tree.h (lang_printable_name): Rename. + * error.c (lang_decl_name): Use new hook. + * lex.c (cxx_init): Remove old hook. + * pt.c (tsubst_decl): Use new hook. + * tree.c (lang_printable_name): Rename. + 2002-03-18 Eric Botcazou PR c++/3882 *************** *** 1061,1071 **** (tsubst_expr) [DECL_STMT]: ...here. And substitute the initializer only after recording the declaration. - 2002-03-18 Ashif Harji - - * lang-specs.h (compiler default_compilers): Add - -no-integrated-cpp flag to invoke an external cpp. - 2002-03-18 Jason Merrill PR c++/2039 --- 3875,3880 ---- *************** *** 1096,1112 **** * class.c (build_base_path): Virtual base layout is fixed in in-charge [cd]tors. PR c++/5757 * init.c (build_new_1): Pass the right pointer to op delete. ! 2002-03-15 Richard Henderson ! * init.c (build_new_1): Use size_binop instead of cp_build_binary_op. 2002-03-15 Richard Henderson ! * decl.c (finish_function): Reapply accidentally reverted ! 2002-02-28 patch. 2002-03-15 Mark Mitchell --- 3905,3947 ---- * class.c (build_base_path): Virtual base layout is fixed in in-charge [cd]tors. + 2002-03-17 Neil Booth + + * cp-lang.c (LANG_HOOKS_PARSE_FILE): Redefine. + * parse.y (yyparse): Remove macro. + + 2002-03-17 Jason Merrill + PR c++/5757 * init.c (build_new_1): Pass the right pointer to op delete. ! 2002-03-16 Nathan Sidwell ! PR c++/4361 ! * cp-tree.h (CLASSTYPE_METHOD_VEC): Document where templated ! conversion operators go. ! (struct lang_decl_flags): Add template_conv_p and unused ! bitfields. ! (DECL_TEMPLATE_CONV_FN_P): New macro. ! * call.c (build_user_type_conversion_1): Don't check second type ! conversion of overload set first. ! * class.c (add_method): Make sure templated conversion operators ! all end up on slot 2. ! * lex.c (do_identifier): A conversion operator token might be ! satisfied by a templated conversion operator. ! * pt.c (check_explicit_specialization): Use ! CLASSTYPE_FIRST_CONVERSION_SLOT. ! (template_parm_this_level_p): New function. ! (push_template_decl_real): Determine DECL_TEMPLATE_CONV_FN_P. ! * search.c (lookup_fnfields_1): Template conversions will be on ! the first slot. ! * typeck.c (build_component_ref): Preserve the type of an ! conversion operator name on the overload type. ! (build_x_function_call): Retrieve the conversion operator name. 2002-03-15 Richard Henderson ! * init.c (build_new_1): Use size_binop instead of cp_build_binary_op. 2002-03-15 Mark Mitchell *************** *** 1118,1129 **** * semantics.c (cp_expand_stmt): Likewise. * cp/tree.c (cp_statement_code_p): Likewise. - 2002-03-15 Richard Henderson - - * decl.c: Include c-pragma.h. - (start_decl, start_function): Invoke maybe_apply_pragma_weak. - * Make-lang.in: Update dependencies. - 2002-03-15 Jason Merrill PR c++/5857 --- 3953,3958 ---- *************** *** 1141,1146 **** --- 3970,3981 ---- variables. * decl2.c (maybe_make_one_only): Also mark the decl as needed. + 2002-03-14 Richard Henderson + + * decl.c: Include c-pragma.h. + (start_decl, start_function): Invoke maybe_apply_pragma_weak. + * Make-lang.in: Update dependencies. + 2002-03-14 Jakub Jelinek PR c++/5908 *************** *** 1152,1157 **** --- 3987,4010 ---- * mangle.c (write_builtin_type): Handle 128-bit integers even if they are not a standard integer type. + 2002-03-12 Richard Sandiford + + * cp-tree.h (init_init_processing): Remove declaration. + * init.c (BI_header_type, init_init_processing): Remove old ABI stuff. + * decl.c (cxx_init_decl_processing): Don't call init_init_processing. + + 2002-03-12 Kaveh R. Ghazi + + * cp-lang.c (tree_code_type, tree_code_length, tree_code_name): + Define. + * decl.c (duplicate_decls): Use TREE_CODE_LENGTH, not + tree_code_length. + * lex.c (cplus_tree_code_type, cplus_tree_code_length, + cplus_tree_code_name): Delete. + (cxx_init): Don't call add_c_tree_codes, instead set + lang_unsafe_for_reeval. Don't try to copy into the various + tree_code arrays. + 2002-03-12 Nathan Sidwell PR c++/5659 *************** *** 1179,1189 **** --- 4032,4066 ---- * typeck.c (build_static_cast): Compare non-qualified types with pointer to member conversions. + 2002-03-11 Dan Nicolaescu + Daniel Berlin + + * cp-lang.c (ok_to_generate_alias_set_for_type): New function. + (cxx_get_alias_set): Use it. + + 2002-03-10 Kaveh R. Ghazi + + * cp-tree.h (stabilize_expr): Prototype. + 2002-03-08 Craig Rodrigues * cp-tree.h (CLEAR_BINFO_MARKED): Make both parts of conditional return void. + 2002-03-08 Neil Booth + + * cp-lang.c (LANG_HOOKS_UNSAVE): Redefine. + * cp-tree.h (cxx_unsave): New. + * tree.c (cp_unsave): Rename cxx_unsave, update prototype. + (init_tree): Update. + + 2002-03-03 Kaveh R. Ghazi + + * decl.c (cxx_init_decl_processing): Use ARRAY_SIZE in lieu of + explicit sizeof/sizeof. + * decl2.c (cxx_decode_option): Likewise. + * lex.c (init_reswords, REDUCE_LENGTH, TOKEN_LENGTH): Likewise. + 2002-03-02 Nathan Sidwell PR c++/775 *************** *** 1199,1211 **** 2002-03-01 Phil Edwards - * cp-tree.h (build_init): Remove prototype. - - 2002-03-01 Phil Edwards - * cp-tree.h: Require __GNUC__ to be #defined. (build_init): Add missing prototype. 2002-02-28 Jason Merrill * search.c (lookup_base_r): Don't clear is_non_public just because --- 4076,4097 ---- 2002-03-01 Phil Edwards * cp-tree.h: Require __GNUC__ to be #defined. (build_init): Add missing prototype. + 2002-03-01 Jason Merrill + + * except.c: Don't include decl.h or obstack.h. Do include + tree-inline.h. + (build_throw): Destroy temporaries from the thrown + expression before calling __cxa_throw. Construct a thrown + temporary directly into the exception object. + (stabilize_throw_expr): New function. + (wrap_cleanups_r): New function. + * tree.c (stabilize_expr): New function. + * init.c (build_init): New function. + * Make-lang.in (cp/except.o): Adjust .h deps. + 2002-02-28 Jason Merrill * search.c (lookup_base_r): Don't clear is_non_public just because *************** *** 1214,1219 **** --- 4100,4120 ---- * decl.c (finish_function): Only warn about missing return statement with -Wreturn-type. + 2002-02-28 Neil Booth + + * class.c (build_clone): Update. + * cp-lang.c (LANG_HOOKS_DUP_LANG_SPECIFIC_DECL): Redefine. + * cp-tree.h (cxx_dup_lang_specific_decl): New. + * lex.c (copy_lang_decl): Rename cxx_dup_lang_specific_decl. + (copy_decl): Update. + * method.c (make_thunk): Update. + + 2002-02-27 Zack Weinberg + + * decl2.c: Delete traditional-mode-related code copied from + the C front end but not used, or used only to permit the + compiler to link. + 2002-02-24 Craig Rodrigues PR c++/4093 *************** *** 1243,1249 **** * pt.c (convert_template_argument): Adjust make_typename_type return value. (tsubst): Adjust cp_build_qualified_type_real calls. ! (check_cv_quals_for_unify): Cope with alowing bad qualifications on template type parms. (instantiate_decl): Recheck substitutions to give warnings on bad qualifications. --- 4144,4150 ---- * pt.c (convert_template_argument): Adjust make_typename_type return value. (tsubst): Adjust cp_build_qualified_type_real calls. ! (check_cv_quals_for_unify): Cope with allowing bad qualifications on template type parms. (instantiate_decl): Recheck substitutions to give warnings on bad qualifications. *************** Tue Nov 27 09:03:47 2001 Richard Kenner *** 2378,2384 **** * search.c (get_vbase_1): Remove. (get_vbase): Remove. (convert_pointer_to_vbase): Remove. ! (lookup_base_recursive): New function. (lookup_base): New function. * typeck.c (require_complete_type): Use lookup_base & build_base_path instead of convert_pointer_to. --- 5279,5285 ---- * search.c (get_vbase_1): Remove. (get_vbase): Remove. (convert_pointer_to_vbase): Remove. ! (lookup_base_r): New function. (lookup_base): New function. * typeck.c (require_complete_type): Use lookup_base & build_base_path instead of convert_pointer_to. *************** Fri Sep 21 08:16:19 2001 J"orn Rennecke *** 3221,3227 **** PR c++/3621 * spew.c (yylex): Only copy the token's lineno, if it is ! non-zero. 2001-07-26 Nathan Sidwell --- 6122,6128 ---- PR c++/3621 * spew.c (yylex): Only copy the token's lineno, if it is ! nonzero. 2001-07-26 Nathan Sidwell *************** Fri Sep 21 08:16:19 2001 J"orn Rennecke *** 3312,3318 **** 2001-07-23 Graham Stott ! * cp/class.c (type_requires_array_cookie): Fix use of uninitialised variable has_two_argument_delete_p. 2001-07-21 Nathan Sidwell --- 6213,6219 ---- 2001-07-23 Graham Stott ! * cp/class.c (type_requires_array_cookie): Fix use of uninitialized variable has_two_argument_delete_p. 2001-07-21 Nathan Sidwell *************** Fri Sep 21 08:16:19 2001 J"orn Rennecke *** 3359,3365 **** 2001-07-20 Nathan Sidwell Remove old-abi remnants. Remove comments about old abi ! behaviour. Remove references to 'new-abi' in comments. * cp-tree.h: Adjust comments. (vbase_offsets_in_vtable_p): Delete. (vcall_offsets_in_vtable_p): Delete. --- 6260,6266 ---- 2001-07-20 Nathan Sidwell Remove old-abi remnants. Remove comments about old abi ! behavior. Remove references to 'new-abi' in comments. * cp-tree.h: Adjust comments. (vbase_offsets_in_vtable_p): Delete. (vcall_offsets_in_vtable_p): Delete. *************** Thu Apr 5 16:54:29 2001 J"orn Rennecke *** 4561,4567 **** (maybe_commonize_var): Allow inlining functions even if they have static local variables, use comdat_linkage for them if flag_weak. (check_initializer): Call obscure_complex_init if ! grok_reference_init returned non-zero. (save_function_data): Clear x_local_names. (pop_cp_function_context): Free x_local_names. (mark_inlined_fns): Remove. --- 7462,7468 ---- (maybe_commonize_var): Allow inlining functions even if they have static local variables, use comdat_linkage for them if flag_weak. (check_initializer): Call obscure_complex_init if ! grok_reference_init returned nonzero. (save_function_data): Clear x_local_names. (pop_cp_function_context): Free x_local_names. (mark_inlined_fns): Remove. *************** Sun Feb 4 15:52:44 2001 Richard Kenner *** 5808,5814 **** (cp_make_fname_decl): Use size_int, not build_int_2. (push_inline_template_parms_recursive): Likewise. (end_template_parm_list): Likewise. ! (for_each_tempalte_parm): Do not use walk_tree_without_duplicates. (tsubst_template_parms): Use size_int, not build_int_2. (tsubst): Likewise. * rtti.c (get_vmi_pseudo_type_info): Likewise. --- 8709,8715 ---- (cp_make_fname_decl): Use size_int, not build_int_2. (push_inline_template_parms_recursive): Likewise. (end_template_parm_list): Likewise. ! (for_each_template_parm): Do not use walk_tree_without_duplicates. (tsubst_template_parms): Use size_int, not build_int_2. (tsubst): Likewise. * rtti.c (get_vmi_pseudo_type_info): Likewise. *************** Thu Nov 23 02:16:47 2000 J"orn Rennecke *** 6300,6306 **** 2000-11-17 Nathan Sidwell ! * typeck2.c (incomplete_type_error): Reorganise to avoid excessive diagnostics. 2000-11-16 Zack Weinberg --- 9201,9207 ---- 2000-11-17 Nathan Sidwell ! * typeck2.c (incomplete_type_error): Reorganize to avoid excessive diagnostics. 2000-11-16 Zack Weinberg *************** Sun Feb 27 16:40:33 2000 Richard Kenner *** 11708,11714 **** (add_method): Used functions are hidden by local functions. (check_bases_and_members): Handle using-decls before finalizing CLASSTYPE_METHOD_VEC. ! * call.c (add_function_candidate): Add ctype parm; if non-zero, override the type of 'this' accordingly. (add_template_candidate, add_template_candidate_real): Add ctype parm. (convert_class_to_reference, build_user_type_conversion_1, --- 14609,14615 ---- (add_method): Used functions are hidden by local functions. (check_bases_and_members): Handle using-decls before finalizing CLASSTYPE_METHOD_VEC. ! * call.c (add_function_candidate): Add ctype parm; if nonzero, override the type of 'this' accordingly. (add_template_candidate, add_template_candidate_real): Add ctype parm. (convert_class_to_reference, build_user_type_conversion_1, diff -Nrc3pad gcc-3.2.3/gcc/cp/ChangeLog.1 gcc-3.3/gcc/cp/ChangeLog.1 *** gcc-3.2.3/gcc/cp/ChangeLog.1 2001-12-16 16:06:57.000000000 +0000 --- gcc-3.3/gcc/cp/ChangeLog.1 2002-09-15 17:55:36.000000000 +0000 *************** Tue May 17 13:34:46 1994 Jason Merrill *** 5729,5735 **** Mon May 16 23:04:01 1994 Stephen R. van den Berg * cp/typeck.c (common_type): Attribute merging. ! (comp_types): Utilise COMP_TYPE_ATTRIBUTES macro. * cp/parse.y: Revamp attribute parsing. --- 5729,5735 ---- Mon May 16 23:04:01 1994 Stephen R. van den Berg * cp/typeck.c (common_type): Attribute merging. ! (comp_types): Utilize COMP_TYPE_ATTRIBUTES macro. * cp/parse.y: Revamp attribute parsing. *************** Wed May 4 11:19:45 1994 Jason Merrill *** 6168,6174 **** Tue May 3 16:02:53 1994 Per Bothner Give a vtable entries a unique named type, for the sake of gdb. ! * class.c (build_vtable_entry): The addres of a thunk now has type vtable_entry_type, not ptr_type_node. * method.c (make_thunk): Fix type of THUNK_DECL. * class.c (add_virtual_function, override_one_vtable): Use --- 6168,6174 ---- Tue May 3 16:02:53 1994 Per Bothner Give a vtable entries a unique named type, for the sake of gdb. ! * class.c (build_vtable_entry): The address of a thunk now has type vtable_entry_type, not ptr_type_node. * method.c (make_thunk): Fix type of THUNK_DECL. * class.c (add_virtual_function, override_one_vtable): Use diff -Nrc3pad gcc-3.2.3/gcc/cp/ChangeLog.2 gcc-3.3/gcc/cp/ChangeLog.2 *** gcc-3.2.3/gcc/cp/ChangeLog.2 2001-12-16 16:06:57.000000000 +0000 --- gcc-3.3/gcc/cp/ChangeLog.2 2002-09-21 12:51:52.000000000 +0000 *************** Wed Oct 13 22:01:35 1999 J"orn Rennecke *** 1264,1270 **** 1999-10-06 Brendan Kehoe ! * decl.c (grokdeclarator): Only warn about non-zero arrays if !in_system_header (linux socketbits.h can give this for __cmsg_data, which is using a GNU extension). --- 1264,1270 ---- 1999-10-06 Brendan Kehoe ! * decl.c (grokdeclarator): Only warn about nonzero arrays if !in_system_header (linux socketbits.h can give this for __cmsg_data, which is using a GNU extension). *************** Mon Mar 4 22:38:39 1996 Gerald Baumgar *** 19205,19211 **** * sig.c (build_signature_pointer_or_reference_type): Align signature pointers/references on 8-byte boundaries so they can be ! grabbed 2 words at a time on a Sparc. Tue Mar 5 10:21:01 1996 Jason Merrill --- 19205,19211 ---- * sig.c (build_signature_pointer_or_reference_type): Align signature pointers/references on 8-byte boundaries so they can be ! grabbed 2 words at a time on a SPARC. Tue Mar 5 10:21:01 1996 Jason Merrill diff -Nrc3pad gcc-3.2.3/gcc/cp/class.c gcc-3.3/gcc/cp/class.c *** gcc-3.2.3/gcc/cp/class.c 2003-03-24 11:33:46.000000000 +0000 --- gcc-3.3/gcc/cp/class.c 2003-04-29 21:34:49.000000000 +0000 *************** Boston, MA 02111-1307, USA. */ *** 35,44 **** #include "lex.h" #include "target.h" - #include "obstack.h" - #define obstack_chunk_alloc xmalloc - #define obstack_chunk_free free - /* The number of nested classes being processed. If we are not in the scope of any class, this is zero. */ --- 35,40 ---- *************** typedef struct vtbl_init_data_s *** 91,96 **** --- 87,95 ---- /* Nonzero if we are building the initializer for a construction vtable. */ int ctor_vtbl_p; + /* True when adding vcall offset entries to the vtable. False when + merely computing the indices. */ + bool generate_vcall_entries; } vtbl_init_data; /* The type of a function passed to walk_subobject_offsets. */ *************** varray_type local_classes; *** 107,113 **** static tree get_vfield_name PARAMS ((tree)); static void finish_struct_anon PARAMS ((tree)); - static tree build_vtable_entry PARAMS ((tree, tree, tree)); static tree get_vtable_name PARAMS ((tree)); static tree get_basefndecls PARAMS ((tree, tree)); static int build_primary_vtable PARAMS ((tree, tree)); --- 106,111 ---- *************** static void delete_duplicate_fields PARA *** 119,134 **** static void finish_struct_bits PARAMS ((tree)); static int alter_access PARAMS ((tree, tree, tree)); static void handle_using_decl PARAMS ((tree, tree)); - static int strictly_overrides PARAMS ((tree, tree)); static void check_for_override PARAMS ((tree, tree)); static tree dfs_modify_vtables PARAMS ((tree, void *)); ! static tree modify_all_vtables PARAMS ((tree, int *, tree)); ! static void determine_primary_base PARAMS ((tree, int *)); static void finish_struct_methods PARAMS ((tree)); static void maybe_warn_about_overly_private_class PARAMS ((tree)); static int field_decl_cmp PARAMS ((const tree *, const tree *)); static int method_name_cmp PARAMS ((const tree *, const tree *)); ! static tree add_implicitly_declared_members PARAMS ((tree, int, int, int)); static tree fixed_type_or_null PARAMS ((tree, int *, int *)); static tree resolve_address_of_overloaded_function PARAMS ((tree, tree, int, int, int, tree)); --- 117,131 ---- static void finish_struct_bits PARAMS ((tree)); static int alter_access PARAMS ((tree, tree, tree)); static void handle_using_decl PARAMS ((tree, tree)); static void check_for_override PARAMS ((tree, tree)); static tree dfs_modify_vtables PARAMS ((tree, void *)); ! static tree modify_all_vtables PARAMS ((tree, tree)); ! static void determine_primary_base PARAMS ((tree)); static void finish_struct_methods PARAMS ((tree)); static void maybe_warn_about_overly_private_class PARAMS ((tree)); static int field_decl_cmp PARAMS ((const tree *, const tree *)); static int method_name_cmp PARAMS ((const tree *, const tree *)); ! static void add_implicitly_declared_members PARAMS ((tree, int, int, int)); static tree fixed_type_or_null PARAMS ((tree, int *, int *)); static tree resolve_address_of_overloaded_function PARAMS ((tree, tree, int, int, int, tree)); *************** static tree build_vtbl_initializer PARAM *** 138,166 **** static int count_fields PARAMS ((tree)); static int add_fields_to_vec PARAMS ((tree, tree, int)); static void check_bitfield_decl PARAMS ((tree)); ! static void check_field_decl PARAMS ((tree, tree, int *, int *, int *, int *)); ! static void check_field_decls PARAMS ((tree, tree *, int *, int *, int *, ! int *)); ! static bool build_base_field PARAMS ((record_layout_info, tree, int *, ! splay_tree, tree)); ! static bool build_base_fields PARAMS ((record_layout_info, int *, ! splay_tree, tree)); static void check_methods PARAMS ((tree)); static void remove_zero_width_bit_fields PARAMS ((tree)); static void check_bases PARAMS ((tree, int *, int *, int *)); ! static void check_bases_and_members PARAMS ((tree, int *)); ! static tree create_vtable_ptr PARAMS ((tree, int *, int *, tree *)); ! static void layout_class_type PARAMS ((tree, int *, int *, tree *)); static void fixup_pending_inline PARAMS ((tree)); static void fixup_inline_methods PARAMS ((tree)); ! static void set_primary_base PARAMS ((tree, tree, int *)); static void propagate_binfo_offsets PARAMS ((tree, tree, tree)); ! static void layout_virtual_bases PARAMS ((tree, splay_tree)); static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *)); static void build_vbase_offset_vtbl_entries PARAMS ((tree, vtbl_init_data *)); static void add_vcall_offset_vtbl_entries_r PARAMS ((tree, vtbl_init_data *)); static void add_vcall_offset_vtbl_entries_1 PARAMS ((tree, vtbl_init_data *)); static void build_vcall_offset_vtbl_entries PARAMS ((tree, vtbl_init_data *)); static void layout_vtable_decl PARAMS ((tree, int)); static tree dfs_find_final_overrider PARAMS ((tree, void *)); static tree find_final_overrider PARAMS ((tree, tree, tree)); --- 135,162 ---- static int count_fields PARAMS ((tree)); static int add_fields_to_vec PARAMS ((tree, tree, int)); static void check_bitfield_decl PARAMS ((tree)); ! static void check_field_decl (tree, tree, int *, int *, int *, int *); ! static void check_field_decls (tree, tree *, int *, int *, int *); ! static tree *build_base_field (record_layout_info, tree, splay_tree, tree *); ! static void build_base_fields (record_layout_info, splay_tree, tree *); static void check_methods PARAMS ((tree)); static void remove_zero_width_bit_fields PARAMS ((tree)); static void check_bases PARAMS ((tree, int *, int *, int *)); ! static void check_bases_and_members (tree); ! static tree create_vtable_ptr (tree, tree *); ! static void include_empty_classes (record_layout_info); ! static void layout_class_type (tree, tree *); static void fixup_pending_inline PARAMS ((tree)); static void fixup_inline_methods PARAMS ((tree)); ! static void set_primary_base PARAMS ((tree, tree)); static void propagate_binfo_offsets PARAMS ((tree, tree, tree)); ! static void layout_virtual_bases (record_layout_info, splay_tree); static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *)); static void build_vbase_offset_vtbl_entries PARAMS ((tree, vtbl_init_data *)); static void add_vcall_offset_vtbl_entries_r PARAMS ((tree, vtbl_init_data *)); static void add_vcall_offset_vtbl_entries_1 PARAMS ((tree, vtbl_init_data *)); static void build_vcall_offset_vtbl_entries PARAMS ((tree, vtbl_init_data *)); + static void add_vcall_offset (tree, tree, vtbl_init_data *); static void layout_vtable_decl PARAMS ((tree, int)); static tree dfs_find_final_overrider PARAMS ((tree, void *)); static tree find_final_overrider PARAMS ((tree, tree, tree)); *************** static tree build_vtable PARAMS ((tree, *** 175,188 **** static void initialize_vtable PARAMS ((tree, tree)); static void initialize_array PARAMS ((tree, tree)); static void layout_nonempty_base_or_field PARAMS ((record_layout_info, ! tree, tree, ! splay_tree, tree)); ! static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int)); static bool layout_empty_base PARAMS ((tree, tree, splay_tree, tree)); static void accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree)); static tree dfs_accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree)); - static void set_vindex PARAMS ((tree, int *)); static void build_rtti_vtbl_entries PARAMS ((tree, vtbl_init_data *)); static void build_vcall_and_vbase_vtbl_entries PARAMS ((tree, vtbl_init_data *)); --- 171,182 ---- static void initialize_vtable PARAMS ((tree, tree)); static void initialize_array PARAMS ((tree, tree)); static void layout_nonempty_base_or_field PARAMS ((record_layout_info, ! tree, tree, splay_tree)); ! static tree end_of_class PARAMS ((tree, int)); static bool layout_empty_base PARAMS ((tree, tree, splay_tree, tree)); static void accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree)); static tree dfs_accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree)); static void build_rtti_vtbl_entries PARAMS ((tree, vtbl_init_data *)); static void build_vcall_and_vbase_vtbl_entries PARAMS ((tree, vtbl_init_data *)); *************** static void record_subobject_offsets PAR *** 212,219 **** static int layout_conflict_p PARAMS ((tree, tree, splay_tree, int)); static int splay_tree_compare_integer_csts PARAMS ((splay_tree_key k1, splay_tree_key k2)); ! static void warn_about_ambiguous_direct_bases PARAMS ((tree)); static bool type_requires_array_cookie PARAMS ((tree)); /* Macros for dfs walking during vtt construction. See dfs_ctor_vtable_bases_queue_p, dfs_build_secondary_vptr_vtt_inits --- 206,219 ---- static int layout_conflict_p PARAMS ((tree, tree, splay_tree, int)); static int splay_tree_compare_integer_csts PARAMS ((splay_tree_key k1, splay_tree_key k2)); ! static void warn_about_ambiguous_bases PARAMS ((tree)); static bool type_requires_array_cookie PARAMS ((tree)); + static bool contains_empty_class_p (tree); + static tree dfs_base_derived_from (tree, void *); + static bool base_derived_from (tree, tree); + static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree); + static tree end_of_base (tree); + static tree get_vcall_index (tree, tree); /* Macros for dfs walking during vtt construction. See dfs_ctor_vtable_bases_queue_p, dfs_build_secondary_vptr_vtt_inits *************** build_base_path (code, expr, binfo, nonn *** 288,300 **** return error_mark_node; } fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); if (fixed_type_p <= 0 && TREE_SIDE_EFFECTS (expr)) expr = save_expr (expr); ! if (!want_pointer) ! expr = build_unary_op (ADDR_EXPR, expr, 0); ! else if (!nonnull) null_test = build (EQ_EXPR, boolean_type_node, expr, integer_zero_node); offset = BINFO_OFFSET (binfo); --- 288,302 ---- return error_mark_node; } + if (!want_pointer) + /* This must happen before the call to save_expr. */ + expr = build_unary_op (ADDR_EXPR, expr, 0); + fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); if (fixed_type_p <= 0 && TREE_SIDE_EFFECTS (expr)) expr = save_expr (expr); ! if (want_pointer && !nonnull) null_test = build (EQ_EXPR, boolean_type_node, expr, integer_zero_node); offset = BINFO_OFFSET (binfo); *************** build_base_path (code, expr, binfo, nonn *** 304,311 **** /* Going via virtual base V_BINFO. We need the static offset from V_BINFO to BINFO, and the dynamic offset from D_BINFO to V_BINFO. That offset is an entry in D_BINFO's vtable. */ ! tree v_offset = build_vfield_ref (build_indirect_ref (expr, NULL), ! TREE_TYPE (TREE_TYPE (expr))); v_binfo = binfo_for_vbase (BINFO_TYPE (v_binfo), BINFO_TYPE (d_binfo)); --- 306,332 ---- /* Going via virtual base V_BINFO. We need the static offset from V_BINFO to BINFO, and the dynamic offset from D_BINFO to V_BINFO. That offset is an entry in D_BINFO's vtable. */ ! tree v_offset; ! ! if (fixed_type_p < 0 && in_base_initializer) ! { ! /* In a base member initializer, we cannot rely on ! the vtable being set up. We have to use the vtt_parm. */ ! tree derived = v_binfo; ! ! while (BINFO_INHERITANCE_CHAIN (derived)) ! derived = BINFO_INHERITANCE_CHAIN (derived); ! ! v_offset = build (PLUS_EXPR, TREE_TYPE (current_vtt_parm), ! current_vtt_parm, BINFO_VPTR_INDEX (derived)); ! ! v_offset = build1 (INDIRECT_REF, ! TREE_TYPE (TYPE_VFIELD (BINFO_TYPE (derived))), ! v_offset); ! } ! else ! v_offset = build_vfield_ref (build_indirect_ref (expr, NULL), ! TREE_TYPE (TREE_TYPE (expr))); v_binfo = binfo_for_vbase (BINFO_TYPE (v_binfo), BINFO_TYPE (d_binfo)); *************** build_base_path (code, expr, binfo, nonn *** 362,367 **** --- 383,406 ---- return expr; } + /* Convert OBJECT to the base TYPE. If CHECK_ACCESS is true, an error + message is emitted if TYPE is inaccessible. OBJECT is assumed to + be non-NULL. */ + + tree + convert_to_base (tree object, tree type, bool check_access) + { + tree binfo; + + binfo = lookup_base (TREE_TYPE (object), type, + check_access ? ba_check : ba_ignore, + NULL); + if (!binfo || binfo == error_mark_node) + return error_mark_node; + + return build_base_path (PLUS_EXPR, object, binfo, /*nonnull=*/1); + } + /* Virtual function things. */ *************** build_vtable (class_type, name, vtable_t *** 509,514 **** --- 548,555 ---- TREE_STATIC (decl) = 1; TREE_READONLY (decl) = 1; DECL_VIRTUAL_P (decl) = 1; + DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN; + import_export_vtable (decl, class_type, 0); return decl; *************** build_vtable (class_type, name, vtable_t *** 516,522 **** /* Get the VAR_DECL of the vtable for TYPE. TYPE need not be polymorphic, or even complete. If this does not exist, create it. If COMPLETE is ! non-zero, then complete the definition of it -- that will render it impossible to actually build the vtable, but is useful to get at those which are known to exist in the runtime. */ --- 557,563 ---- /* Get the VAR_DECL of the vtable for TYPE. TYPE need not be polymorphic, or even complete. If this does not exist, create it. If COMPLETE is ! nonzero, then complete the definition of it -- that will render it impossible to actually build the vtable, but is useful to get at those which are known to exist in the runtime. */ *************** get_vtable_decl (type, complete) *** 525,545 **** tree type; int complete; { ! tree name = get_vtable_name (type); ! tree decl = IDENTIFIER_GLOBAL_VALUE (name); ! ! if (decl) ! { ! my_friendly_assert (TREE_CODE (decl) == VAR_DECL ! && DECL_VIRTUAL_P (decl), 20000118); ! return decl; ! } ! ! decl = build_vtable (type, name, void_type_node); ! decl = pushdecl_top_level (decl); ! my_friendly_assert (IDENTIFIER_GLOBAL_VALUE (name) == decl, ! 20000517); /* At one time the vtable info was grabbed 2 words at a time. This fails on sparc unless you have 8-byte alignment. (tiemann) */ DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node), --- 566,579 ---- tree type; int complete; { ! tree decl; ! ! if (CLASSTYPE_VTABLES (type)) ! return CLASSTYPE_VTABLES (type); + decl = build_vtable (type, get_vtable_name (type), void_type_node); + CLASSTYPE_VTABLES (type) = decl; + /* At one time the vtable info was grabbed 2 words at a time. This fails on sparc unless you have 8-byte alignment. (tiemann) */ DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node), *************** copy_virtuals (binfo) *** 566,575 **** copies = copy_list (BINFO_VIRTUALS (binfo)); for (t = copies; t; t = TREE_CHAIN (t)) ! { ! BV_VCALL_INDEX (t) = NULL_TREE; ! BV_USE_VCALL_INDEX_P (t) = 0; ! } return copies; } --- 600,606 ---- copies = copy_list (BINFO_VIRTUALS (binfo)); for (t = copies; t; t = TREE_CHAIN (t)) ! BV_VCALL_INDEX (t) = NULL_TREE; return copies; } *************** copy_virtuals (binfo) *** 577,583 **** /* Build the primary virtual function table for TYPE. If BINFO is non-NULL, build the vtable starting with the initial approximation that it is the same as the one which is the head of the association ! list. Returns a non-zero value if a new vtable is actually created. */ static int --- 608,614 ---- /* Build the primary virtual function table for TYPE. If BINFO is non-NULL, build the vtable starting with the initial approximation that it is the same as the one which is the head of the association ! list. Returns a nonzero value if a new vtable is actually created. */ static int *************** build_primary_vtable (binfo, type) *** 629,635 **** FOR_TYPE is the most derived type which caused this table to be needed. ! Returns non-zero if we haven't met BINFO before. The order in which vtables are built (by calling this function) for an object must remain the same, otherwise a binary incompatibility --- 660,666 ---- FOR_TYPE is the most derived type which caused this table to be needed. ! Returns nonzero if we haven't met BINFO before. The order in which vtables are built (by calling this function) for an object must remain the same, otherwise a binary incompatibility *************** build_secondary_vtable (binfo, for_type) *** 660,666 **** } /* Create a new vtable for BINFO which is the hierarchy dominated by ! T. Return non-zero if we actually created a new vtable. */ static int make_new_vtable (t, binfo) --- 691,697 ---- } /* Create a new vtable for BINFO which is the hierarchy dominated by ! T. Return nonzero if we actually created a new vtable. */ static int make_new_vtable (t, binfo) *************** modify_vtable_entry (t, binfo, fndecl, d *** 722,758 **** BV_DELTA (v) = delta; BV_VCALL_INDEX (v) = NULL_TREE; BV_FN (v) = fndecl; - - /* Now assign virtual dispatch information, if unset. We can - dispatch this through any overridden base function. - - FIXME this can choose a secondary vtable if the primary is not - also lexically first, leading to useless conversions. - In the V3 ABI, there's no reason for DECL_VIRTUAL_CONTEXT to - ever be different from DECL_CONTEXT. */ - if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST) - { - DECL_VINDEX (fndecl) = DECL_VINDEX (base_fndecl); - DECL_VIRTUAL_CONTEXT (fndecl) = DECL_VIRTUAL_CONTEXT (base_fndecl); - } } } - /* Set DECL_VINDEX for DECL. VINDEX_P is the number of virtual - functions present in the vtable so far. */ - - static void - set_vindex (decl, vfuns_p) - tree decl; - int *vfuns_p; - { - int vindex; - - vindex = *vfuns_p; - *vfuns_p += (TARGET_VTABLE_USES_DESCRIPTORS - ? TARGET_VTABLE_USES_DESCRIPTORS : 1); - DECL_VINDEX (decl) = build_shared_int_cst (vindex); - } /* Add method METHOD to class TYPE. If ERROR_P is true, we are adding the method after the class has already been defined because a --- 753,761 ---- *************** add_method (type, method, error_p) *** 769,774 **** --- 772,779 ---- int len; int slot; tree method_vec; + int template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL + && DECL_TEMPLATE_CONV_FN_P (method)); if (!CLASSTYPE_METHOD_VEC (type)) /* Make a new method vector. We start with 8 entries. We must *************** add_method (type, method, error_p) *** 793,806 **** slot = CLASSTYPE_DESTRUCTOR_SLOT; else { /* See if we already have an entry with this name. */ for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT; slot < len; ++slot) ! if (!TREE_VEC_ELT (method_vec, slot) ! || (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, ! slot))) ! == DECL_NAME (method))) ! break; ! if (slot == len) { /* We need a bigger method vector. */ --- 798,833 ---- slot = CLASSTYPE_DESTRUCTOR_SLOT; else { + int have_template_convs_p = 0; + /* See if we already have an entry with this name. */ for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT; slot < len; ++slot) ! { ! tree m = TREE_VEC_ELT (method_vec, slot); ! ! if (!m) ! break; ! m = OVL_CURRENT (m); ! ! if (template_conv_p) ! { ! have_template_convs_p = (TREE_CODE (m) == TEMPLATE_DECL ! && DECL_TEMPLATE_CONV_FN_P (m)); ! ! /* If we need to move things up, see if there's ! space. */ ! if (!have_template_convs_p) ! { ! slot = len - 1; ! if (TREE_VEC_ELT (method_vec, slot)) ! slot++; ! } ! break; ! } ! if (DECL_NAME (m) == DECL_NAME (method)) ! break; ! } ! if (slot == len) { /* We need a bigger method vector. */ *************** add_method (type, method, error_p) *** 833,854 **** slide some of the vector elements up. In theory, this makes this algorithm O(N^2) but we don't expect many conversion operators. */ ! for (slot = 2; slot < len; ++slot) ! { ! tree fn = TREE_VEC_ELT (method_vec, slot); ! if (!fn) ! /* There are no more entries in the vector, so we ! can insert the new conversion operator here. */ ! break; ! if (!DECL_CONV_FN_P (OVL_CURRENT (fn))) ! /* We can insert the new function right at the ! SLOTth position. */ ! break; ! } ! ! if (!TREE_VEC_ELT (method_vec, slot)) /* There is nothing in the Ith slot, so we can avoid moving anything. */ ; --- 860,886 ---- slide some of the vector elements up. In theory, this makes this algorithm O(N^2) but we don't expect many conversion operators. */ ! if (template_conv_p) ! slot = CLASSTYPE_FIRST_CONVERSION_SLOT; ! else ! for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT; slot < len; ++slot) ! { ! tree fn = TREE_VEC_ELT (method_vec, slot); ! if (!fn) ! /* There are no more entries in the vector, so we ! can insert the new conversion operator here. */ ! break; ! if (!DECL_CONV_FN_P (OVL_CURRENT (fn))) ! /* We can insert the new function right at the ! SLOTth position. */ ! break; ! } ! ! if (template_conv_p && have_template_convs_p) ! /*OK*/; ! else if (!TREE_VEC_ELT (method_vec, slot)) /* There is nothing in the Ith slot, so we can avoid moving anything. */ ; *************** add_method (type, method, error_p) *** 947,953 **** TREE_VEC_ELT (method_vec, slot) = build_overload (method, TREE_VEC_ELT (method_vec, slot)); ! /* Add the new binding. */ if (!DECL_CONSTRUCTOR_P (method) && !DECL_DESTRUCTOR_P (method)) push_class_level_binding (DECL_NAME (method), --- 979,985 ---- TREE_VEC_ELT (method_vec, slot) = build_overload (method, TREE_VEC_ELT (method_vec, slot)); ! /* Add the new binding. */ if (!DECL_CONSTRUCTOR_P (method) && !DECL_DESTRUCTOR_P (method)) push_class_level_binding (DECL_NAME (method), *************** handle_using_decl (using_decl, t) *** 1126,1139 **** return; } ! if (name == constructor_name (ctype) ! || name == constructor_name_full (ctype)) { cp_error_at ("`%D' names constructor", using_decl); return; } ! if (name == constructor_name (t) ! || name == constructor_name_full (t)) { cp_error_at ("`%D' invalid in `%T'", using_decl, t); return; --- 1158,1169 ---- return; } ! if (constructor_name_p (name, ctype)) { cp_error_at ("`%D' names constructor", using_decl); return; } ! if (constructor_name_p (name, t)) { cp_error_at ("`%D' invalid in `%T'", using_decl, t); return; *************** handle_using_decl (using_decl, t) *** 1148,1155 **** } if (BASELINK_P (fdecl)) ! /* Ignore base type this came from. */ ! fdecl = TREE_VALUE (fdecl); old_value = IDENTIFIER_CLASS_VALUE (name); if (old_value) --- 1178,1185 ---- } if (BASELINK_P (fdecl)) ! /* Ignore base type this came from. */ ! fdecl = BASELINK_FUNCTIONS (fdecl); old_value = IDENTIFIER_CLASS_VALUE (name); if (old_value) *************** check_bases (t, cant_have_default_ctor_p *** 1281,1287 **** } if (TREE_VIA_VIRTUAL (base_binfo)) ! /* A virtual base does not effect nearly emptiness. */ ; else if (CLASSTYPE_NEARLY_EMPTY_P (basetype)) { --- 1311,1317 ---- } if (TREE_VIA_VIRTUAL (base_binfo)) ! /* A virtual base does not effect nearly emptiness. */ ; else if (CLASSTYPE_NEARLY_EMPTY_P (basetype)) { *************** check_bases (t, cant_have_default_ctor_p *** 1290,1296 **** derived class is not nearly empty either. */ CLASSTYPE_NEARLY_EMPTY_P (t) = 0; else ! /* Remember we've seen one. */ seen_non_virtual_nearly_empty_base_p = 1; } else if (!is_empty_class (basetype)) --- 1320,1326 ---- derived class is not nearly empty either. */ CLASSTYPE_NEARLY_EMPTY_P (t) = 0; else ! /* Remember we've seen one. */ seen_non_virtual_nearly_empty_base_p = 1; } else if (!is_empty_class (basetype)) *************** mark_primary_virtual_base (base_binfo, t *** 1439,1445 **** /* If BINFO is an unmarked virtual binfo for a class with a primary virtual base, then BINFO has no primary base in this graph. Called from ! mark_primary_bases. DATA is the most derived type. */ static tree dfs_unshared_virtual_bases (binfo, data) tree binfo; --- 1469,1475 ---- /* If BINFO is an unmarked virtual binfo for a class with a primary virtual base, then BINFO has no primary base in this graph. Called from ! mark_primary_bases. DATA is the most derived type. */ static tree dfs_unshared_virtual_bases (binfo, data) tree binfo; *************** static tree dfs_unshared_virtual_bases ( *** 1472,1482 **** if (binfo != TYPE_BINFO (t)) /* The vtable fields will have been copied when duplicating the base binfos. That information is bogus, make sure we don't try ! and use it. */ BINFO_VTABLE (binfo) = NULL_TREE; /* If this is a virtual primary base, make sure its offset matches ! that which it is primary for. */ if (BINFO_PRIMARY_P (binfo) && TREE_VIA_VIRTUAL (binfo) && binfo_for_vbase (BINFO_TYPE (binfo), t) == binfo) { --- 1502,1512 ---- if (binfo != TYPE_BINFO (t)) /* The vtable fields will have been copied when duplicating the base binfos. That information is bogus, make sure we don't try ! and use it. */ BINFO_VTABLE (binfo) = NULL_TREE; /* If this is a virtual primary base, make sure its offset matches ! that which it is primary for. */ if (BINFO_PRIMARY_P (binfo) && TREE_VIA_VIRTUAL (binfo) && binfo_for_vbase (BINFO_TYPE (binfo), t) == binfo) { *************** mark_primary_bases (type) *** 1505,1511 **** tree base_binfo; if (!CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo))) ! /* Not a dynamic base. */ continue; base_binfo = get_primary_binfo (binfo); --- 1535,1541 ---- tree base_binfo; if (!CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo))) ! /* Not a dynamic base. */ continue; base_binfo = get_primary_binfo (binfo); *************** mark_primary_bases (type) *** 1534,1543 **** /* Make the BINFO the primary base of T. */ static void ! set_primary_base (t, binfo, vfuns_p) tree t; tree binfo; - int *vfuns_p; { tree basetype; --- 1564,1572 ---- /* Make the BINFO the primary base of T. */ static void ! set_primary_base (t, binfo) tree t; tree binfo; { tree basetype; *************** set_primary_base (t, binfo, vfuns_p) *** 1546,1561 **** TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype); TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype); TYPE_VFIELD (t) = TYPE_VFIELD (basetype); - CLASSTYPE_RTTI (t) = CLASSTYPE_RTTI (basetype); - *vfuns_p = CLASSTYPE_VSIZE (basetype); } /* Determine the primary class for T. */ static void ! determine_primary_base (t, vfuns_p) tree t; - int *vfuns_p; { int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); tree vbases; --- 1575,1587 ---- TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype); TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype); TYPE_VFIELD (t) = TYPE_VFIELD (basetype); } /* Determine the primary class for T. */ static void ! determine_primary_base (t) tree t; { int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); tree vbases; *************** determine_primary_base (t, vfuns_p) *** 1574,1585 **** if (TYPE_CONTAINS_VPTR_P (basetype)) { - /* Even a virtual baseclass can contain our RTTI - information. But, we prefer a non-virtual polymorphic - baseclass. */ - if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t)) - CLASSTYPE_RTTI (t) = CLASSTYPE_RTTI (basetype); - /* We prefer a non-virtual base, although a virtual one will do. */ if (TREE_VIA_VIRTUAL (base_binfo)) --- 1600,1605 ---- *************** determine_primary_base (t, vfuns_p) *** 1587,1593 **** if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t)) { ! set_primary_base (t, base_binfo, vfuns_p); CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype)); } else --- 1607,1613 ---- if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t)) { ! set_primary_base (t, base_binfo); CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype)); } else *************** determine_primary_base (t, vfuns_p) *** 1689,1695 **** /* If we've got a primary base, use it. */ if (candidate) { ! set_primary_base (t, candidate, vfuns_p); CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (BINFO_TYPE (candidate))); } --- 1709,1715 ---- /* If we've got a primary base, use it. */ if (candidate) { ! set_primary_base (t, candidate); CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (BINFO_TYPE (candidate))); } *************** maybe_warn_about_overly_private_class (t *** 1833,1839 **** return; has_nonprivate_method = 1; ! break; } else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn)) has_member_fn = 1; --- 1853,1859 ---- return; has_nonprivate_method = 1; ! /* Keep searching for a static member function. */ } else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn)) has_member_fn = 1; *************** duplicate_tag_error (t) *** 2075,2086 **** --- 2095,2108 ---- memset ((char *) TYPE_LANG_SPECIFIC (t), 0, sizeof (struct lang_type)); BINFO_BASETYPES(binfo) = NULL_TREE; + TYPE_LANG_SPECIFIC (t)->u.h.is_lang_type_class = 1; TYPE_BINFO (t) = binfo; CLASSTYPE_INTERFACE_ONLY (t) = interface_only; SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); TYPE_REDEFINED (t) = 1; CLASSTYPE_TEMPLATE_INFO (t) = template_info; CLASSTYPE_USE_TEMPLATE (t) = use_template; + CLASSTYPE_DECL_LIST (t) = NULL_TREE; } TYPE_SIZE (t) = NULL_TREE; TYPE_MODE (t) = VOIDmode; *************** layout_vtable_decl (binfo, n) *** 2126,2132 **** layout_decl (vtable, 0); /* At one time the vtable info was grabbed 2 words at a time. This ! fails on Sparc unless you have 8-byte alignment. */ DECL_ALIGN (vtable) = MAX (TYPE_ALIGN (double_type_node), DECL_ALIGN (vtable)); } --- 2148,2154 ---- layout_decl (vtable, 0); /* At one time the vtable info was grabbed 2 words at a time. This ! fails on SPARC unless you have 8-byte alignment. */ DECL_ALIGN (vtable) = MAX (TYPE_ALIGN (double_type_node), DECL_ALIGN (vtable)); } *************** same_signature_p (fndecl, base_fndecl) *** 2164,2169 **** --- 2186,2214 ---- return 0; } + /* Called from base_derived_from via dfs_walk. */ + + static tree + dfs_base_derived_from (tree binfo, void *data) + { + tree base = (tree) data; + + if (same_type_p (TREE_TYPE (base), TREE_TYPE (binfo)) + && tree_int_cst_equal (BINFO_OFFSET (base), BINFO_OFFSET (binfo))) + return error_mark_node; + + return NULL_TREE; + } + + /* Returns TRUE if DERIVED is a binfo containing the binfo BASE as a + subobject. */ + + static bool + base_derived_from (tree derived, tree base) + { + return dfs_walk (derived, dfs_base_derived_from, NULL, base) != NULL_TREE; + } + typedef struct find_final_overrider_data_s { /* The function for which we are trying to find a final overrider. */ tree fn; *************** typedef struct find_final_overrider_data *** 2171,2184 **** tree declaring_base; /* The most derived class in the hierarchy. */ tree most_derived_type; ! /* The final overriding function. */ ! tree overriding_fn; ! /* The functions that we thought might be final overriders, but ! aren't. */ tree candidates; - /* The BINFO for the class in which the final overriding function - appears. */ - tree overriding_base; } find_final_overrider_data; /* Called from find_final_overrider via dfs_walk. */ --- 2216,2223 ---- tree declaring_base; /* The most derived class in the hierarchy. */ tree most_derived_type; ! /* The candidate overriders. */ tree candidates; } find_final_overrider_data; /* Called from find_final_overrider via dfs_walk. */ *************** dfs_find_final_overrider (binfo, data) *** 2202,2320 **** method = NULL_TREE; /* We've found a path to the declaring base. Walk down the path looking for an overrider for FN. */ ! for (path = reverse_path (binfo); ! path; ! path = TREE_CHAIN (path)) { method = look_for_overrides_here (BINFO_TYPE (TREE_VALUE (path)), ffod->fn); if (method) ! break; } /* If we found an overrider, record the overriding function, and the base from which it came. */ if (path) { ! tree base; ! ! /* Assume the path is non-virtual. See if there are any ! virtual bases from (but not including) the overrider up ! to and including the base where the function is ! defined. */ ! for (base = TREE_CHAIN (path); base; base = TREE_CHAIN (base)) ! if (TREE_VIA_VIRTUAL (TREE_VALUE (base))) ! { ! base = ffod->declaring_base; ! break; ! } ! /* If we didn't already have an overrider, or any ! candidates, then this function is the best candidate so ! far. */ ! if (!ffod->overriding_fn && !ffod->candidates) ! { ! ffod->overriding_fn = method; ! ffod->overriding_base = TREE_VALUE (path); ! } ! else if (ffod->overriding_fn) { ! /* We had a best overrider; let's see how this compares. */ ! ! if (ffod->overriding_fn == method ! && (tree_int_cst_equal ! (BINFO_OFFSET (TREE_VALUE (path)), ! BINFO_OFFSET (ffod->overriding_base)))) ! /* We found the same overrider we already have, and in the ! same place; it's still the best. */; ! else if (strictly_overrides (ffod->overriding_fn, method)) ! /* The old function overrides this function; it's still the ! best. */; ! else if (strictly_overrides (method, ffod->overriding_fn)) ! { ! /* The new function overrides the old; it's now the ! best. */ ! ffod->overriding_fn = method; ! ffod->overriding_base = TREE_VALUE (path); ! } else ! { ! /* Ambiguous. */ ! ffod->candidates ! = build_tree_list (NULL_TREE, ! ffod->overriding_fn); ! if (method != ffod->overriding_fn) ! ffod->candidates ! = tree_cons (NULL_TREE, method, ffod->candidates); ! ffod->overriding_fn = NULL_TREE; ! ffod->overriding_base = NULL_TREE; ! } } - else - { - /* We had a list of ambiguous overrides; let's see how this - new one compares. */ - - tree candidates; - bool incomparable = false; - - /* If there were previous candidates, and this function - overrides all of them, then it is the new best - candidate. */ - for (candidates = ffod->candidates; - candidates; - candidates = TREE_CHAIN (candidates)) - { - /* If the candidate overrides the METHOD, then we - needn't worry about it any further. */ - if (strictly_overrides (TREE_VALUE (candidates), - method)) - { - method = NULL_TREE; - break; - } ! /* If the METHOD doesn't override the candidate, ! then it is incomporable. */ ! if (!strictly_overrides (method, ! TREE_VALUE (candidates))) ! incomparable = true; ! } ! ! /* If METHOD overrode all the candidates, then it is the ! new best candidate. */ ! if (!candidates && !incomparable) ! { ! ffod->overriding_fn = method; ! ffod->overriding_base = TREE_VALUE (path); ! ffod->candidates = NULL_TREE; ! } ! /* If METHOD didn't override all the candidates, then it ! is another candidate. */ ! else if (method && incomparable) ! ffod->candidates ! = tree_cons (NULL_TREE, method, ffod->candidates); ! } } } --- 2241,2286 ---- method = NULL_TREE; /* We've found a path to the declaring base. Walk down the path looking for an overrider for FN. */ ! path = reverse_path (binfo); ! while (!same_type_p (BINFO_TYPE (TREE_VALUE (path)), ! ffod->most_derived_type)) ! path = TREE_CHAIN (path); ! while (path) { method = look_for_overrides_here (BINFO_TYPE (TREE_VALUE (path)), ffod->fn); if (method) ! { ! path = TREE_VALUE (path); ! break; ! } ! ! path = TREE_CHAIN (path); } /* If we found an overrider, record the overriding function, and the base from which it came. */ if (path) { ! tree *candidate; ! /* Remove any candidates overridden by this new function. */ ! candidate = &ffod->candidates; ! while (*candidate) { ! /* If *CANDIDATE overrides METHOD, then METHOD ! cannot override anything else on the list. */ ! if (base_derived_from (TREE_VALUE (*candidate), path)) ! return NULL_TREE; ! /* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */ ! if (base_derived_from (path, TREE_VALUE (*candidate))) ! *candidate = TREE_CHAIN (*candidate); else ! candidate = &TREE_CHAIN (*candidate); } ! /* Add the new function. */ ! ffod->candidates = tree_cons (method, path, ffod->candidates); } } *************** dfs_find_final_overrider (binfo, data) *** 2323,2340 **** /* Returns a TREE_LIST whose TREE_PURPOSE is the final overrider for FN and whose TREE_VALUE is the binfo for the base where the ! overriding occurs. BINFO (in the hierarchy dominated by T) is the ! base object in which FN is declared. */ static tree ! find_final_overrider (t, binfo, fn) ! tree t; tree binfo; tree fn; { find_final_overrider_data ffod; ! /* Getting this right is a little tricky. This is legal: struct S { virtual void f (); }; struct T { virtual void f (); }; --- 2289,2306 ---- /* Returns a TREE_LIST whose TREE_PURPOSE is the final overrider for FN and whose TREE_VALUE is the binfo for the base where the ! overriding occurs. BINFO (in the hierarchy dominated by the binfo ! DERIVED) is the base object in which FN is declared. */ static tree ! find_final_overrider (derived, binfo, fn) ! tree derived; tree binfo; tree fn; { find_final_overrider_data ffod; ! /* Getting this right is a little tricky. This is valid: struct S { virtual void f (); }; struct T { virtual void f (); }; *************** find_final_overrider (t, binfo, fn) *** 2354,2394 **** different overriders along any two, then there is a problem. */ ffod.fn = fn; ffod.declaring_base = binfo; ! ffod.most_derived_type = t; ! ffod.overriding_fn = NULL_TREE; ! ffod.overriding_base = NULL_TREE; ffod.candidates = NULL_TREE; ! dfs_walk (TYPE_BINFO (t), dfs_find_final_overrider, NULL, &ffod); /* If there was no winner, issue an error message. */ ! if (!ffod.overriding_fn) { ! error ("no unique final overrider for `%D' in `%T'", fn, t); return error_mark_node; } ! return build_tree_list (ffod.overriding_fn, ffod.overriding_base); } ! /* Returns the function from the BINFO_VIRTUALS entry in T which matches ! the signature of FUNCTION_DECL FN, or NULL_TREE if none. In other words, ! the function that the slot in T's primary vtable points to. */ - static tree get_matching_virtual PARAMS ((tree, tree)); static tree ! get_matching_virtual (t, fn) ! tree t, fn; { ! tree f; ! for (f = BINFO_VIRTUALS (TYPE_BINFO (t)); f; f = TREE_CHAIN (f)) ! if (same_signature_p (BV_FN (f), fn)) ! return BV_FN (f); ! return NULL_TREE; } /* Update an entry in the vtable for BINFO, which is in the hierarchy --- 2320,2361 ---- different overriders along any two, then there is a problem. */ ffod.fn = fn; ffod.declaring_base = binfo; ! ffod.most_derived_type = BINFO_TYPE (derived); ffod.candidates = NULL_TREE; ! dfs_walk (derived, dfs_find_final_overrider, NULL, &ffod); /* If there was no winner, issue an error message. */ ! if (!ffod.candidates || TREE_CHAIN (ffod.candidates)) { ! error ("no unique final overrider for `%D' in `%T'", fn, ! BINFO_TYPE (derived)); return error_mark_node; } ! return ffod.candidates; } ! /* Return the index of the vcall offset for FN when TYPE is used as a ! virtual base. */ static tree ! get_vcall_index (tree fn, tree type) { ! tree v; ! for (v = CLASSTYPE_VCALL_INDICES (type); v; v = TREE_CHAIN (v)) ! if ((DECL_DESTRUCTOR_P (fn) && DECL_DESTRUCTOR_P (TREE_PURPOSE (v))) ! || same_signature_p (fn, TREE_PURPOSE (v))) ! break; ! ! /* There should always be an appropriate index. */ ! my_friendly_assert (v, 20021103); ! ! return TREE_VALUE (v); } /* Update an entry in the vtable for BINFO, which is in the hierarchy *************** update_vtable_entry_for_fn (t, binfo, fn *** 2424,2430 **** first_defn = b; /* Find the final overrider. */ ! overrider = find_final_overrider (t, b, fn); if (overrider == error_mark_node) return; --- 2391,2397 ---- first_defn = b; /* Find the final overrider. */ ! overrider = find_final_overrider (TYPE_BINFO (t), b, fn); if (overrider == error_mark_node) return; *************** update_vtable_entry_for_fn (t, binfo, fn *** 2456,2462 **** /* Compute the constant adjustment to the `this' pointer. The `this' pointer, when this function is called, will point at BINFO (or one of its primary bases, which are at the same offset). */ - if (virtual_base) /* The `this' pointer needs to be adjusted from the declaration to the nearest virtual base. */ --- 2423,2428 ---- *************** update_vtable_entry_for_fn (t, binfo, fn *** 2469,2504 **** will be zero, as it will be a primary base. */ delta = size_zero_node; else ! { ! /* The `this' pointer needs to be adjusted from pointing to ! BINFO to pointing at the base where the final overrider ! appears. */ ! delta = size_diffop (BINFO_OFFSET (TREE_VALUE (overrider)), ! BINFO_OFFSET (binfo)); ! ! if (! integer_zerop (delta)) ! { ! /* We'll need a thunk. But if we have a (perhaps formerly) ! primary virtual base, we have a vcall slot for this function, ! so we can use it rather than create a non-virtual thunk. */ ! ! b = get_primary_binfo (first_defn); ! for (; b; b = get_primary_binfo (b)) ! { ! tree f = get_matching_virtual (BINFO_TYPE (b), fn); ! if (!f) ! /* b doesn't have this function; no suitable vbase. */ ! break; ! if (TREE_VIA_VIRTUAL (b)) ! { ! /* Found one; we can treat ourselves as a virtual base. */ ! virtual_base = binfo; ! delta = size_zero_node; ! break; ! } ! } ! } ! } modify_vtable_entry (t, binfo, --- 2435,2445 ---- will be zero, as it will be a primary base. */ delta = size_zero_node; else ! /* The `this' pointer needs to be adjusted from pointing to ! BINFO to pointing at the base where the final overrider ! appears. */ ! delta = size_diffop (BINFO_OFFSET (TREE_VALUE (overrider)), ! BINFO_OFFSET (binfo)); modify_vtable_entry (t, binfo, *************** update_vtable_entry_for_fn (t, binfo, fn *** 2507,2513 **** virtuals); if (virtual_base) ! BV_USE_VCALL_INDEX_P (*virtuals) = 1; } /* Called from modify_all_vtables via dfs_walk. */ --- 2448,2456 ---- virtuals); if (virtual_base) ! BV_VCALL_INDEX (*virtuals) ! = get_vcall_index (TREE_PURPOSE (overrider), ! BINFO_TYPE (virtual_base)); } /* Called from modify_all_vtables via dfs_walk. */ *************** dfs_modify_vtables (binfo, data) *** 2562,2570 **** should therefore be appended to the end of the vtable for T. */ static tree ! modify_all_vtables (t, vfuns_p, virtuals) tree t; - int *vfuns_p; tree virtuals; { tree binfo = TYPE_BINFO (t); --- 2505,2512 ---- should therefore be appended to the end of the vtable for T. */ static tree ! modify_all_vtables (t, virtuals) tree t; tree virtuals; { tree binfo = TYPE_BINFO (t); *************** modify_all_vtables (t, vfuns_p, virtuals *** 2588,2599 **** if (!value_member (fn, BINFO_VIRTUALS (binfo)) || DECL_VINDEX (fn) == error_mark_node) { - /* Set the vtable index. */ - set_vindex (fn, vfuns_p); - /* We don't need to convert to a base class when calling - this function. */ - DECL_VIRTUAL_CONTEXT (fn) = t; - /* We don't need to adjust the `this' pointer when calling this function. */ BV_DELTA (*fnsp) = integer_zero_node; --- 2530,2535 ---- *************** modify_all_vtables (t, vfuns_p, virtuals *** 2606,2631 **** /* We've already got an entry for this function. Skip it. */ *fnsp = TREE_CHAIN (*fnsp); } - - return virtuals; - } ! /* Here, we already know that they match in every respect. ! All we have to check is where they had their declarations. ! ! Return non-zero iff FNDECL1 is declared in a class which has a ! proper base class containing FNDECL2. We don't care about ! ambiguity or accessibility. */ ! ! static int ! strictly_overrides (fndecl1, fndecl2) ! tree fndecl1, fndecl2; ! { ! base_kind kind; ! ! return (lookup_base (DECL_CONTEXT (fndecl1), DECL_CONTEXT (fndecl2), ! ba_ignore | ba_quiet, &kind) ! && kind != bk_same_type); } /* Get the base virtual function declarations in T that have the --- 2542,2549 ---- /* We've already got an entry for this function. Skip it. */ *fnsp = TREE_CHAIN (*fnsp); } ! return virtuals; } /* Get the base virtual function declarations in T that have the *************** get_basefndecls (name, t) *** 2640,2650 **** int n_baseclasses = CLASSTYPE_N_BASECLASSES (t); int i; ! for (methods = TYPE_METHODS (t); methods; methods = TREE_CHAIN (methods)) ! if (TREE_CODE (methods) == FUNCTION_DECL ! && DECL_VINDEX (methods) != NULL_TREE ! && DECL_NAME (methods) == name) ! base_fndecls = tree_cons (NULL_TREE, methods, base_fndecls); if (base_fndecls) return base_fndecls; --- 2558,2576 ---- int n_baseclasses = CLASSTYPE_N_BASECLASSES (t); int i; ! /* Find virtual functions in T with the indicated NAME. */ ! i = lookup_fnfields_1 (t, name); ! if (i != -1) ! for (methods = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), i); ! methods; ! methods = OVL_NEXT (methods)) ! { ! tree method = OVL_CURRENT (methods); ! ! if (TREE_CODE (method) == FUNCTION_DECL ! && DECL_VINDEX (method)) ! base_fndecls = tree_cons (NULL_TREE, method, base_fndecls); ! } if (base_fndecls) return base_fndecls; *************** warn_hidden (t) *** 2724,2734 **** base_fndecls); } ! /* If there are no functions to hide, continue. */ if (!base_fndecls) continue; ! /* Remove any overridden functions. */ for (fns = TREE_VEC_ELT (method_vec, i); fns; fns = OVL_NEXT (fns)) { fndecl = OVL_CURRENT (fns); --- 2650,2660 ---- base_fndecls); } ! /* If there are no functions to hide, continue. */ if (!base_fndecls) continue; ! /* Remove any overridden functions. */ for (fns = TREE_VEC_ELT (method_vec, i); fns; fns = OVL_NEXT (fns)) { fndecl = OVL_CURRENT (fns); *************** finish_struct_anon (t) *** 2819,2824 **** --- 2745,2773 ---- } } + /* Add T to CLASSTYPE_DECL_LIST of current_class_type which + will be used later during class template instantiation. + When FRIEND_P is zero, T can be a static member data (VAR_DECL), + a non-static member data (FIELD_DECL), a member function + (FUNCTION_DECL), a nested type (RECORD_TYPE, ENUM_TYPE), + a typedef (TYPE_DECL) or a member class template (TEMPLATE_DECL) + When FRIEND_P is nonzero, T is either a friend class + (RECORD_TYPE, TEMPLATE_DECL) or a friend function + (FUNCTION_DECL, TEMPLATE_DECL). */ + + void + maybe_add_class_template_decl_list (type, t, friend_p) + tree type; + tree t; + int friend_p; + { + /* Save some memory by not creating TREE_LIST if TYPE is not template. */ + if (CLASSTYPE_TEMPLATE_INFO (type)) + CLASSTYPE_DECL_LIST (type) + = tree_cons (friend_p ? NULL_TREE : type, + t, CLASSTYPE_DECL_LIST (type)); + } + /* Create default constructors, assignment operators, and so forth for the type indicated by T, if they are needed. CANT_HAVE_DEFAULT_CTOR, CANT_HAVE_CONST_CTOR, and *************** finish_struct_anon (t) *** 2828,2834 **** reference, respectively. If a virtual destructor is created, its DECL is returned; otherwise the return value is NULL_TREE. */ ! static tree add_implicitly_declared_members (t, cant_have_default_ctor, cant_have_const_cctor, cant_have_const_assignment) --- 2777,2783 ---- reference, respectively. If a virtual destructor is created, its DECL is returned; otherwise the return value is NULL_TREE. */ ! static void add_implicitly_declared_members (t, cant_have_default_ctor, cant_have_const_cctor, cant_have_const_assignment) *************** add_implicitly_declared_members (t, cant *** 2899,2911 **** /* Now, hook all of the new functions on to TYPE_METHODS, and add them to the CLASSTYPE_METHOD_VEC. */ for (f = &implicit_fns; *f; f = &TREE_CHAIN (*f)) ! add_method (t, *f, /*error_p=*/0); ! *f = TYPE_METHODS (t); ! TYPE_METHODS (t) = implicit_fns; --adding_implicit_members; - - return virtual_dtor; } /* Subroutine of finish_struct_1. Recursively count the number of fields --- 2848,2874 ---- /* Now, hook all of the new functions on to TYPE_METHODS, and add them to the CLASSTYPE_METHOD_VEC. */ for (f = &implicit_fns; *f; f = &TREE_CHAIN (*f)) ! { ! add_method (t, *f, /*error_p=*/0); ! maybe_add_class_template_decl_list (current_class_type, *f, /*friend_p=*/0); ! } ! if (abi_version_at_least (2)) ! /* G++ 3.2 put the implicit destructor at the *beginning* of the ! list, which cause the destructor to be emitted in an incorrect ! location in the vtable. */ ! TYPE_METHODS (t) = chainon (TYPE_METHODS (t), implicit_fns); ! else ! { ! if (warn_abi && virtual_dtor) ! warning ("vtable layout for class `%T' may not be ABI-compliant " ! "and may change in a future version of GCC due to implicit " ! "virtual destructor", ! t); ! *f = TYPE_METHODS (t); ! TYPE_METHODS (t) = implicit_fns; ! } --adding_implicit_members; } /* Subroutine of finish_struct_1. Recursively count the number of fields *************** check_field_decl (field, t, cant_have_co *** 3127,3141 **** cp_error_at ("multiple fields in union `%T' initialized"); *any_default_members = 1; } - - /* Non-bit-fields are aligned for their type, except packed fields - which require only BITS_PER_UNIT alignment. */ - DECL_ALIGN (field) = MAX (DECL_ALIGN (field), - (DECL_PACKED (field) - ? BITS_PER_UNIT - : TYPE_ALIGN (TREE_TYPE (field)))); - if (! DECL_PACKED (field)) - DECL_USER_ALIGN (field) |= TYPE_USER_ALIGN (TREE_TYPE (field)); } /* Check the data members (both static and non-static), class-scoped --- 3090,3095 ---- *************** check_field_decl (field, t, cant_have_co *** 3168,3182 **** fields can be added by adding to this chain. */ static void ! check_field_decls (t, access_decls, empty_p, ! cant_have_default_ctor_p, cant_have_const_ctor_p, ! no_const_asn_ref_p) ! tree t; ! tree *access_decls; ! int *empty_p; ! int *cant_have_default_ctor_p; ! int *cant_have_const_ctor_p; ! int *no_const_asn_ref_p; { tree *field; tree *next; --- 3122,3131 ---- fields can be added by adding to this chain. */ static void ! check_field_decls (tree t, tree *access_decls, ! int *cant_have_default_ctor_p, ! int *cant_have_const_ctor_p, ! int *no_const_asn_ref_p) { tree *field; tree *next; *************** check_field_decls (t, access_decls, empt *** 3214,3225 **** tree element_type; /* The class is non-empty. */ ! *empty_p = 0; /* The class is not even nearly empty. */ CLASSTYPE_NEARLY_EMPTY_P (t) = 0; /* If one of the data members contains an empty class, so does T. */ ! element_type = strip_array_types (type); if (CLASS_TYPE_P (element_type) && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type)) CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1; --- 3163,3174 ---- tree element_type; /* The class is non-empty. */ ! CLASSTYPE_EMPTY_P (t) = 0; /* The class is not even nearly empty. */ CLASSTYPE_NEARLY_EMPTY_P (t) = 0; /* If one of the data members contains an empty class, so does T. */ ! element_type = strip_array_types (type); if (CLASS_TYPE_P (element_type) && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type)) CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1; *************** check_field_decls (t, access_decls, empt *** 3313,3319 **** *cant_have_default_ctor_p = 1; TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1; ! if (! TYPE_HAS_CONSTRUCTOR (t) && extra_warnings) cp_warning_at ("non-static reference `%#D' in class without a constructor", x); } --- 3262,3269 ---- *cant_have_default_ctor_p = 1; TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1; ! if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t) ! && extra_warnings) cp_warning_at ("non-static reference `%#D' in class without a constructor", x); } *************** check_field_decls (t, access_decls, empt *** 3347,3353 **** *cant_have_default_ctor_p = 1; TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1; ! if (! TYPE_HAS_CONSTRUCTOR (t) && extra_warnings) cp_warning_at ("non-static const member `%#D' in class without a constructor", x); } /* A field that is pseudo-const makes the structure likewise. */ --- 3297,3304 ---- *cant_have_default_ctor_p = 1; TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1; ! if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t) ! && extra_warnings) cp_warning_at ("non-static const member `%#D' in class without a constructor", x); } /* A field that is pseudo-const makes the structure likewise. */ *************** record_subobject_offset (type, offset, o *** 3431,3437 **** return 0; } ! /* Returns non-zero if TYPE is an empty class type and there is already an entry in OFFSETS for the same TYPE as the same OFFSET. */ static int --- 3382,3388 ---- return 0; } ! /* Returns nonzero if TYPE is an empty class type and there is already an entry in OFFSETS for the same TYPE as the same OFFSET. */ static int *************** check_subobject_offset (type, offset, of *** 3460,3472 **** /* Walk through all the subobjects of TYPE (located at OFFSET). Call F for every subobject, passing it the type, offset, and table of ! OFFSETS. If VBASES_P is non-zero, then even virtual non-primary ! bases should be traversed; otherwise, they are ignored. If MAX_OFFSET is non-NULL, then subobjects with an offset greater than MAX_OFFSET will not be walked. ! If F returns a non-zero value, the traversal ceases, and that value is returned. Otherwise, returns zero. */ static int --- 3411,3423 ---- /* Walk through all the subobjects of TYPE (located at OFFSET). Call F for every subobject, passing it the type, offset, and table of ! OFFSETS. If VBASES_P is one, then virtual non-primary bases should ! be traversed. If MAX_OFFSET is non-NULL, then subobjects with an offset greater than MAX_OFFSET will not be walked. ! If F returns a nonzero value, the traversal ceases, and that value is returned. Otherwise, returns zero. */ static int *************** walk_subobject_offsets (type, f, offset, *** 3479,3493 **** --- 3430,3453 ---- int vbases_p; { int r = 0; + tree type_binfo = NULL_TREE; /* If this OFFSET is bigger than the MAX_OFFSET, then we should stop. */ if (max_offset && INT_CST_LT (max_offset, offset)) return 0; + if (!TYPE_P (type)) + { + if (abi_version_at_least (2)) + type_binfo = type; + type = BINFO_TYPE (type); + } + if (CLASS_TYPE_P (type)) { tree field; + tree binfo; int i; /* Avoid recursing into objects that are not interesting. */ *************** walk_subobject_offsets (type, f, offset, *** 3500,3535 **** return r; /* Iterate through the direct base classes of TYPE. */ ! for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); ++i) { ! tree binfo = BINFO_BASETYPE (TYPE_BINFO (type), i); if (!vbases_p && TREE_VIA_VIRTUAL (binfo) && !BINFO_PRIMARY_P (binfo)) continue; ! r = walk_subobject_offsets (BINFO_TYPE (binfo), f, ! size_binop (PLUS_EXPR, ! offset, ! BINFO_OFFSET (binfo)), offsets, max_offset, ! vbases_p); if (r) return r; } /* Iterate through the fields of TYPE. */ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) ! if (TREE_CODE (field) == FIELD_DECL) { r = walk_subobject_offsets (TREE_TYPE (field), f, size_binop (PLUS_EXPR, offset, ! DECL_FIELD_OFFSET (field)), offsets, max_offset, /*vbases_p=*/1); --- 3460,3578 ---- return r; /* Iterate through the direct base classes of TYPE. */ ! if (!type_binfo) ! type_binfo = TYPE_BINFO (type); ! for (i = 0; i < BINFO_N_BASETYPES (type_binfo); ++i) { ! tree binfo_offset; ! ! binfo = BINFO_BASETYPE (type_binfo, i); ! ! if (abi_version_at_least (2) ! && TREE_VIA_VIRTUAL (binfo)) ! continue; if (!vbases_p && TREE_VIA_VIRTUAL (binfo) && !BINFO_PRIMARY_P (binfo)) continue; ! if (!abi_version_at_least (2)) ! binfo_offset = size_binop (PLUS_EXPR, ! offset, ! BINFO_OFFSET (binfo)); ! else ! { ! tree orig_binfo; ! /* We cannot rely on BINFO_OFFSET being set for the base ! class yet, but the offsets for direct non-virtual ! bases can be calculated by going back to the TYPE. */ ! orig_binfo = BINFO_BASETYPE (TYPE_BINFO (type), i); ! binfo_offset = size_binop (PLUS_EXPR, ! offset, ! BINFO_OFFSET (orig_binfo)); ! } ! ! r = walk_subobject_offsets (binfo, f, ! binfo_offset, offsets, max_offset, ! (abi_version_at_least (2) ! ? /*vbases_p=*/0 : vbases_p)); if (r) return r; } + if (abi_version_at_least (2)) + { + tree vbase; + + /* Iterate through the virtual base classes of TYPE. In G++ + 3.2, we included virtual bases in the direct base class + loop above, which results in incorrect results; the + correct offsets for virtual bases are only known when + working with the most derived type. */ + if (vbases_p) + for (vbase = CLASSTYPE_VBASECLASSES (type); + vbase; + vbase = TREE_CHAIN (vbase)) + { + binfo = TREE_VALUE (vbase); + r = walk_subobject_offsets (binfo, + f, + size_binop (PLUS_EXPR, + offset, + BINFO_OFFSET (binfo)), + offsets, + max_offset, + /*vbases_p=*/0); + if (r) + return r; + } + else + { + /* We still have to walk the primary base, if it is + virtual. (If it is non-virtual, then it was walked + above.) */ + vbase = get_primary_binfo (type_binfo); + if (vbase && TREE_VIA_VIRTUAL (vbase)) + { + tree derived = type_binfo; + while (BINFO_INHERITANCE_CHAIN (derived)) + derived = BINFO_INHERITANCE_CHAIN (derived); + derived = TREE_TYPE (derived); + vbase = binfo_for_vbase (TREE_TYPE (vbase), derived); + + if (BINFO_PRIMARY_BASE_OF (vbase) == type_binfo) + { + r = (walk_subobject_offsets + (vbase, f, offset, + offsets, max_offset, /*vbases_p=*/0)); + if (r) + return r; + } + } + } + } + /* Iterate through the fields of TYPE. */ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) ! if (TREE_CODE (field) == FIELD_DECL && !DECL_ARTIFICIAL (field)) { + tree field_offset; + + if (abi_version_at_least (2)) + field_offset = byte_position (field); + else + /* In G++ 3.2, DECL_FIELD_OFFSET was used. */ + field_offset = DECL_FIELD_OFFSET (field); + r = walk_subobject_offsets (TREE_TYPE (field), f, size_binop (PLUS_EXPR, offset, ! field_offset), offsets, max_offset, /*vbases_p=*/1); *************** walk_subobject_offsets (type, f, offset, *** 3549,3556 **** return 0; /* Step through each of the elements in the array. */ ! for (index = size_zero_node; ! INT_CST_LT (index, TYPE_MAX_VALUE (domain)); index = size_binop (PLUS_EXPR, index, size_one_node)) { r = walk_subobject_offsets (TREE_TYPE (type), --- 3592,3602 ---- return 0; /* Step through each of the elements in the array. */ ! for (index = size_zero_node; ! /* G++ 3.2 had an off-by-one error here. */ ! (abi_version_at_least (2) ! ? !INT_CST_LT (TYPE_MAX_VALUE (domain), index) ! : INT_CST_LT (index, TYPE_MAX_VALUE (domain))); index = size_binop (PLUS_EXPR, index, size_one_node)) { r = walk_subobject_offsets (TREE_TYPE (type), *************** walk_subobject_offsets (type, f, offset, *** 3575,3581 **** } /* Record all of the empty subobjects of TYPE (located at OFFSET) in ! OFFSETS. If VBASES_P is non-zero, virtual bases of TYPE are examined. */ static void --- 3621,3627 ---- } /* Record all of the empty subobjects of TYPE (located at OFFSET) in ! OFFSETS. If VBASES_P is nonzero, virtual bases of TYPE are examined. */ static void *************** record_subobject_offsets (type, offset, *** 3589,3596 **** offsets, /*max_offset=*/NULL_TREE, vbases_p); } ! /* Returns non-zero if any of the empty subobjects of TYPE (located at ! OFFSET) conflict with entries in OFFSETS. If VBASES_P is non-zero, virtual bases of TYPE are examined. */ static int --- 3635,3642 ---- offsets, /*max_offset=*/NULL_TREE, vbases_p); } ! /* Returns nonzero if any of the empty subobjects of TYPE (located at ! OFFSET) conflict with entries in OFFSETS. If VBASES_P is nonzero, virtual bases of TYPE are examined. */ static int *************** layout_conflict_p (type, offset, offsets *** 3618,3639 **** /* DECL is a FIELD_DECL corresponding either to a base subobject of a non-static data member of the type indicated by RLI. BINFO is the binfo corresponding to the base subobject, OFFSETS maps offsets to ! types already located at those offsets. T is the most derived ! type. This function determines the position of the DECL. */ static void ! layout_nonempty_base_or_field (rli, decl, binfo, offsets, t) ! record_layout_info rli; ! tree decl; ! tree binfo; ! splay_tree offsets; ! tree t; { tree offset = NULL_TREE; ! tree type = TREE_TYPE (decl); ! /* If we are laying out a base class, rather than a field, then ! DECL_ARTIFICIAL will be set on the FIELD_DECL. */ ! int field_p = !DECL_ARTIFICIAL (decl); /* Try to place the field. It may take more than one try if we have a hard time placing the field without putting two objects of the --- 3664,3697 ---- /* DECL is a FIELD_DECL corresponding either to a base subobject of a non-static data member of the type indicated by RLI. BINFO is the binfo corresponding to the base subobject, OFFSETS maps offsets to ! types already located at those offsets. This function determines ! the position of the DECL. */ static void ! layout_nonempty_base_or_field (record_layout_info rli, ! tree decl, ! tree binfo, ! splay_tree offsets) { + tree t = rli->t; tree offset = NULL_TREE; ! bool field_p; ! tree type; ! ! if (binfo) ! { ! /* For the purposes of determining layout conflicts, we want to ! use the class type of BINFO; TREE_TYPE (DECL) will be the ! CLASSTYPE_AS_BASE version, which does not contain entries for ! zero-sized bases. */ ! type = TREE_TYPE (binfo); ! field_p = false; ! } ! else ! { ! type = TREE_TYPE (decl); ! field_p = true; ! } /* Try to place the field. It may take more than one try if we have a hard time placing the field without putting two objects of the *************** layout_nonempty_base_or_field (rli, decl *** 3658,3670 **** offset zero -- its S component would be at the same address as the S we already allocated. So, we have to skip ahead. Since all data members, including those whose type is an ! empty class, have non-zero size, any overlap can happen only with a direct or indirect base-class -- it can't happen with a data member. */ ! if (layout_conflict_p (TREE_TYPE (decl), ! offset, ! offsets, ! field_p)) { /* Strip off the size allocated to this field. That puts us at the first place we could have put the field with --- 3716,3730 ---- offset zero -- its S component would be at the same address as the S we already allocated. So, we have to skip ahead. Since all data members, including those whose type is an ! empty class, have nonzero size, any overlap can happen only with a direct or indirect base-class -- it can't happen with a data member. */ ! /* G++ 3.2 did not check for overlaps when placing a non-empty ! virtual base. */ ! if (!abi_version_at_least (2) && binfo && TREE_VIA_VIRTUAL (binfo)) ! break; ! if (layout_conflict_p (field_p ? type : binfo, offset, ! offsets, field_p)) { /* Strip off the size allocated to this field. That puts us at the first place we could have put the field with *************** layout_nonempty_base_or_field (rli, decl *** 3687,3701 **** /* Now that we know where it will be placed, update its BINFO_OFFSET. */ if (binfo && CLASS_TYPE_P (BINFO_TYPE (binfo))) propagate_binfo_offsets (binfo, ! convert (ssizetype, offset), t); } /* Layout the empty base BINFO. EOC indicates the byte currently just past the end of the class, and should be correctly aligned for a class of the type indicated by BINFO; OFFSETS gives the offsets of the empty bases allocated so far. T is the most derived ! type. Return non-zero iff we added it at the end. */ static bool layout_empty_base (binfo, eoc, offsets, t) --- 3747,3778 ---- /* Now that we know where it will be placed, update its BINFO_OFFSET. */ if (binfo && CLASS_TYPE_P (BINFO_TYPE (binfo))) + /* Indirect virtual bases may have a nonzero BINFO_OFFSET at + this point because their BINFO_OFFSET is copied from another + hierarchy. Therefore, we may not need to add the entire + OFFSET. */ propagate_binfo_offsets (binfo, ! size_diffop (convert (ssizetype, offset), ! convert (ssizetype, ! BINFO_OFFSET (binfo))), ! t); ! } ! ! /* Returns true if TYPE is empty and OFFSET is nonzero. */ ! ! static int ! empty_base_at_nonzero_offset_p (tree type, ! tree offset, ! splay_tree offsets ATTRIBUTE_UNUSED) ! { ! return is_empty_class (type) && !integer_zerop (offset); } /* Layout the empty base BINFO. EOC indicates the byte currently just past the end of the class, and should be correctly aligned for a class of the type indicated by BINFO; OFFSETS gives the offsets of the empty bases allocated so far. T is the most derived ! type. Return nonzero iff we added it at the end. */ static bool layout_empty_base (binfo, eoc, offsets, t) *************** layout_empty_base (binfo, eoc, offsets, *** 3707,3720 **** tree alignment; tree basetype = BINFO_TYPE (binfo); bool atend = false; ! /* This routine should only be used for empty classes. */ my_friendly_assert (is_empty_class (basetype), 20000321); alignment = ssize_int (CLASSTYPE_ALIGN_UNIT (basetype)); /* This is an empty base class. We first try to put it at offset zero. */ ! if (layout_conflict_p (BINFO_TYPE (binfo), BINFO_OFFSET (binfo), offsets, /*vbases_p=*/0)) --- 3784,3804 ---- tree alignment; tree basetype = BINFO_TYPE (binfo); bool atend = false; ! /* This routine should only be used for empty classes. */ my_friendly_assert (is_empty_class (basetype), 20000321); alignment = ssize_int (CLASSTYPE_ALIGN_UNIT (basetype)); + + if (abi_version_at_least (2)) + BINFO_OFFSET (binfo) = size_zero_node; + if (warn_abi && !integer_zerop (BINFO_OFFSET (binfo))) + warning ("offset of empty base `%T' may not be ABI-compliant and may" + "change in a future version of GCC", + BINFO_TYPE (binfo)); /* This is an empty base class. We first try to put it at offset zero. */ ! if (layout_conflict_p (binfo, BINFO_OFFSET (binfo), offsets, /*vbases_p=*/0)) *************** layout_empty_base (binfo, eoc, offsets, *** 3725,3731 **** propagate_binfo_offsets (binfo, convert (ssizetype, eoc), t); while (1) { ! if (!layout_conflict_p (BINFO_TYPE (binfo), BINFO_OFFSET (binfo), offsets, /*vbases_p=*/0)) --- 3809,3815 ---- propagate_binfo_offsets (binfo, convert (ssizetype, eoc), t); while (1) { ! if (!layout_conflict_p (binfo, BINFO_OFFSET (binfo), offsets, /*vbases_p=*/0)) *************** layout_empty_base (binfo, eoc, offsets, *** 3739,3841 **** return atend; } ! /* Build a FIELD_DECL for the base given by BINFO in the class ! indicated by RLI. If the new object is non-empty, clear *EMPTY_P. ! *BASE_ALIGN is a running maximum of the alignments of any base ! class. OFFSETS gives the location of empty base subobjects. T is ! the most derived type. Return non-zero if the new object cannot be ! nearly-empty. */ ! static bool ! build_base_field (rli, binfo, empty_p, offsets, t) ! record_layout_info rli; ! tree binfo; ! int *empty_p; ! splay_tree offsets; ! tree t; { tree basetype = BINFO_TYPE (binfo); - tree decl; - bool atend = false; if (!COMPLETE_TYPE_P (basetype)) /* This error is now reported in xref_tag, thus giving better location information. */ ! return atend; ! ! decl = build_decl (FIELD_DECL, NULL_TREE, basetype); ! DECL_ARTIFICIAL (decl) = 1; ! DECL_FIELD_CONTEXT (decl) = rli->t; ! DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype); ! DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype); ! DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype); ! DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype); ! /* Tell the backend not to round up to TYPE_ALIGN. */ ! DECL_PACKED (decl) = 1; ! if (!integer_zerop (DECL_SIZE (decl))) { /* The containing class is non-empty because it has a non-empty base class. */ ! *empty_p = 0; /* Try to place the field. It may take more than one try if we have a hard time placing the field without putting two objects of the same type at the same address. */ ! layout_nonempty_base_or_field (rli, decl, binfo, offsets, t); } else { ! unsigned HOST_WIDE_INT eoc; /* On some platforms (ARM), even empty classes will not be byte-aligned. */ ! eoc = tree_low_cst (rli_size_unit_so_far (rli), 0); ! eoc = CEIL (eoc, DECL_ALIGN_UNIT (decl)) * DECL_ALIGN_UNIT (decl); ! atend |= layout_empty_base (binfo, size_int (eoc), offsets, t); } /* Record the offsets of BINFO and its base subobjects. */ ! record_subobject_offsets (BINFO_TYPE (binfo), BINFO_OFFSET (binfo), offsets, /*vbases_p=*/0); ! return atend; } /* Layout all of the non-virtual base classes. Record empty ! subobjects in OFFSETS. T is the most derived type. Return ! non-zero if the type cannot be nearly empty. */ ! static bool ! build_base_fields (rli, empty_p, offsets, t) ! record_layout_info rli; ! int *empty_p; ! splay_tree offsets; ! tree t; { /* Chain to hold all the new FIELD_DECLs which stand in for base class subobjects. */ ! tree rec = rli->t; ! int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec); int i; - bool atend = 0; /* The primary base class is always allocated first. */ ! if (CLASSTYPE_HAS_PRIMARY_BASE_P (rec)) ! build_base_field (rli, CLASSTYPE_PRIMARY_BINFO (rec), ! empty_p, offsets, t); /* Now allocate the rest of the bases. */ for (i = 0; i < n_baseclasses; ++i) { tree base_binfo; ! base_binfo = BINFO_BASETYPE (TYPE_BINFO (rec), i); /* The primary base was already allocated above, so we don't need to allocate it again here. */ ! if (base_binfo == CLASSTYPE_PRIMARY_BINFO (rec)) continue; /* A primary virtual base class is allocated just like any other --- 3823,3963 ---- return atend; } ! /* Layout the the base given by BINFO in the class indicated by RLI. ! *BASE_ALIGN is a running maximum of the alignments of ! any base class. OFFSETS gives the location of empty base ! subobjects. T is the most derived type. Return nonzero if the new ! object cannot be nearly-empty. A new FIELD_DECL is inserted at ! *NEXT_FIELD, unless BINFO is for an empty base class. ! Returns the location at which the next field should be inserted. */ ! ! static tree * ! build_base_field (record_layout_info rli, tree binfo, ! splay_tree offsets, tree *next_field) { + tree t = rli->t; tree basetype = BINFO_TYPE (binfo); if (!COMPLETE_TYPE_P (basetype)) /* This error is now reported in xref_tag, thus giving better location information. */ ! return next_field; ! /* Place the base class. */ ! if (!is_empty_class (basetype)) { + tree decl; + /* The containing class is non-empty because it has a non-empty base class. */ ! CLASSTYPE_EMPTY_P (t) = 0; ! ! /* Create the FIELD_DECL. */ ! decl = build_decl (FIELD_DECL, NULL_TREE, CLASSTYPE_AS_BASE (basetype)); ! DECL_ARTIFICIAL (decl) = 1; ! DECL_FIELD_CONTEXT (decl) = t; ! DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype); ! DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype); ! DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype); ! DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype); ! DECL_IGNORED_P (decl) = 1; /* Try to place the field. It may take more than one try if we have a hard time placing the field without putting two objects of the same type at the same address. */ ! layout_nonempty_base_or_field (rli, decl, binfo, offsets); ! /* Add the new FIELD_DECL to the list of fields for T. */ ! TREE_CHAIN (decl) = *next_field; ! *next_field = decl; ! next_field = &TREE_CHAIN (decl); } else { ! tree eoc; ! bool atend; /* On some platforms (ARM), even empty classes will not be byte-aligned. */ ! eoc = round_up (rli_size_unit_so_far (rli), ! CLASSTYPE_ALIGN_UNIT (basetype)); ! atend = layout_empty_base (binfo, eoc, offsets, t); ! /* A nearly-empty class "has no proper base class that is empty, ! not morally virtual, and at an offset other than zero." */ ! if (!TREE_VIA_VIRTUAL (binfo) && CLASSTYPE_NEARLY_EMPTY_P (t)) ! { ! if (atend) ! CLASSTYPE_NEARLY_EMPTY_P (t) = 0; ! /* The check above (used in G++ 3.2) is insufficient because ! an empty class placed at offset zero might itself have an ! empty base at a nonzero offset. */ ! else if (walk_subobject_offsets (basetype, ! empty_base_at_nonzero_offset_p, ! size_zero_node, ! /*offsets=*/NULL, ! /*max_offset=*/NULL_TREE, ! /*vbases_p=*/true)) ! { ! if (abi_version_at_least (2)) ! CLASSTYPE_NEARLY_EMPTY_P (t) = 0; ! else if (warn_abi) ! warning ("class `%T' will be considered nearly empty in a " ! "future version of GCC", t); ! } ! } ! ! /* We do not create a FIELD_DECL for empty base classes because ! it might overlap some other field. We want to be able to ! create CONSTRUCTORs for the class by iterating over the ! FIELD_DECLs, and the back end does not handle overlapping ! FIELD_DECLs. */ ! ! /* An empty virtual base causes a class to be non-empty ! -- but in that case we do not need to clear CLASSTYPE_EMPTY_P ! here because that was already done when the virtual table ! pointer was created. */ } /* Record the offsets of BINFO and its base subobjects. */ ! record_subobject_offsets (binfo, BINFO_OFFSET (binfo), offsets, /*vbases_p=*/0); ! ! return next_field; } /* Layout all of the non-virtual base classes. Record empty ! subobjects in OFFSETS. T is the most derived type. Return nonzero ! if the type cannot be nearly empty. The fields created ! corresponding to the base classes will be inserted at ! *NEXT_FIELD. */ ! static void ! build_base_fields (record_layout_info rli, ! splay_tree offsets, tree *next_field) { /* Chain to hold all the new FIELD_DECLs which stand in for base class subobjects. */ ! tree t = rli->t; ! int n_baseclasses = CLASSTYPE_N_BASECLASSES (t); int i; /* The primary base class is always allocated first. */ ! if (CLASSTYPE_HAS_PRIMARY_BASE_P (t)) ! next_field = build_base_field (rli, CLASSTYPE_PRIMARY_BINFO (t), ! offsets, next_field); /* Now allocate the rest of the bases. */ for (i = 0; i < n_baseclasses; ++i) { tree base_binfo; ! base_binfo = BINFO_BASETYPE (TYPE_BINFO (t), i); /* The primary base was already allocated above, so we don't need to allocate it again here. */ ! if (base_binfo == CLASSTYPE_PRIMARY_BINFO (t)) continue; /* A primary virtual base class is allocated just like any other *************** build_base_fields (rli, empty_p, offsets *** 3845,3853 **** && !BINFO_PRIMARY_P (base_binfo)) continue; ! atend |= build_base_field (rli, base_binfo, empty_p, offsets, t); } - return atend; } /* Go through the TYPE_METHODS of T issuing any appropriate --- 3967,3975 ---- && !BINFO_PRIMARY_P (base_binfo)) continue; ! next_field = build_base_field (rli, base_binfo, ! offsets, next_field); } } /* Go through the TYPE_METHODS of T issuing any appropriate *************** build_clone (fn, name) *** 3975,3981 **** for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms)) { DECL_CONTEXT (parms) = clone; ! copy_lang_decl (parms); } } --- 4097,4103 ---- for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms)) { DECL_CONTEXT (parms) = clone; ! cxx_dup_lang_specific_decl (parms); } } *************** build_clone (fn, name) *** 4005,4011 **** } /* Produce declarations for all appropriate clones of FN. If ! UPDATE_METHOD_VEC_P is non-zero, the clones are added to the CLASTYPE_METHOD_VEC as well. */ void --- 4127,4133 ---- } /* Produce declarations for all appropriate clones of FN. If ! UPDATE_METHOD_VEC_P is nonzero, the clones are added to the CLASTYPE_METHOD_VEC as well. */ void *************** clone_function_decl (fn, update_method_v *** 4067,4073 **** declared. An out-of-class definition can specify additional default arguments. As it is the clones that are involved in overload resolution, we must propagate the information from the DECL to its ! clones. */ void adjust_clone_args (decl) --- 4189,4195 ---- declared. An out-of-class definition can specify additional default arguments. As it is the clones that are involved in overload resolution, we must propagate the information from the DECL to its ! clones. */ void adjust_clone_args (decl) *************** adjust_clone_args (decl) *** 4084,4090 **** clone_parms = orig_clone_parms; ! /* Skip the 'this' parameter. */ orig_clone_parms = TREE_CHAIN (orig_clone_parms); orig_decl_parms = TREE_CHAIN (orig_decl_parms); --- 4206,4212 ---- clone_parms = orig_clone_parms; ! /* Skip the 'this' parameter. */ orig_clone_parms = TREE_CHAIN (orig_clone_parms); orig_decl_parms = TREE_CHAIN (orig_decl_parms); *************** adjust_clone_args (decl) *** 4107,4113 **** if (TREE_PURPOSE (decl_parms) && !TREE_PURPOSE (clone_parms)) { /* A default parameter has been added. Adjust the ! clone's parameters. */ tree exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone)); tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone)); tree type; --- 4229,4235 ---- if (TREE_PURPOSE (decl_parms) && !TREE_PURPOSE (clone_parms)) { /* A default parameter has been added. Adjust the ! clone's parameters. */ tree exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone)); tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone)); tree type; *************** type_requires_array_cookie (type) *** 4206,4212 **** if (!fns || fns == error_mark_node) return false; /* Loop through all of the functions. */ ! for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns)) { tree fn; tree second_parm; --- 4328,4334 ---- if (!fns || fns == error_mark_node) return false; /* Loop through all of the functions. */ ! for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns)) { tree fn; tree second_parm; *************** type_requires_array_cookie (type) *** 4236,4244 **** level: i.e., independently of the ABI in use. */ static void ! check_bases_and_members (t, empty_p) ! tree t; ! int *empty_p; { /* Nonzero if we are not allowed to generate a default constructor for this case. */ --- 4358,4364 ---- level: i.e., independently of the ABI in use. */ static void ! check_bases_and_members (tree t) { /* Nonzero if we are not allowed to generate a default constructor for this case. */ *************** check_bases_and_members (t, empty_p) *** 4257,4273 **** cant_have_const_ctor = 0; no_const_asn_ref = 0; ! /* Assume that the class is nearly empty; we'll clear this flag if ! it turns out not to be nearly empty. */ ! CLASSTYPE_NEARLY_EMPTY_P (t) = 1; ! CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0; ! ! /* Check all the base-classes. */ check_bases (t, &cant_have_default_ctor, &cant_have_const_ctor, &no_const_asn_ref); /* Check all the data member declarations. */ ! check_field_decls (t, &access_decls, empty_p, &cant_have_default_ctor, &cant_have_const_ctor, &no_const_asn_ref); --- 4377,4388 ---- cant_have_const_ctor = 0; no_const_asn_ref = 0; ! /* Check all the base-classes. */ check_bases (t, &cant_have_default_ctor, &cant_have_const_ctor, &no_const_asn_ref); /* Check all the data member declarations. */ ! check_field_decls (t, &access_decls, &cant_have_default_ctor, &cant_have_const_ctor, &no_const_asn_ref); *************** check_bases_and_members (t, empty_p) *** 4318,4324 **** /* Figure out whether or not we will need a cookie when dynamically allocating an array of this type. */ ! TYPE_LANG_SPECIFIC (t)->vec_new_uses_cookie = type_requires_array_cookie (t); } --- 4433,4439 ---- /* Figure out whether or not we will need a cookie when dynamically allocating an array of this type. */ ! TYPE_LANG_SPECIFIC (t)->u.c.vec_new_uses_cookie = type_requires_array_cookie (t); } *************** check_bases_and_members (t, empty_p) *** 4330,4339 **** on VIRTUALS_P. */ static tree ! create_vtable_ptr (t, empty_p, vfuns_p, virtuals_p) tree t; - int *empty_p; - int *vfuns_p; tree *virtuals_p; { tree fn; --- 4445,4452 ---- on VIRTUALS_P. */ static tree ! create_vtable_ptr (t, virtuals_p) tree t; tree *virtuals_p; { tree fn; *************** create_vtable_ptr (t, empty_p, vfuns_p, *** 4391,4397 **** TYPE_VFIELD (t) = field; /* This class is non-empty. */ ! *empty_p = 0; if (CLASSTYPE_N_BASECLASSES (t)) /* If there were any baseclasses, they can't possibly be at --- 4504,4510 ---- TYPE_VFIELD (t) = field; /* This class is non-empty. */ ! CLASSTYPE_EMPTY_P (t) = 0; if (CLASSTYPE_N_BASECLASSES (t)) /* If there were any baseclasses, they can't possibly be at *************** dfs_set_offset_for_unshared_vbases (binf *** 4540,4572 **** return NULL_TREE; } ! /* Set BINFO_OFFSET for all of the virtual bases for T. Update TYPE_ALIGN and TYPE_SIZE for T. OFFSETS gives the location of empty subobjects of T. */ static void ! layout_virtual_bases (t, offsets) ! tree t; ! splay_tree offsets; { ! tree vbases, dsize; ! unsigned HOST_WIDE_INT eoc; bool first_vbase = true; if (CLASSTYPE_N_BASECLASSES (t) == 0) return; #ifdef STRUCTURE_SIZE_BOUNDARY ! /* Packed structures don't need to have minimum size. */ ! if (! TYPE_PACKED (t)) ! TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), STRUCTURE_SIZE_BOUNDARY); #endif ! /* DSIZE is the size of the class without the virtual bases. */ ! dsize = TYPE_SIZE (t); ! ! /* Make every class have alignment of at least one. */ ! TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), BITS_PER_UNIT); /* Go through the virtual bases, allocating space for each virtual base that is not already a primary base class. These are --- 4653,4693 ---- return NULL_TREE; } ! /* Set BINFO_OFFSET for all of the virtual bases for RLI->T. Update TYPE_ALIGN and TYPE_SIZE for T. OFFSETS gives the location of empty subobjects of T. */ static void ! layout_virtual_bases (record_layout_info rli, splay_tree offsets) { ! tree vbases; ! tree t = rli->t; bool first_vbase = true; + tree *next_field; if (CLASSTYPE_N_BASECLASSES (t) == 0) return; + if (!abi_version_at_least(2)) + { + /* In G++ 3.2, we incorrectly rounded the size before laying out + the virtual bases. */ + finish_record_layout (rli, /*free_p=*/false); #ifdef STRUCTURE_SIZE_BOUNDARY ! /* Packed structures don't need to have minimum size. */ ! if (! TYPE_PACKED (t)) ! TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), STRUCTURE_SIZE_BOUNDARY); #endif + rli->offset = TYPE_SIZE_UNIT (t); + rli->bitpos = bitsize_zero_node; + rli->record_align = TYPE_ALIGN (t); + } ! /* Find the last field. The artificial fields created for virtual ! bases will go after the last extant field to date. */ ! next_field = &TYPE_FIELDS (t); ! while (*next_field) ! next_field = &TREE_CHAIN (*next_field); /* Go through the virtual bases, allocating space for each virtual base that is not already a primary base class. These are *************** layout_virtual_bases (t, offsets) *** 4584,4628 **** if (!BINFO_PRIMARY_P (vbase)) { /* This virtual base is not a primary base of any class in the hierarchy, so we have to add space for it. */ ! tree basetype, usize; ! unsigned int desired_align; ! ! basetype = BINFO_TYPE (vbase); ! ! desired_align = CLASSTYPE_ALIGN (basetype); ! TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), desired_align); ! ! /* Add padding so that we can put the virtual base class at an ! appropriately aligned offset. */ ! dsize = round_up (dsize, desired_align); ! usize = size_binop (CEIL_DIV_EXPR, dsize, bitsize_unit_node); ! ! /* We try to squish empty virtual bases in just like ! ordinary empty bases. */ ! if (is_empty_class (basetype)) ! layout_empty_base (vbase, ! convert (sizetype, usize), ! offsets, t); ! else ! { ! tree offset; ! ! offset = convert (ssizetype, usize); ! offset = size_diffop (offset, ! convert (ssizetype, ! BINFO_OFFSET (vbase))); ! ! /* And compute the offset of the virtual base. */ ! propagate_binfo_offsets (vbase, offset, t); ! /* Every virtual baseclass takes a least a UNIT, so that ! we can take it's address and get something different ! for each base. */ ! dsize = size_binop (PLUS_EXPR, dsize, ! size_binop (MAX_EXPR, bitsize_unit_node, ! CLASSTYPE_SIZE (basetype))); ! } /* If the first virtual base might have been placed at a lower address, had we started from CLASSTYPE_SIZE, rather --- 4705,4716 ---- if (!BINFO_PRIMARY_P (vbase)) { + tree basetype = TREE_TYPE (vbase); + /* This virtual base is not a primary base of any class in the hierarchy, so we have to add space for it. */ ! next_field = build_base_field (rli, vbase, ! offsets, next_field); /* If the first virtual base might have been placed at a lower address, had we started from CLASSTYPE_SIZE, rather *************** layout_virtual_bases (t, offsets) *** 4633,4652 **** the results which is not particularly tractable. */ if (warn_abi && first_vbase ! && tree_int_cst_lt (size_binop (CEIL_DIV_EXPR, ! round_up (CLASSTYPE_SIZE (t), ! desired_align), ! bitsize_unit_node), ! BINFO_OFFSET (vbase))) warning ("offset of virtual base `%T' is not ABI-compliant and may change in a future version of GCC", basetype); - /* Keep track of the offsets assigned to this virtual base. */ - record_subobject_offsets (BINFO_TYPE (vbase), - BINFO_OFFSET (vbase), - offsets, - /*vbases_p=*/0); - first_vbase = false; } } --- 4721,4735 ---- the results which is not particularly tractable. */ if (warn_abi && first_vbase ! && (tree_int_cst_lt ! (size_binop (CEIL_DIV_EXPR, ! round_up (CLASSTYPE_SIZE (t), ! CLASSTYPE_ALIGN (basetype)), ! bitsize_unit_node), ! BINFO_OFFSET (vbase)))) warning ("offset of virtual base `%T' is not ABI-compliant and may change in a future version of GCC", basetype); first_vbase = false; } } *************** layout_virtual_bases (t, offsets) *** 4657,4736 **** in lookup_base depend on the BINFO_OFFSETs being set correctly. */ dfs_walk (TYPE_BINFO (t), dfs_set_offset_for_unshared_vbases, NULL, t); ! /* If we had empty base classes that protruded beyond the end of the ! class, we didn't update DSIZE above; we were hoping to overlay ! multiple such bases at the same location. */ ! eoc = end_of_class (t, /*include_virtuals_p=*/1); ! dsize = size_binop (MAX_EXPR, dsize, bitsize_int (eoc * BITS_PER_UNIT)); ! /* Now, make sure that the total size of the type is a multiple of ! its alignment. */ ! dsize = round_up (dsize, TYPE_ALIGN (t)); ! TYPE_SIZE (t) = dsize; ! TYPE_SIZE_UNIT (t) = convert (sizetype, ! size_binop (CEIL_DIV_EXPR, TYPE_SIZE (t), ! bitsize_unit_node)); ! /* Check for ambiguous virtual bases. */ ! if (extra_warnings) ! for (vbases = CLASSTYPE_VBASECLASSES (t); ! vbases; ! vbases = TREE_CHAIN (vbases)) ! { ! tree basetype = BINFO_TYPE (TREE_VALUE (vbases)); ! ! if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL)) ! warning ("virtual base `%T' inaccessible in `%T' due to ambiguity", ! basetype, t); ! } } /* Returns the offset of the byte just past the end of the base class with the highest offset in T. If INCLUDE_VIRTUALS_P is zero, then only non-virtual bases are included. */ ! static unsigned HOST_WIDE_INT end_of_class (t, include_virtuals_p) tree t; int include_virtuals_p; { ! unsigned HOST_WIDE_INT result = 0; int i; for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); ++i) { ! tree base_binfo; ! tree offset; ! tree size; ! unsigned HOST_WIDE_INT end_of_base; ! ! base_binfo = BINFO_BASETYPE (TYPE_BINFO (t), i); if (!include_virtuals_p ! && TREE_VIA_VIRTUAL (base_binfo) ! && !BINFO_PRIMARY_P (base_binfo)) continue; ! if (is_empty_class (BINFO_TYPE (base_binfo))) ! /* An empty class has zero CLASSTYPE_SIZE_UNIT, but we need to ! allocate some space for it. It cannot have virtual bases, ! so TYPE_SIZE_UNIT is fine. */ ! size = TYPE_SIZE_UNIT (BINFO_TYPE (base_binfo)); ! else ! size = CLASSTYPE_SIZE_UNIT (BINFO_TYPE (base_binfo)); ! offset = size_binop (PLUS_EXPR, ! BINFO_OFFSET (base_binfo), ! size); ! end_of_base = tree_low_cst (offset, /*pos=*/1); ! if (end_of_base > result) ! result = end_of_base; } return result; } ! /* Warn about direct bases of T that are inaccessible because they are ambiguous. For example: struct S {}; --- 4740,4809 ---- in lookup_base depend on the BINFO_OFFSETs being set correctly. */ dfs_walk (TYPE_BINFO (t), dfs_set_offset_for_unshared_vbases, NULL, t); + } ! /* Returns the offset of the byte just past the end of the base class ! BINFO. */ ! static tree ! end_of_base (tree binfo) ! { ! tree size; ! if (is_empty_class (BINFO_TYPE (binfo))) ! /* An empty class has zero CLASSTYPE_SIZE_UNIT, but we need to ! allocate some space for it. It cannot have virtual bases, so ! TYPE_SIZE_UNIT is fine. */ ! size = TYPE_SIZE_UNIT (BINFO_TYPE (binfo)); ! else ! size = CLASSTYPE_SIZE_UNIT (BINFO_TYPE (binfo)); ! ! return size_binop (PLUS_EXPR, BINFO_OFFSET (binfo), size); } /* Returns the offset of the byte just past the end of the base class with the highest offset in T. If INCLUDE_VIRTUALS_P is zero, then only non-virtual bases are included. */ ! static tree end_of_class (t, include_virtuals_p) tree t; int include_virtuals_p; { ! tree result = size_zero_node; ! tree binfo; ! tree offset; int i; for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); ++i) { ! binfo = BINFO_BASETYPE (TYPE_BINFO (t), i); if (!include_virtuals_p ! && TREE_VIA_VIRTUAL (binfo) ! && BINFO_PRIMARY_BASE_OF (binfo) != TYPE_BINFO (t)) continue; ! offset = end_of_base (binfo); ! if (INT_CST_LT_UNSIGNED (result, offset)) ! result = offset; } + /* G++ 3.2 did not check indirect virtual bases. */ + if (abi_version_at_least (2) && include_virtuals_p) + for (binfo = CLASSTYPE_VBASECLASSES (t); + binfo; + binfo = TREE_CHAIN (binfo)) + { + offset = end_of_base (TREE_VALUE (binfo)); + if (INT_CST_LT_UNSIGNED (result, offset)) + result = offset; + } + return result; } ! /* Warn about bases of T that are inaccessible because they are ambiguous. For example: struct S {}; *************** end_of_class (t, include_virtuals_p) *** 4741,4759 **** subobjects of U. */ static void ! warn_about_ambiguous_direct_bases (t) tree t; { int i; for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); ++i) { ! tree basetype = TYPE_BINFO_BASETYPE (t, i); if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL)) warning ("direct base `%T' inaccessible in `%T' due to ambiguity", ! basetype, t); } } /* Compare two INTEGER_CSTs K1 and K2. */ --- 4814,4848 ---- subobjects of U. */ static void ! warn_about_ambiguous_bases (t) tree t; { int i; + tree vbases; + tree basetype; + /* Check direct bases. */ for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); ++i) { ! basetype = TYPE_BINFO_BASETYPE (t, i); if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL)) warning ("direct base `%T' inaccessible in `%T' due to ambiguity", ! basetype, t); } + + /* Check for ambiguous virtual bases. */ + if (extra_warnings) + for (vbases = CLASSTYPE_VBASECLASSES (t); + vbases; + vbases = TREE_CHAIN (vbases)) + { + basetype = BINFO_TYPE (TREE_VALUE (vbases)); + + if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL)) + warning ("virtual base `%T' inaccessible in `%T' due to ambiguity", + basetype, t); + } } /* Compare two INTEGER_CSTs K1 and K2. */ *************** splay_tree_compare_integer_csts (k1, k2) *** 4766,4792 **** return tree_int_cst_compare ((tree) k1, (tree) k2); } /* Calculate the TYPE_SIZE, TYPE_ALIGN, etc for T. Calculate BINFO_OFFSETs for all of the base-classes. Position the vtable ! pointer. Accumulate declared virtual functions on VIRTUALS_P. */ static void ! layout_class_type (t, empty_p, vfuns_p, virtuals_p) ! tree t; ! int *empty_p; ! int *vfuns_p; ! tree *virtuals_p; { tree non_static_data_members; tree field; tree vptr; record_layout_info rli; - unsigned HOST_WIDE_INT eoc; /* Maps offsets (represented as INTEGER_CSTs) to a TREE_LIST of types that appear at that offset. */ splay_tree empty_base_offsets; /* True if the last field layed out was a bit-field. */ bool last_field_was_bitfield = false; /* Keep track of the first non-static data member. */ non_static_data_members = TYPE_FIELDS (t); --- 4855,4913 ---- return tree_int_cst_compare ((tree) k1, (tree) k2); } + /* Increase the size indicated in RLI to account for empty classes + that are "off the end" of the class. */ + + static void + include_empty_classes (record_layout_info rli) + { + tree eoc; + tree rli_size; + + /* It might be the case that we grew the class to allocate a + zero-sized base class. That won't be reflected in RLI, yet, + because we are willing to overlay multiple bases at the same + offset. However, now we need to make sure that RLI is big enough + to reflect the entire class. */ + eoc = end_of_class (rli->t, + CLASSTYPE_AS_BASE (rli->t) != NULL_TREE); + rli_size = rli_size_unit_so_far (rli); + if (TREE_CODE (rli_size) == INTEGER_CST + && INT_CST_LT_UNSIGNED (rli_size, eoc)) + { + rli->bitpos = round_up (rli->bitpos, BITS_PER_UNIT); + rli->bitpos + = size_binop (PLUS_EXPR, + rli->bitpos, + size_binop (MULT_EXPR, + convert (bitsizetype, + size_binop (MINUS_EXPR, + eoc, rli_size)), + bitsize_int (BITS_PER_UNIT))); + normalize_rli (rli); + } + } + /* Calculate the TYPE_SIZE, TYPE_ALIGN, etc for T. Calculate BINFO_OFFSETs for all of the base-classes. Position the vtable ! pointer. Accumulate declared virtual functions on VIRTUALS_P. */ static void ! layout_class_type (tree t, tree *virtuals_p) { tree non_static_data_members; tree field; tree vptr; record_layout_info rli; /* Maps offsets (represented as INTEGER_CSTs) to a TREE_LIST of types that appear at that offset. */ splay_tree empty_base_offsets; /* True if the last field layed out was a bit-field. */ bool last_field_was_bitfield = false; + /* The location at which the next field should be inserted. */ + tree *next_field; + /* T, as a base class. */ + tree base_t; /* Keep track of the first non-static data member. */ non_static_data_members = TYPE_FIELDS (t); *************** layout_class_type (t, empty_p, vfuns_p, *** 4796,4818 **** /* If possible, we reuse the virtual function table pointer from one of our base classes. */ ! determine_primary_base (t, vfuns_p); /* Create a pointer to our virtual function table. */ ! vptr = create_vtable_ptr (t, empty_p, vfuns_p, virtuals_p); /* The vptr is always the first thing in the class. */ if (vptr) { ! TYPE_FIELDS (t) = chainon (vptr, TYPE_FIELDS (t)); place_field (rli, vptr); } /* Build FIELD_DECLs for all of the non-virtual base-types. */ empty_base_offsets = splay_tree_new (splay_tree_compare_integer_csts, NULL, NULL); ! if (build_base_fields (rli, empty_p, empty_base_offsets, t)) ! CLASSTYPE_NEARLY_EMPTY_P (t) = 0; /* Layout the non-static data members. */ for (field = non_static_data_members; field; field = TREE_CHAIN (field)) --- 4917,4942 ---- /* If possible, we reuse the virtual function table pointer from one of our base classes. */ ! determine_primary_base (t); /* Create a pointer to our virtual function table. */ ! vptr = create_vtable_ptr (t, virtuals_p); /* The vptr is always the first thing in the class. */ if (vptr) { ! TREE_CHAIN (vptr) = TYPE_FIELDS (t); ! TYPE_FIELDS (t) = vptr; ! next_field = &TREE_CHAIN (vptr); place_field (rli, vptr); } + else + next_field = &TYPE_FIELDS (t); /* Build FIELD_DECLs for all of the non-virtual base-types. */ empty_base_offsets = splay_tree_new (splay_tree_compare_integer_csts, NULL, NULL); ! build_base_fields (rli, empty_base_offsets, next_field); /* Layout the non-static data members. */ for (field = non_static_data_members; field; field = TREE_CHAIN (field)) *************** layout_class_type (t, empty_p, vfuns_p, *** 4864,4880 **** field. We have to back up by one to find the largest type that fits. */ integer_type = integer_types[itk - 1]; ! padding = size_binop (MINUS_EXPR, DECL_SIZE (field), ! TYPE_SIZE (integer_type)); DECL_SIZE (field) = TYPE_SIZE (integer_type); DECL_ALIGN (field) = TYPE_ALIGN (integer_type); DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type); } else ! padding = NULL_TREE; ! layout_nonempty_base_or_field (rli, field, NULL_TREE, ! empty_base_offsets, t); /* If a bit-field does not immediately follow another bit-field, and yet it starts in the middle of a byte, we have failed to --- 4988,5031 ---- field. We have to back up by one to find the largest type that fits. */ integer_type = integer_types[itk - 1]; ! ! if (abi_version_at_least (2) && TREE_CODE (t) == UNION_TYPE) ! /* In a union, the padding field must have the full width ! of the bit-field; all fields start at offset zero. */ ! padding = DECL_SIZE (field); ! else ! { ! if (warn_abi && TREE_CODE (t) == UNION_TYPE) ! warning ("size assigned to `%T' may not be " ! "ABI-compliant and may change in a future " ! "version of GCC", ! t); ! padding = size_binop (MINUS_EXPR, DECL_SIZE (field), ! TYPE_SIZE (integer_type)); ! } DECL_SIZE (field) = TYPE_SIZE (integer_type); DECL_ALIGN (field) = TYPE_ALIGN (integer_type); DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type); + layout_nonempty_base_or_field (rli, field, NULL_TREE, + empty_base_offsets); + /* Now that layout has been performed, set the size of the + field to the size of its declared type; the rest of the + field is effectively invisible. */ + DECL_SIZE (field) = TYPE_SIZE (type); } else ! { ! padding = NULL_TREE; ! layout_nonempty_base_or_field (rli, field, NULL_TREE, ! empty_base_offsets); ! } ! /* Remember the location of any empty classes in FIELD. */ ! if (abi_version_at_least (2)) ! record_subobject_offsets (TREE_TYPE (field), ! byte_position(field), ! empty_base_offsets, ! /*vbases_p=*/1); /* If a bit-field does not immediately follow another bit-field, and yet it starts in the middle of a byte, we have failed to *************** layout_class_type (t, empty_p, vfuns_p, *** 4888,4893 **** --- 5039,5055 ---- cp_warning_at ("offset of `%D' is not ABI-compliant and may change in a future version of GCC", field); + /* G++ used to use DECL_FIELD_OFFSET as if it were the byte + offset of the field. */ + if (warn_abi + && !tree_int_cst_equal (DECL_FIELD_OFFSET (field), + byte_position (field)) + && contains_empty_class_p (TREE_TYPE (field))) + cp_warning_at ("`%D' contains empty classes which may cause base " + "classes to be placed at different locations in a " + "future version of GCC", + field); + /* If we needed additional padding after this field, add it now. */ if (padding) *************** layout_class_type (t, empty_p, vfuns_p, *** 4903,4975 **** DECL_USER_ALIGN (padding_field) = 0; layout_nonempty_base_or_field (rli, padding_field, NULL_TREE, ! empty_base_offsets, t); } last_field_was_bitfield = DECL_C_BIT_FIELD (field); } ! /* It might be the case that we grew the class to allocate a ! zero-sized base class. That won't be reflected in RLI, yet, ! because we are willing to overlay multiple bases at the same ! offset. However, now we need to make sure that RLI is big enough ! to reflect the entire class. */ ! eoc = end_of_class (t, /*include_virtuals_p=*/0); ! if (TREE_CODE (rli_size_unit_so_far (rli)) == INTEGER_CST ! && compare_tree_int (rli_size_unit_so_far (rli), eoc) < 0) ! { ! rli->offset = size_binop (MAX_EXPR, rli->offset, size_int (eoc)); ! rli->bitpos = bitsize_zero_node; ! } ! ! /* We make all structures have at least one element, so that they ! have non-zero size. The class may be empty even if it has ! basetypes. Therefore, we add the fake field after all the other ! fields; if there are already FIELD_DECLs on the list, their ! offsets will not be disturbed. */ ! if (!eoc && *empty_p) { ! tree padding; ! ! padding = build_decl (FIELD_DECL, NULL_TREE, char_type_node); ! place_field (rli, padding); } ! /* Let the back-end lay out the type. Note that at this point we ! have only included non-virtual base-classes; we will lay out the ! virtual base classes later. So, the TYPE_SIZE/TYPE_ALIGN after ! this call are not necessarily correct; they are just the size and ! alignment when no virtual base clases are used. */ ! finish_record_layout (rli); /* Delete all zero-width bit-fields from the list of fields. Now that the type is laid out they are no longer important. */ remove_zero_width_bit_fields (t); ! /* Remember the size and alignment of the class before adding ! the virtual bases. */ ! if (*empty_p) ! { ! CLASSTYPE_SIZE (t) = bitsize_zero_node; ! CLASSTYPE_SIZE_UNIT (t) = size_zero_node; ! } ! /* If this is a POD, we can't reuse its tail padding. */ ! else if (!CLASSTYPE_NON_POD_P (t)) { ! CLASSTYPE_SIZE (t) = TYPE_SIZE (t); ! CLASSTYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (t); } else ! { ! CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t); ! CLASSTYPE_SIZE_UNIT (t) = TYPE_BINFO_SIZE_UNIT (t); ! } ! ! CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t); ! CLASSTYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (t); /* Every empty class contains an empty class. */ ! if (*empty_p) CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1; /* Set the TYPE_DECL for this type to contain the right --- 5065,5166 ---- DECL_USER_ALIGN (padding_field) = 0; layout_nonempty_base_or_field (rli, padding_field, NULL_TREE, ! empty_base_offsets); } last_field_was_bitfield = DECL_C_BIT_FIELD (field); } ! if (abi_version_at_least (2) && !integer_zerop (rli->bitpos)) { ! /* Make sure that we are on a byte boundary so that the size of ! the class without virtual bases will always be a round number ! of bytes. */ ! rli->bitpos = round_up (rli->bitpos, BITS_PER_UNIT); ! normalize_rli (rli); } ! /* G++ 3.2 does not allow virtual bases to be overlaid with tail ! padding. */ ! if (!abi_version_at_least (2)) ! include_empty_classes(rli); /* Delete all zero-width bit-fields from the list of fields. Now that the type is laid out they are no longer important. */ remove_zero_width_bit_fields (t); ! /* Create the version of T used for virtual bases. We do not use ! make_aggr_type for this version; this is an artificial type. For ! a POD type, we just reuse T. */ ! if (CLASSTYPE_NON_POD_P (t) || CLASSTYPE_EMPTY_P (t)) { ! base_t = make_node (TREE_CODE (t)); ! ! /* Set the size and alignment for the new type. In G++ 3.2, all ! empty classes were considered to have size zero when used as ! base classes. */ ! if (!abi_version_at_least (2) && CLASSTYPE_EMPTY_P (t)) ! { ! TYPE_SIZE (base_t) = bitsize_zero_node; ! TYPE_SIZE_UNIT (base_t) = size_zero_node; ! if (warn_abi && !integer_zerop (rli_size_unit_so_far (rli))) ! warning ("layout of classes derived from empty class `%T' " ! "may change in a future version of GCC", ! t); ! } ! else ! { ! tree eoc; ! ! /* If the ABI version is not at least two, and the last ! field was a bit-field, RLI may not be on a byte ! boundary. In particular, rli_size_unit_so_far might ! indicate the last complete byte, while rli_size_so_far ! indicates the total number of bits used. Therefore, ! rli_size_so_far, rather than rli_size_unit_so_far, is ! used to compute TYPE_SIZE_UNIT. */ ! eoc = end_of_class (t, /*include_virtuals_p=*/0); ! TYPE_SIZE_UNIT (base_t) ! = size_binop (MAX_EXPR, ! convert (sizetype, ! size_binop (CEIL_DIV_EXPR, ! rli_size_so_far (rli), ! bitsize_int (BITS_PER_UNIT))), ! eoc); ! TYPE_SIZE (base_t) ! = size_binop (MAX_EXPR, ! rli_size_so_far (rli), ! size_binop (MULT_EXPR, ! convert (bitsizetype, eoc), ! bitsize_int (BITS_PER_UNIT))); ! } ! TYPE_ALIGN (base_t) = rli->record_align; ! TYPE_USER_ALIGN (base_t) = TYPE_USER_ALIGN (t); ! ! /* Copy the fields from T. */ ! next_field = &TYPE_FIELDS (base_t); ! for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) ! if (TREE_CODE (field) == FIELD_DECL) ! { ! *next_field = build_decl (FIELD_DECL, ! DECL_NAME (field), ! TREE_TYPE (field)); ! DECL_CONTEXT (*next_field) = base_t; ! DECL_FIELD_OFFSET (*next_field) = DECL_FIELD_OFFSET (field); ! DECL_FIELD_BIT_OFFSET (*next_field) ! = DECL_FIELD_BIT_OFFSET (field); ! next_field = &TREE_CHAIN (*next_field); ! } ! ! /* Record the base version of the type. */ ! CLASSTYPE_AS_BASE (t) = base_t; ! TYPE_CONTEXT (base_t) = t; } else ! CLASSTYPE_AS_BASE (t) = t; /* Every empty class contains an empty class. */ ! if (CLASSTYPE_EMPTY_P (t)) CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1; /* Set the TYPE_DECL for this type to contain the right *************** layout_class_type (t, empty_p, vfuns_p, *** 4981,5034 **** around. We must get these done before we try to lay out the virtual function table. As a side-effect, this will remove the base subobject fields. */ ! layout_virtual_bases (t, empty_base_offsets); ! /* Warn about direct bases that can't be talked about due to ! ambiguity. */ ! warn_about_ambiguous_direct_bases (t); /* Clean up. */ splay_tree_delete (empty_base_offsets); } ! /* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration ! (or C++ class declaration). ! For C++, we must handle the building of derived classes. ! Also, C++ allows static class members. The way that this is ! handled is to keep the field name where it is (as the DECL_NAME ! of the field), and place the overloaded decl in the bit position ! of the field. layout_record and layout_union will know about this. ! More C++ hair: inline functions have text in their ! DECL_PENDING_INLINE_INFO nodes which must somehow be parsed into ! meaningful tree structure. After the struct has been laid out, set ! things up so that this can happen. ! And still more: virtual functions. In the case of single inheritance, ! when a new virtual function is seen which redefines a virtual function ! from the base class, the new virtual function is placed into ! the virtual function table at exactly the same address that ! it had in the base class. When this is extended to multiple ! inheritance, the same thing happens, except that multiple virtual ! function tables must be maintained. The first virtual function ! table is treated in exactly the same way as in the case of single ! inheritance. Additional virtual function tables have different ! DELTAs, which tell how to adjust `this' to point to the right thing. ! ATTRIBUTES is the set of decl attributes to be applied, if any. */ void finish_struct_1 (t) tree t; { tree x; ! int vfuns; ! /* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */ tree virtuals = NULL_TREE; int n_fields = 0; tree vfield; - int empty = 1; if (COMPLETE_TYPE_P (t)) { --- 5172,5234 ---- around. We must get these done before we try to lay out the virtual function table. As a side-effect, this will remove the base subobject fields. */ ! layout_virtual_bases (rli, empty_base_offsets); ! /* Make sure that empty classes are reflected in RLI at this ! point. */ ! include_empty_classes(rli); ! ! /* Make sure not to create any structures with zero size. */ ! if (integer_zerop (rli_size_unit_so_far (rli)) && CLASSTYPE_EMPTY_P (t)) ! place_field (rli, ! build_decl (FIELD_DECL, NULL_TREE, char_type_node)); ! ! /* Let the back-end lay out the type. */ ! finish_record_layout (rli, /*free_p=*/true); ! ! /* Warn about bases that can't be talked about due to ambiguity. */ ! warn_about_ambiguous_bases (t); /* Clean up. */ splay_tree_delete (empty_base_offsets); } ! /* Returns the virtual function with which the vtable for TYPE is ! emitted, or NULL_TREE if that heuristic is not applicable to TYPE. */ ! static tree ! key_method (tree type) ! { ! tree method; ! if (TYPE_FOR_JAVA (type) ! || processing_template_decl ! || CLASSTYPE_TEMPLATE_INSTANTIATION (type) ! || CLASSTYPE_INTERFACE_KNOWN (type)) ! return NULL_TREE; ! for (method = TYPE_METHODS (type); method != NULL_TREE; ! method = TREE_CHAIN (method)) ! if (DECL_VINDEX (method) != NULL_TREE ! && ! DECL_DECLARED_INLINE_P (method) ! && ! DECL_PURE_VIRTUAL_P (method)) ! return method; ! return NULL_TREE; ! } ! ! /* Perform processing required when the definition of T (a class type) ! is complete. */ void finish_struct_1 (t) tree t; { tree x; ! /* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */ tree virtuals = NULL_TREE; int n_fields = 0; tree vfield; if (COMPLETE_TYPE_P (t)) { *************** finish_struct_1 (t) *** 5045,5061 **** TYPE_SIZE (t) = NULL_TREE; CLASSTYPE_GOT_SEMICOLON (t) = 0; CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE; - vfuns = 0; - CLASSTYPE_RTTI (t) = NULL_TREE; fixup_inline_methods (t); /* Do end-of-class semantic processing: checking the validity of the bases and members and add implicitly generated methods. */ ! check_bases_and_members (t, &empty); /* Layout the class itself. */ ! layout_class_type (t, &empty, &vfuns, &virtuals); /* Make sure that we get our own copy of the vfield FIELD_DECL. */ vfield = TYPE_VFIELD (t); --- 5245,5276 ---- TYPE_SIZE (t) = NULL_TREE; CLASSTYPE_GOT_SEMICOLON (t) = 0; CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE; fixup_inline_methods (t); + /* Make assumptions about the class; we'll reset the flags if + necessary. */ + CLASSTYPE_EMPTY_P (t) = 1; + CLASSTYPE_NEARLY_EMPTY_P (t) = 1; + CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0; + /* Do end-of-class semantic processing: checking the validity of the bases and members and add implicitly generated methods. */ ! check_bases_and_members (t); ! ! /* Find the key method */ ! if (TYPE_CONTAINS_VPTR_P (t)) ! { ! CLASSTYPE_KEY_METHOD (t) = key_method (t); ! ! /* If a polymorphic class has no key method, we may emit the vtable ! in every translation unit where the class definition appears. */ ! if (CLASSTYPE_KEY_METHOD (t) == NULL_TREE) ! keyed_classes = tree_cons (NULL_TREE, t, keyed_classes); ! } /* Layout the class itself. */ ! layout_class_type (t, &virtuals); /* Make sure that we get our own copy of the vfield FIELD_DECL. */ vfield = TYPE_VFIELD (t); *************** finish_struct_1 (t) *** 5066,5072 **** my_friendly_assert (same_type_p (DECL_FIELD_CONTEXT (vfield), BINFO_TYPE (primary)), 20010726); ! /* The vtable better be at the start. */ my_friendly_assert (integer_zerop (DECL_FIELD_OFFSET (vfield)), 20010726); my_friendly_assert (integer_zerop (BINFO_OFFSET (primary)), --- 5281,5287 ---- my_friendly_assert (same_type_p (DECL_FIELD_CONTEXT (vfield), BINFO_TYPE (primary)), 20010726); ! /* The vtable better be at the start. */ my_friendly_assert (integer_zerop (DECL_FIELD_OFFSET (vfield)), 20010726); my_friendly_assert (integer_zerop (BINFO_OFFSET (primary)), *************** finish_struct_1 (t) *** 5079,5085 **** else my_friendly_assert (!vfield || DECL_FIELD_CONTEXT (vfield) == t, 20010726); ! virtuals = modify_all_vtables (t, &vfuns, nreverse (virtuals)); /* If we created a new vtbl pointer for this class, add it to the list. */ --- 5294,5300 ---- else my_friendly_assert (!vfield || DECL_FIELD_CONTEXT (vfield) == t, 20010726); ! virtuals = modify_all_vtables (t, nreverse (virtuals)); /* If we created a new vtbl pointer for this class, add it to the list. */ *************** finish_struct_1 (t) *** 5097,5124 **** /* Here we know enough to change the type of our virtual function table, but we will wait until later this function. */ build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t); - - /* If this type has basetypes with constructors, then those - constructors might clobber the virtual function table. But - they don't if the derived class shares the exact vtable of the base - class. */ - CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1; - } - /* If we didn't need a new vtable, see if we should copy one from - the base. */ - else if (CLASSTYPE_HAS_PRIMARY_BASE_P (t)) - { - tree binfo = CLASSTYPE_PRIMARY_BINFO (t); - - /* If this class uses a different vtable than its primary base - then when we will need to initialize our vptr after the base - class constructor runs. */ - if (TYPE_BINFO_VTABLE (t) != BINFO_VTABLE (binfo)) - CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1; } if (TYPE_CONTAINS_VPTR_P (t)) { if (TYPE_BINFO_VTABLE (t)) my_friendly_assert (DECL_VIRTUAL_P (TYPE_BINFO_VTABLE (t)), 20000116); --- 5312,5324 ---- /* Here we know enough to change the type of our virtual function table, but we will wait until later this function. */ build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t); } if (TYPE_CONTAINS_VPTR_P (t)) { + int vindex; + tree fn; + if (TYPE_BINFO_VTABLE (t)) my_friendly_assert (DECL_VIRTUAL_P (TYPE_BINFO_VTABLE (t)), 20000116); *************** finish_struct_1 (t) *** 5126,5134 **** my_friendly_assert (TYPE_BINFO_VIRTUALS (t) == NULL_TREE, 20000116); - CLASSTYPE_VSIZE (t) = vfuns; /* Add entries for virtual functions introduced by this class. */ TYPE_BINFO_VIRTUALS (t) = chainon (TYPE_BINFO_VIRTUALS (t), virtuals); } finish_struct_bits (t); --- 5326,5342 ---- my_friendly_assert (TYPE_BINFO_VIRTUALS (t) == NULL_TREE, 20000116); /* Add entries for virtual functions introduced by this class. */ TYPE_BINFO_VIRTUALS (t) = chainon (TYPE_BINFO_VIRTUALS (t), virtuals); + + /* Set DECL_VINDEX for all functions declared in this class. */ + for (vindex = 0, fn = BINFO_VIRTUALS (TYPE_BINFO (t)); + fn; + fn = TREE_CHAIN (fn), + vindex += (TARGET_VTABLE_USES_DESCRIPTORS + ? TARGET_VTABLE_USES_DESCRIPTORS : 1)) + if (TREE_CODE (DECL_VINDEX (BV_FN (fn))) != INTEGER_CST) + DECL_VINDEX (BV_FN (fn)) = build_shared_int_cst (vindex); } finish_struct_bits (t); *************** finish_struct_1 (t) *** 5143,5150 **** /* Done with FIELDS...now decide whether to sort these for faster lookups later. ! The C front-end only does this when n_fields > 15. We use ! a smaller number because most searches fail (succeeding ultimately as the search bores through the inheritance hierarchy), and we want this failure to occur quickly. */ --- 5351,5357 ---- /* Done with FIELDS...now decide whether to sort these for faster lookups later. ! We use a small number because most searches fail (succeeding ultimately as the search bores through the inheritance hierarchy), and we want this failure to occur quickly. */ *************** finish_struct_1 (t) *** 5164,5178 **** { tree vfields = CLASSTYPE_VFIELDS (t); ! while (vfields) ! { ! /* Mark the fact that constructor for T ! could affect anybody inheriting from T ! who wants to initialize vtables for VFIELDS's type. */ ! if (VF_DERIVED_VALUE (vfields)) ! TREE_ADDRESSABLE (vfields) = 1; ! vfields = TREE_CHAIN (vfields); ! } } /* Make the rtl for any new vtables we have created, and unmark --- 5371,5383 ---- { tree vfields = CLASSTYPE_VFIELDS (t); ! for (vfields = CLASSTYPE_VFIELDS (t); ! vfields; vfields = TREE_CHAIN (vfields)) ! /* Mark the fact that constructor for T could affect anybody ! inheriting from T who wants to initialize vtables for ! VFIELDS's type. */ ! if (VF_BINFO_VALUE (vfields)) ! TREE_ADDRESSABLE (vfields) = 1; } /* Make the rtl for any new vtables we have created, and unmark *************** unreverse_member_declarations (t) *** 5210,5219 **** tree prev; tree x; ! /* The TYPE_FIELDS, TYPE_METHODS, and CLASSTYPE_TAGS are all in ! reverse order. Put them in declaration order now. */ TYPE_METHODS (t) = nreverse (TYPE_METHODS (t)); CLASSTYPE_TAGS (t) = nreverse (CLASSTYPE_TAGS (t)); /* Actually, for the TYPE_FIELDS, only the non TYPE_DECLs are in reverse order, so we can't just use nreverse. */ --- 5415,5425 ---- tree prev; tree x; ! /* The following lists are all in reverse order. Put them in ! declaration order now. */ TYPE_METHODS (t) = nreverse (TYPE_METHODS (t)); CLASSTYPE_TAGS (t) = nreverse (CLASSTYPE_TAGS (t)); + CLASSTYPE_DECL_LIST (t) = nreverse (CLASSTYPE_DECL_LIST (t)); /* Actually, for the TYPE_FIELDS, only the non TYPE_DECLs are in reverse order, so we can't just use nreverse. */ *************** finish_struct (t, attributes) *** 5270,5281 **** else error ("trying to finish struct, but kicked out due to previous parse errors"); ! if (processing_template_decl) ! { ! tree scope = current_scope (); ! if (scope && TREE_CODE (scope) == FUNCTION_DECL) ! add_stmt (build_min (TAG_DEFN, t)); ! } return t; } --- 5476,5483 ---- else error ("trying to finish struct, but kicked out due to previous parse errors"); ! if (processing_template_decl && at_function_scope_p ()) ! add_stmt (build_min (TAG_DEFN, t)); return t; } *************** fixed_type_or_null (instance, nonnull, c *** 5371,5377 **** if (nonnull) *nonnull = 1; ! /* if we're in a ctor or dtor, we know our type. */ if (DECL_LANG_SPECIFIC (current_function_decl) && (DECL_CONSTRUCTOR_P (current_function_decl) || DECL_DESTRUCTOR_P (current_function_decl))) --- 5573,5579 ---- if (nonnull) *nonnull = 1; ! /* if we're in a ctor or dtor, we know our type. */ if (DECL_LANG_SPECIFIC (current_function_decl) && (DECL_CONSTRUCTOR_P (current_function_decl) || DECL_DESTRUCTOR_P (current_function_decl))) *************** fixed_type_or_null (instance, nonnull, c *** 5386,5396 **** /* Reference variables should be references to objects. */ if (nonnull) *nonnull = 1; ! ! if (TREE_CODE (instance) == VAR_DECL ! && DECL_INITIAL (instance)) ! return fixed_type_or_null (DECL_INITIAL (instance), ! nonnull, cdtorp); } return NULL_TREE; --- 5588,5608 ---- /* Reference variables should be references to objects. */ if (nonnull) *nonnull = 1; ! ! /* DECL_VAR_MARKED_P is used to prevent recursion; a ! variable's initializer may refer to the variable ! itself. */ ! if (TREE_CODE (instance) == VAR_DECL ! && DECL_INITIAL (instance) ! && !DECL_VAR_MARKED_P (instance)) ! { ! tree type; ! DECL_VAR_MARKED_P (instance) = 1; ! type = fixed_type_or_null (DECL_INITIAL (instance), ! nonnull, cdtorp); ! DECL_VAR_MARKED_P (instance) = 0; ! return type; ! } } return NULL_TREE; *************** fixed_type_or_null (instance, nonnull, c *** 5399,5405 **** } } ! /* Return non-zero if the dynamic type of INSTANCE is known, and equivalent to the static type. We also handle the case where INSTANCE is really a pointer. Return negative if this is a ctor/dtor. There the dynamic type is known, but this might not be --- 5611,5617 ---- } } ! /* Return nonzero if the dynamic type of INSTANCE is known, and equivalent to the static type. We also handle the case where INSTANCE is really a pointer. Return negative if this is a ctor/dtor. There the dynamic type is known, but this might not be *************** init_class_processing () *** 5441,5447 **** = (class_stack_node_t) xmalloc (current_class_stack_size * sizeof (struct class_stack_node)); VARRAY_TREE_INIT (local_classes, 8, "local_classes"); - ggc_add_tree_varray_root (&local_classes, 1); access_default_node = build_int_2 (0, 0); access_public_node = build_int_2 (ak_public, 0); --- 5653,5658 ---- *************** void *** 5598,5605 **** popclass () { poplevel_class (); - /* Since poplevel_class does the popping of class decls nowadays, - this really only frees the obstack used for these decls. */ pop_class_decls (); current_class_depth--; --- 5809,5814 ---- *************** push_lang_context (name) *** 5716,5722 **** /* DECL_IGNORED_P is initially set for these types, to avoid clutter. (See record_builtin_java_type in decl.c.) However, that causes incorrect debug entries if these types are actually used. ! So we re-enable debug output after extern "Java". */ DECL_IGNORED_P (TYPE_NAME (java_byte_type_node)) = 0; DECL_IGNORED_P (TYPE_NAME (java_short_type_node)) = 0; DECL_IGNORED_P (TYPE_NAME (java_int_type_node)) = 0; --- 5925,5931 ---- /* DECL_IGNORED_P is initially set for these types, to avoid clutter. (See record_builtin_java_type in decl.c.) However, that causes incorrect debug entries if these types are actually used. ! So we re-enable debug output after extern "Java". */ DECL_IGNORED_P (TYPE_NAME (java_byte_type_node)) = 0; DECL_IGNORED_P (TYPE_NAME (java_short_type_node)) = 0; DECL_IGNORED_P (TYPE_NAME (java_int_type_node)) = 0; *************** pop_lang_context () *** 5748,5754 **** /* Given an OVERLOAD and a TARGET_TYPE, return the function that matches the TARGET_TYPE. If there is no satisfactory match, return error_mark_node, and issue an error message if COMPLAIN is ! non-zero. Permit pointers to member function if PTRMEM is non-zero. If TEMPLATE_ONLY, the name of the overloaded function was a template-id, and EXPLICIT_TARGS are the explicitly provided template arguments. */ --- 5957,5963 ---- /* Given an OVERLOAD and a TARGET_TYPE, return the function that matches the TARGET_TYPE. If there is no satisfactory match, return error_mark_node, and issue an error message if COMPLAIN is ! nonzero. Permit pointers to member function if PTRMEM is nonzero. If TEMPLATE_ONLY, the name of the overloaded function was a template-id, and EXPLICIT_TARGS are the explicitly provided template arguments. */ *************** cannot resolve overloaded function `%D' *** 6013,6019 **** /* The target must be a REFERENCE_TYPE. Above, build_unary_op will mark the function as addressed, but here we must do it explicitly. */ ! mark_addressable (fn); return fn; } --- 6222,6228 ---- /* The target must be a REFERENCE_TYPE. Above, build_unary_op will mark the function as addressed, but here we must do it explicitly. */ ! cxx_mark_addressable (fn); return fn; } *************** instantiate_type (lhstype, rhs, flags) *** 6058,6063 **** --- 6267,6275 ---- return error_mark_node; } + if (TREE_CODE (rhs) == BASELINK) + rhs = BASELINK_FUNCTIONS (rhs); + /* We don't overwrite rhs if it is an overloaded function. Copying it would destroy the tree link. */ if (TREE_CODE (rhs) != OVERLOAD) *************** instantiate_type (lhstype, rhs, flags) *** 6104,6110 **** case OFFSET_REF: rhs = TREE_OPERAND (rhs, 1); if (BASELINK_P (rhs)) ! return instantiate_type (lhstype, TREE_VALUE (rhs), flags | allow_ptrmem); /* This can happen if we are forming a pointer-to-member for a --- 6316,6322 ---- case OFFSET_REF: rhs = TREE_OPERAND (rhs, 1); if (BASELINK_P (rhs)) ! return instantiate_type (lhstype, BASELINK_FUNCTIONS (rhs), flags | allow_ptrmem); /* This can happen if we are forming a pointer-to-member for a *************** instantiate_type (lhstype, rhs, flags) *** 6137,6146 **** /*explicit_targs=*/NULL_TREE); case TREE_LIST: ! /* Now we should have a baselink. */ my_friendly_assert (BASELINK_P (rhs), 990412); ! return instantiate_type (lhstype, TREE_VALUE (rhs), flags); case CALL_EXPR: /* This is too hard for now. */ --- 6349,6358 ---- /*explicit_targs=*/NULL_TREE); case TREE_LIST: ! /* Now we should have a baselink. */ my_friendly_assert (BASELINK_P (rhs), 990412); ! return instantiate_type (lhstype, BASELINK_FUNCTIONS (rhs), flags); case CALL_EXPR: /* This is too hard for now. */ *************** is_empty_class (type) *** 6345,6351 **** if (! IS_AGGR_TYPE (type)) return 0; ! return integer_zerop (CLASSTYPE_SIZE (type)); } /* Find the enclosing class of the given NODE. NODE can be a *_DECL or --- 6557,6594 ---- if (! IS_AGGR_TYPE (type)) return 0; ! /* In G++ 3.2, whether or not a class was empty was determined by ! looking at its size. */ ! if (abi_version_at_least (2)) ! return CLASSTYPE_EMPTY_P (type); ! else ! return integer_zerop (CLASSTYPE_SIZE (type)); ! } ! ! /* Returns true if TYPE contains an empty class. */ ! ! static bool ! contains_empty_class_p (tree type) ! { ! if (is_empty_class (type)) ! return true; ! if (CLASS_TYPE_P (type)) ! { ! tree field; ! int i; ! ! for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); ++i) ! if (contains_empty_class_p (TYPE_BINFO_BASETYPE (type, i))) ! return true; ! for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) ! if (TREE_CODE (field) == FIELD_DECL ! && !DECL_ARTIFICIAL (field) ! && is_empty_class (TREE_TYPE (field))) ! return true; ! } ! else if (TREE_CODE (type) == ARRAY_TYPE) ! return contains_empty_class_p (TREE_TYPE (type)); ! return false; } /* Find the enclosing class of the given NODE. NODE can be a *_DECL or *************** maybe_note_name_used_in_class (name, dec *** 6424,6430 **** } /* Note that NAME was declared (as DECL) in the current class. Check ! to see that the declaration is legal. */ void note_name_declared_in_class (name, decl) --- 6667,6673 ---- } /* Note that NAME was declared (as DECL) in the current class. Check ! to see that the declaration is valid. */ void note_name_declared_in_class (name, decl) *************** get_vtbl_decl_for_binfo (binfo) *** 6479,6485 **** /* Called from get_primary_binfo via dfs_walk. DATA is a TREE_LIST who's TREE_PURPOSE is the TYPE of the required primary base and ! who's TREE_VALUE is a list of candidate binfos that we fill in. */ static tree dfs_get_primary_binfo (binfo, data) --- 6722,6728 ---- /* Called from get_primary_binfo via dfs_walk. DATA is a TREE_LIST who's TREE_PURPOSE is the TYPE of the required primary base and ! who's TREE_VALUE is a list of candidate binfos that we fill in. */ static tree dfs_get_primary_binfo (binfo, data) *************** get_primary_binfo (binfo) *** 6586,6592 **** return result; } ! /* If INDENTED_P is zero, indent to INDENT. Return non-zero. */ static int maybe_indent_hierarchy (stream, indent, indented_p) --- 6829,6835 ---- return result; } ! /* If INDENTED_P is zero, indent to INDENT. Return nonzero. */ static int maybe_indent_hierarchy (stream, indent, indented_p) *************** initialize_array (decl, inits) *** 6876,6881 **** --- 7119,7125 ---- context = DECL_CONTEXT (decl); DECL_CONTEXT (decl) = NULL_TREE; DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, inits); + TREE_HAS_CONSTRUCTOR (DECL_INITIAL (decl)) = 1; cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0); DECL_CONTEXT (decl) = context; } *************** build_vtt (t) *** 6917,6924 **** /* Now, build the VTT object itself. */ vtt = build_vtable (t, get_vtt_name (t), type); - pushdecl_top_level (vtt); initialize_array (vtt, inits); dump_vtt (t, vtt); } --- 7161,7170 ---- /* Now, build the VTT object itself. */ vtt = build_vtable (t, get_vtt_name (t), type); initialize_array (vtt, inits); + /* Add the VTT to the vtables list. */ + TREE_CHAIN (vtt) = TREE_CHAIN (CLASSTYPE_VTABLES (t)); + TREE_CHAIN (CLASSTYPE_VTABLES (t)) = vtt; dump_vtt (t, vtt); } *************** get_original_base (base_binfo, binfo) *** 6953,6959 **** /* When building a secondary VTT, BINFO_VTABLE is set to a TREE_LIST with PURPOSE the RTTI_BINFO, VALUE the real vtable pointer for this binfo, and CHAIN the vtable pointer for this binfo after construction is ! complete. VALUE can also be another BINFO, in which case we recurse. */ static tree binfo_ctor_vtable (binfo) --- 7199,7205 ---- /* When building a secondary VTT, BINFO_VTABLE is set to a TREE_LIST with PURPOSE the RTTI_BINFO, VALUE the real vtable pointer for this binfo, and CHAIN the vtable pointer for this binfo after construction is ! complete. VALUE can also be another BINFO, in which case we recurse. */ static tree binfo_ctor_vtable (binfo) *************** dfs_build_secondary_vptr_vtt_inits (binf *** 7144,7150 **** { /* It's a primary virtual base, and this is not the construction vtable. Find the base this is primary of in the inheritance graph, ! and use that base's vtable now. */ while (BINFO_PRIMARY_BASE_OF (binfo)) binfo = BINFO_PRIMARY_BASE_OF (binfo); } --- 7390,7396 ---- { /* It's a primary virtual base, and this is not the construction vtable. Find the base this is primary of in the inheritance graph, ! and use that base's vtable now. */ while (BINFO_PRIMARY_BASE_OF (binfo)) binfo = BINFO_PRIMARY_BASE_OF (binfo); } *************** build_ctor_vtbl_group (binfo, t) *** 7253,7259 **** TREE_TYPE (vtbl) = type; /* Initialize the construction vtable. */ ! pushdecl_top_level (vtbl); initialize_array (vtbl, inits); dump_vtable (t, binfo, vtbl); } --- 7499,7505 ---- TREE_TYPE (vtbl) = type; /* Initialize the construction vtable. */ ! CLASSTYPE_VTABLES (t) = chainon (CLASSTYPE_VTABLES (t), vtbl); initialize_array (vtbl, inits); dump_vtable (t, binfo, vtbl); } *************** accumulate_vtbl_inits (binfo, orig_binfo *** 7283,7289 **** BINFO_TYPE (orig_binfo)), 20000517); ! /* If it doesn't have a vptr, we don't do anything. */ if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo))) return; --- 7529,7535 ---- BINFO_TYPE (orig_binfo)), 20000517); ! /* If it doesn't have a vptr, we don't do anything. */ if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo))) return; *************** build_vtbl_initializer (binfo, orig_binf *** 7470,7477 **** vid.last_init = &vid.inits; vid.primary_vtbl_p = (binfo == TYPE_BINFO (t)); vid.ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t); /* The first vbase or vcall offset is at index -3 in the vtable. */ ! vid.index = ssize_int (-3); /* Add entries to the vtable for RTTI. */ build_rtti_vtbl_entries (binfo, &vid); --- 7716,7724 ---- vid.last_init = &vid.inits; vid.primary_vtbl_p = (binfo == TYPE_BINFO (t)); vid.ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t); + vid.generate_vcall_entries = true; /* The first vbase or vcall offset is at index -3 in the vtable. */ ! vid.index = ssize_int (-3 * TARGET_VTABLE_DATA_ENTRY_DISTANCE); /* Add entries to the vtable for RTTI. */ build_rtti_vtbl_entries (binfo, &vid); *************** build_vtbl_initializer (binfo, orig_binf *** 7482,7489 **** VARRAY_TREE_INIT (vid.fns, 32, "fns"); /* Add the vcall and vbase offset entries. */ build_vcall_and_vbase_vtbl_entries (binfo, &vid); - /* Clean up. */ - VARRAY_FREE (vid.fns); /* Clear BINFO_VTABLE_PATH_MARKED; it's set by build_vbase_offset_vtbl_entries. */ for (vbase = CLASSTYPE_VBASECLASSES (t); --- 7729,7734 ---- *************** build_vtbl_initializer (binfo, orig_binf *** 7491,7496 **** --- 7736,7760 ---- vbase = TREE_CHAIN (vbase)) CLEAR_BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase)); + /* If the target requires padding between data entries, add that now. */ + if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1) + { + tree cur, *prev; + + for (prev = &vid.inits; (cur = *prev); prev = &TREE_CHAIN (cur)) + { + tree add = cur; + int i; + + for (i = 1; i < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++i) + add = tree_cons (NULL_TREE, + build1 (NOP_EXPR, vtable_entry_type, + null_pointer_node), + add); + *prev = add; + } + } + if (non_fn_entries_p) *non_fn_entries_p = list_length (vid.inits); *************** build_vtbl_initializer (binfo, orig_binf *** 7502,7508 **** tree delta; tree vcall_index; tree fn; - tree pfn; tree init = NULL_TREE; fn = BV_FN (v); --- 7766,7771 ---- *************** build_vtbl_initializer (binfo, orig_binf *** 7537,7550 **** /* Pull the offset for `this', and the function to call, out of the list. */ delta = BV_DELTA (v); ! ! if (BV_USE_VCALL_INDEX_P (v)) ! { ! vcall_index = BV_VCALL_INDEX (v); ! my_friendly_assert (vcall_index != NULL_TREE, 20000621); ! } ! else ! vcall_index = NULL_TREE; my_friendly_assert (TREE_CODE (delta) == INTEGER_CST, 19990727); my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 19990727); --- 7800,7806 ---- /* Pull the offset for `this', and the function to call, out of the list. */ delta = BV_DELTA (v); ! vcall_index = BV_VCALL_INDEX (v); my_friendly_assert (TREE_CODE (delta) == INTEGER_CST, 19990727); my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 19990727); *************** build_vtbl_initializer (binfo, orig_binf *** 7553,7567 **** So, we replace these functions with __pure_virtual. */ if (DECL_PURE_VIRTUAL_P (fn)) fn = abort_fndecl; ! /* Take the address of the function, considering it to be of an appropriate generic type. */ ! pfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn); /* The address of a function can't change. */ ! TREE_CONSTANT (pfn) = 1; ! ! /* Enter it in the vtable. */ ! init = build_vtable_entry (delta, vcall_index, pfn); } /* And add it to the chain of initializers. */ --- 7809,7821 ---- So, we replace these functions with __pure_virtual. */ if (DECL_PURE_VIRTUAL_P (fn)) fn = abort_fndecl; ! else if (!integer_zerop (delta) || vcall_index) ! fn = make_thunk (fn, delta, vcall_index); /* Take the address of the function, considering it to be of an appropriate generic type. */ ! init = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn); /* The address of a function can't change. */ ! TREE_CONSTANT (init) = 1; } /* And add it to the chain of initializers. */ *************** build_vbase_offset_vtbl_entries (binfo, *** 7708,7714 **** } /* The next vbase will come at a more negative offset. */ ! vid->index = size_binop (MINUS_EXPR, vid->index, ssize_int (1)); /* The initializer is the delta from BINFO to this virtual base. The vbase offsets go in reverse inheritance-graph order, and --- 7962,7969 ---- } /* The next vbase will come at a more negative offset. */ ! vid->index = size_binop (MINUS_EXPR, vid->index, ! ssize_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE)); /* The initializer is the delta from BINFO to this virtual base. The vbase offsets go in reverse inheritance-graph order, and *************** build_vcall_offset_vtbl_entries (binfo, *** 7734,7764 **** tree binfo; vtbl_init_data *vid; { ! /* We only need these entries if this base is a virtual base. */ ! if (!TREE_VIA_VIRTUAL (binfo)) ! return; ! ! /* We need a vcall offset for each of the virtual functions in this ! vtable. For example: ! class A { virtual void f (); }; ! class B1 : virtual public A { virtual void f (); }; ! class B2 : virtual public A { virtual void f (); }; ! class C: public B1, public B2 { virtual void f (); }; ! A C object has a primary base of B1, which has a primary base of A. A ! C also has a secondary base of B2, which no longer has a primary base ! of A. So the B2-in-C construction vtable needs a secondary vtable for ! A, which will adjust the A* to a B2* to call f. We have no way of ! knowing what (or even whether) this offset will be when we define B2, ! so we store this "vcall offset" in the A sub-vtable and look it up in ! a "virtual thunk" for B2::f. ! We need entries for all the functions in our primary vtable and ! in our non-virtual bases' secondary vtables. */ ! vid->vbase = binfo; ! /* Now, walk through the non-virtual bases, adding vcall offsets. */ ! add_vcall_offset_vtbl_entries_r (binfo, vid); } /* Build vcall offsets, starting with those for BINFO. */ --- 7989,8025 ---- tree binfo; vtbl_init_data *vid; { ! /* We only need these entries if this base is a virtual base. We ! compute the indices -- but do not add to the vtable -- when ! building the main vtable for a class. */ ! if (TREE_VIA_VIRTUAL (binfo) || binfo == TYPE_BINFO (vid->derived)) ! { ! /* We need a vcall offset for each of the virtual functions in this ! vtable. For example: ! class A { virtual void f (); }; ! class B1 : virtual public A { virtual void f (); }; ! class B2 : virtual public A { virtual void f (); }; ! class C: public B1, public B2 { virtual void f (); }; ! A C object has a primary base of B1, which has a primary base of A. A ! C also has a secondary base of B2, which no longer has a primary base ! of A. So the B2-in-C construction vtable needs a secondary vtable for ! A, which will adjust the A* to a B2* to call f. We have no way of ! knowing what (or even whether) this offset will be when we define B2, ! so we store this "vcall offset" in the A sub-vtable and look it up in ! a "virtual thunk" for B2::f. ! We need entries for all the functions in our primary vtable and ! in our non-virtual bases' secondary vtables. */ ! vid->vbase = binfo; ! /* If we are just computing the vcall indices -- but do not need ! the actual entries -- not that. */ ! if (!TREE_VIA_VIRTUAL (binfo)) ! vid->generate_vcall_entries = false; ! /* Now, walk through the non-virtual bases, adding vcall offsets. */ ! add_vcall_offset_vtbl_entries_r (binfo, vid); ! } } /* Build vcall offsets, starting with those for BINFO. */ *************** add_vcall_offset_vtbl_entries_1 (binfo, *** 7804,7939 **** tree binfo; vtbl_init_data* vid; { ! tree derived_virtuals; ! tree base_virtuals; ! tree orig_virtuals; ! tree binfo_inits; ! /* If BINFO is a primary base, the most derived class which has BINFO as ! a primary base; otherwise, just BINFO. */ ! tree non_primary_binfo; ! ! binfo_inits = NULL_TREE; ! /* We might be a primary base class. Go up the inheritance hierarchy ! until we find the most derived class of which we are a primary base: ! it is the BINFO_VIRTUALS there that we need to consider. */ ! non_primary_binfo = binfo; ! while (BINFO_INHERITANCE_CHAIN (non_primary_binfo)) { ! tree b; ! /* If we have reached a virtual base, then it must be vid->vbase, ! because we ignore other virtual bases in ! add_vcall_offset_vtbl_entries_r. In turn, it must be a primary ! base (possibly multi-level) of vid->binfo, or we wouldn't ! have called build_vcall_and_vbase_vtbl_entries for it. But it ! might be a lost primary, so just skip down to vid->binfo. */ ! if (TREE_VIA_VIRTUAL (non_primary_binfo)) { ! if (non_primary_binfo != vid->vbase) ! abort (); ! non_primary_binfo = vid->binfo; ! break; } ! b = BINFO_INHERITANCE_CHAIN (non_primary_binfo); ! if (get_primary_binfo (b) != non_primary_binfo) ! break; ! non_primary_binfo = b; } ! if (vid->ctor_vtbl_p) ! /* For a ctor vtable we need the equivalent binfo within the hierarchy ! where rtti_binfo is the most derived type. */ ! non_primary_binfo = get_original_base ! (non_primary_binfo, TYPE_BINFO (BINFO_TYPE (vid->rtti_binfo))); ! /* Make entries for the rest of the virtuals. */ ! for (base_virtuals = BINFO_VIRTUALS (binfo), ! derived_virtuals = BINFO_VIRTUALS (non_primary_binfo), ! orig_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo))); ! base_virtuals; ! base_virtuals = TREE_CHAIN (base_virtuals), ! derived_virtuals = TREE_CHAIN (derived_virtuals), ! orig_virtuals = TREE_CHAIN (orig_virtuals)) { ! tree orig_fn; ! tree fn; ! tree base; ! tree base_binfo; ! size_t i; ! tree vcall_offset; ! /* Find the declaration that originally caused this function to ! be present in BINFO_TYPE (binfo). */ ! orig_fn = BV_FN (orig_virtuals); ! /* When processing BINFO, we only want to generate vcall slots for ! function slots introduced in BINFO. So don't try to generate ! one if the function isn't even defined in BINFO. */ ! if (!same_type_p (DECL_CONTEXT (orig_fn), BINFO_TYPE (binfo))) ! continue; ! /* Find the overriding function. */ ! fn = BV_FN (derived_virtuals); ! /* If there is already an entry for a function with the same ! signature as FN, then we do not need a second vcall offset. ! Check the list of functions already present in the derived ! class vtable. */ ! for (i = 0; i < VARRAY_ACTIVE_SIZE (vid->fns); ++i) ! { ! tree derived_entry; ! derived_entry = VARRAY_TREE (vid->fns, i); ! if (same_signature_p (BV_FN (derived_entry), fn) ! /* We only use one vcall offset for virtual destructors, ! even though there are two virtual table entries. */ ! || (DECL_DESTRUCTOR_P (BV_FN (derived_entry)) ! && DECL_DESTRUCTOR_P (fn))) ! { ! if (!vid->ctor_vtbl_p) ! BV_VCALL_INDEX (derived_virtuals) ! = BV_VCALL_INDEX (derived_entry); ! break; ! } ! } ! if (i != VARRAY_ACTIVE_SIZE (vid->fns)) ! continue; ! /* The FN comes from BASE. So, we must calculate the adjustment from ! vid->vbase to BASE. We can just look for BASE in the complete ! object because we are converting from a virtual base, so if there ! were multiple copies, there would not be a unique final overrider ! and vid->derived would be ill-formed. */ ! base = DECL_CONTEXT (fn); ! base_binfo = lookup_base (vid->derived, base, ba_any, NULL); ! /* Compute the vcall offset. */ ! /* As mentioned above, the vbase we're working on is a primary base of ! vid->binfo. But it might be a lost primary, so its BINFO_OFFSET ! might be wrong, so we just use the BINFO_OFFSET from vid->binfo. */ ! vcall_offset = BINFO_OFFSET (vid->binfo); ! vcall_offset = size_diffop (BINFO_OFFSET (base_binfo), ! vcall_offset); ! vcall_offset = fold (build1 (NOP_EXPR, vtable_entry_type, ! vcall_offset)); ! *vid->last_init = build_tree_list (NULL_TREE, vcall_offset); vid->last_init = &TREE_CHAIN (*vid->last_init); - - /* Keep track of the vtable index where this vcall offset can be - found. For a construction vtable, we already made this - annotation when we built the original vtable. */ - if (!vid->ctor_vtbl_p) - BV_VCALL_INDEX (derived_virtuals) = vid->index; - - /* The next vcall offset will be found at a more negative - offset. */ - vid->index = size_binop (MINUS_EXPR, vid->index, ssize_int (1)); - - /* Keep track of this function. */ - VARRAY_PUSH_TREE (vid->fns, derived_virtuals); } } --- 8065,8218 ---- tree binfo; vtbl_init_data* vid; { ! /* Make entries for the rest of the virtuals. */ ! if (abi_version_at_least (2)) ! { ! tree orig_fn; ! /* The ABI requires that the methods be processed in declaration ! order. G++ 3.2 used the order in the vtable. */ ! for (orig_fn = TYPE_METHODS (BINFO_TYPE (binfo)); ! orig_fn; ! orig_fn = TREE_CHAIN (orig_fn)) ! if (DECL_VINDEX (orig_fn)) ! add_vcall_offset (orig_fn, binfo, vid); ! } ! else { ! tree derived_virtuals; ! tree base_virtuals; ! tree orig_virtuals; ! /* If BINFO is a primary base, the most derived class which has ! BINFO as a primary base; otherwise, just BINFO. */ ! tree non_primary_binfo; ! /* We might be a primary base class. Go up the inheritance hierarchy ! until we find the most derived class of which we are a primary base: ! it is the BINFO_VIRTUALS there that we need to consider. */ ! non_primary_binfo = binfo; ! while (BINFO_INHERITANCE_CHAIN (non_primary_binfo)) { ! tree b; ! ! /* If we have reached a virtual base, then it must be vid->vbase, ! because we ignore other virtual bases in ! add_vcall_offset_vtbl_entries_r. In turn, it must be a primary ! base (possibly multi-level) of vid->binfo, or we wouldn't ! have called build_vcall_and_vbase_vtbl_entries for it. But it ! might be a lost primary, so just skip down to vid->binfo. */ ! if (TREE_VIA_VIRTUAL (non_primary_binfo)) ! { ! if (non_primary_binfo != vid->vbase) ! abort (); ! non_primary_binfo = vid->binfo; ! break; ! } ! ! b = BINFO_INHERITANCE_CHAIN (non_primary_binfo); ! if (get_primary_binfo (b) != non_primary_binfo) ! break; ! non_primary_binfo = b; } ! if (vid->ctor_vtbl_p) ! /* For a ctor vtable we need the equivalent binfo within the hierarchy ! where rtti_binfo is the most derived type. */ ! non_primary_binfo = get_original_base ! (non_primary_binfo, TYPE_BINFO (BINFO_TYPE (vid->rtti_binfo))); ! ! for (base_virtuals = BINFO_VIRTUALS (binfo), ! derived_virtuals = BINFO_VIRTUALS (non_primary_binfo), ! orig_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo))); ! base_virtuals; ! base_virtuals = TREE_CHAIN (base_virtuals), ! derived_virtuals = TREE_CHAIN (derived_virtuals), ! orig_virtuals = TREE_CHAIN (orig_virtuals)) ! { ! tree orig_fn; ! ! /* Find the declaration that originally caused this function to ! be present in BINFO_TYPE (binfo). */ ! orig_fn = BV_FN (orig_virtuals); ! ! /* When processing BINFO, we only want to generate vcall slots for ! function slots introduced in BINFO. So don't try to generate ! one if the function isn't even defined in BINFO. */ ! if (!same_type_p (DECL_CONTEXT (orig_fn), BINFO_TYPE (binfo))) ! continue; ! ! add_vcall_offset (orig_fn, binfo, vid); ! } } + } ! /* Add a vcall offset entry for ORIG_FN to the vtable. */ ! static void ! add_vcall_offset (tree orig_fn, tree binfo, vtbl_init_data *vid) ! { ! size_t i; ! tree vcall_offset; ! ! /* If there is already an entry for a function with the same ! signature as FN, then we do not need a second vcall offset. ! Check the list of functions already present in the derived ! class vtable. */ ! for (i = 0; i < VARRAY_ACTIVE_SIZE (vid->fns); ++i) { ! tree derived_entry; ! derived_entry = VARRAY_TREE (vid->fns, i); ! if (same_signature_p (derived_entry, orig_fn) ! /* We only use one vcall offset for virtual destructors, ! even though there are two virtual table entries. */ ! || (DECL_DESTRUCTOR_P (derived_entry) ! && DECL_DESTRUCTOR_P (orig_fn))) ! return; ! } ! /* If we are building these vcall offsets as part of building ! the vtable for the most derived class, remember the vcall ! offset. */ ! if (vid->binfo == TYPE_BINFO (vid->derived)) ! CLASSTYPE_VCALL_INDICES (vid->derived) ! = tree_cons (orig_fn, vid->index, ! CLASSTYPE_VCALL_INDICES (vid->derived)); ! /* The next vcall offset will be found at a more negative ! offset. */ ! vid->index = size_binop (MINUS_EXPR, vid->index, ! ssize_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE)); ! /* Keep track of this function. */ ! VARRAY_PUSH_TREE (vid->fns, orig_fn); ! if (vid->generate_vcall_entries) ! { ! tree base; ! tree fn; ! /* Find the overriding function. */ ! fn = find_final_overrider (vid->rtti_binfo, binfo, orig_fn); ! if (fn == error_mark_node) ! vcall_offset = build1 (NOP_EXPR, vtable_entry_type, ! integer_zero_node); ! else ! { ! base = TREE_VALUE (fn); ! /* The vbase we're working on is a primary base of ! vid->binfo. But it might be a lost primary, so its ! BINFO_OFFSET might be wrong, so we just use the ! BINFO_OFFSET from vid->binfo. */ ! vcall_offset = size_diffop (BINFO_OFFSET (base), ! BINFO_OFFSET (vid->binfo)); ! vcall_offset = fold (build1 (NOP_EXPR, vtable_entry_type, ! vcall_offset)); ! } ! /* Add the intiailizer to the vtable. */ *vid->last_init = build_tree_list (NULL_TREE, vcall_offset); vid->last_init = &TREE_CHAIN (*vid->last_init); } } *************** build_rtti_vtbl_entries (binfo, vid) *** 7972,8023 **** /* The second entry is the address of the typeinfo object. */ if (flag_rtti) ! decl = build_unary_op (ADDR_EXPR, get_tinfo_decl (t), 0); else decl = integer_zero_node; /* Convert the declaration to a type that can be stored in the vtable. */ ! init = build1 (NOP_EXPR, vfunc_ptr_type_node, decl); ! TREE_CONSTANT (init) = 1; *vid->last_init = build_tree_list (NULL_TREE, init); vid->last_init = &TREE_CHAIN (*vid->last_init); /* Add the offset-to-top entry. It comes earlier in the vtable that the the typeinfo entry. Convert the offset to look like a function pointer, so that we can put it in the vtable. */ ! init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset); ! TREE_CONSTANT (init) = 1; *vid->last_init = build_tree_list (NULL_TREE, init); vid->last_init = &TREE_CHAIN (*vid->last_init); } - - /* Build an entry in the virtual function table. DELTA is the offset - for the `this' pointer. VCALL_INDEX is the vtable index containing - the vcall offset; NULL_TREE if none. ENTRY is the virtual function - table entry itself. It's TREE_TYPE must be VFUNC_PTR_TYPE_NODE, - but it may not actually be a virtual function table pointer. (For - example, it might be the address of the RTTI object, under the new - ABI.) */ - - static tree - build_vtable_entry (delta, vcall_index, entry) - tree delta; - tree vcall_index; - tree entry; - { - tree fn = TREE_OPERAND (entry, 0); - - if ((!integer_zerop (delta) || vcall_index != NULL_TREE) - && fn != abort_fndecl) - { - entry = make_thunk (entry, delta, vcall_index); - entry = build1 (ADDR_EXPR, vtable_entry_type, entry); - TREE_READONLY (entry) = 1; - TREE_CONSTANT (entry) = 1; - } - #ifdef GATHER_STATISTICS - n_vtable_entries += 1; - #endif - return entry; - } --- 8251,8270 ---- /* The second entry is the address of the typeinfo object. */ if (flag_rtti) ! decl = build_address (get_tinfo_decl (t)); else decl = integer_zero_node; /* Convert the declaration to a type that can be stored in the vtable. */ ! init = build_nop (vfunc_ptr_type_node, decl); *vid->last_init = build_tree_list (NULL_TREE, init); vid->last_init = &TREE_CHAIN (*vid->last_init); /* Add the offset-to-top entry. It comes earlier in the vtable that the the typeinfo entry. Convert the offset to look like a function pointer, so that we can put it in the vtable. */ ! init = build_nop (vfunc_ptr_type_node, offset); *vid->last_init = build_tree_list (NULL_TREE, init); vid->last_init = &TREE_CHAIN (*vid->last_init); } diff -Nrc3pad gcc-3.2.3/gcc/cp/config-lang.in gcc-3.3/gcc/cp/config-lang.in *** gcc-3.2.3/gcc/cp/config-lang.in 2001-12-20 00:20:45.000000000 +0000 --- gcc-3.3/gcc/cp/config-lang.in 2002-07-14 01:59:14.000000000 +0000 *************** compilers="cc1plus\$(exeext)" *** 33,35 **** --- 33,37 ---- stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)" target_libs="${libstdcxx_version} target-gperf" + + gtfiles="\$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/parse.y \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/spew.c \$(srcdir)/cp/tree.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c" diff -Nrc3pad gcc-3.2.3/gcc/cp/cp-lang.c gcc-3.3/gcc/cp/cp-lang.c *** gcc-3.2.3/gcc/cp/cp-lang.c 2002-10-25 22:11:13.000000000 +0000 --- gcc-3.3/gcc/cp/cp-lang.c 2003-03-10 07:28:40.000000000 +0000 *************** Boston, MA 02111-1307, USA. */ *** 28,36 **** #include "langhooks.h" #include "langhooks-def.h" ! static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree)); ! static tree cp_expr_size PARAMS ((tree)); ! static bool cp_var_mod_type_p PARAMS ((tree)); #undef LANG_HOOKS_NAME #define LANG_HOOKS_NAME "GNU C++" --- 28,38 ---- #include "langhooks.h" #include "langhooks-def.h" ! static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree)); ! static bool ok_to_generate_alias_set_for_type PARAMS ((tree)); ! static bool cxx_warn_unused_global_decl PARAMS ((tree)); ! static tree cp_expr_size PARAMS ((tree)); ! static bool cp_var_mod_type_p PARAMS ((tree)); #undef LANG_HOOKS_NAME #define LANG_HOOKS_NAME "GNU C++" *************** static bool cp_var_mod_type_p PARAMS ( *** 43,57 **** #undef LANG_HOOKS_INIT_OPTIONS #define LANG_HOOKS_INIT_OPTIONS cxx_init_options #undef LANG_HOOKS_DECODE_OPTION ! #define LANG_HOOKS_DECODE_OPTION cxx_decode_option #undef LANG_HOOKS_POST_OPTIONS #define LANG_HOOKS_POST_OPTIONS c_common_post_options #undef LANG_HOOKS_GET_ALIAS_SET #define LANG_HOOKS_GET_ALIAS_SET cxx_get_alias_set #undef LANG_HOOKS_EXPAND_CONSTANT #define LANG_HOOKS_EXPAND_CONSTANT cplus_expand_constant #undef LANG_HOOKS_SAFE_FROM_P #define LANG_HOOKS_SAFE_FROM_P c_safe_from_p #undef LANG_HOOKS_PRINT_STATISTICS #define LANG_HOOKS_PRINT_STATISTICS cxx_print_statistics #undef LANG_HOOKS_PRINT_XNODE --- 45,79 ---- #undef LANG_HOOKS_INIT_OPTIONS #define LANG_HOOKS_INIT_OPTIONS cxx_init_options #undef LANG_HOOKS_DECODE_OPTION ! #define LANG_HOOKS_DECODE_OPTION c_common_decode_option #undef LANG_HOOKS_POST_OPTIONS #define LANG_HOOKS_POST_OPTIONS c_common_post_options #undef LANG_HOOKS_GET_ALIAS_SET #define LANG_HOOKS_GET_ALIAS_SET cxx_get_alias_set #undef LANG_HOOKS_EXPAND_CONSTANT #define LANG_HOOKS_EXPAND_CONSTANT cplus_expand_constant + #undef LANG_HOOKS_EXPAND_EXPR + #define LANG_HOOKS_EXPAND_EXPR cxx_expand_expr #undef LANG_HOOKS_SAFE_FROM_P #define LANG_HOOKS_SAFE_FROM_P c_safe_from_p + #undef LANG_HOOKS_PARSE_FILE + #define LANG_HOOKS_PARSE_FILE c_common_parse_file + #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL + #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL cxx_dup_lang_specific_decl + #undef LANG_HOOKS_UNSAVE_EXPR_NOW + #define LANG_HOOKS_UNSAVE_EXPR_NOW cxx_unsave_expr_now + #undef LANG_HOOKS_MAYBE_BUILD_CLEANUP + #define LANG_HOOKS_MAYBE_BUILD_CLEANUP cxx_maybe_build_cleanup + #undef LANG_HOOKS_TRUTHVALUE_CONVERSION + #define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion + #undef LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES + #define LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES cxx_insert_default_attributes + #undef LANG_HOOKS_UNSAFE_FOR_REEVAL + #define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval + #undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME + #define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME mangle_decl + #undef LANG_HOOKS_MARK_ADDRESSABLE + #define LANG_HOOKS_MARK_ADDRESSABLE cxx_mark_addressable #undef LANG_HOOKS_PRINT_STATISTICS #define LANG_HOOKS_PRINT_STATISTICS cxx_print_statistics #undef LANG_HOOKS_PRINT_XNODE *************** static bool cp_var_mod_type_p PARAMS ( *** 62,69 **** #define LANG_HOOKS_PRINT_TYPE cxx_print_type #undef LANG_HOOKS_PRINT_IDENTIFIER #define LANG_HOOKS_PRINT_IDENTIFIER cxx_print_identifier ! #undef LANG_HOOKS_SET_YYDEBUG ! #define LANG_HOOKS_SET_YYDEBUG cxx_set_yydebug #undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES #define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES \ --- 84,111 ---- #define LANG_HOOKS_PRINT_TYPE cxx_print_type #undef LANG_HOOKS_PRINT_IDENTIFIER #define LANG_HOOKS_PRINT_IDENTIFIER cxx_print_identifier ! #undef LANG_HOOKS_DECL_PRINTABLE_NAME ! #define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name ! #undef LANG_HOOKS_PRINT_ERROR_FUNCTION ! #define LANG_HOOKS_PRINT_ERROR_FUNCTION cxx_print_error_function ! #undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL ! #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl ! #undef LANG_HOOKS_WRITE_GLOBALS ! #define LANG_HOOKS_WRITE_GLOBALS lhd_do_nothing ! ! ! #undef LANG_HOOKS_FUNCTION_INIT ! #define LANG_HOOKS_FUNCTION_INIT cxx_push_function_context ! #undef LANG_HOOKS_FUNCTION_FINAL ! #define LANG_HOOKS_FUNCTION_FINAL cxx_pop_function_context ! ! /* Attribute hooks. */ ! #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE ! #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE c_common_attribute_table ! #undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE ! #define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE c_common_format_attribute_table ! #undef LANG_HOOKS_ATTRIBUTE_TABLE ! #define LANG_HOOKS_ATTRIBUTE_TABLE cxx_attribute_table #undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES #define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES \ *************** static bool cp_var_mod_type_p PARAMS ( *** 98,120 **** #undef LANG_HOOKS_EXPR_SIZE #define LANG_HOOKS_EXPR_SIZE cp_expr_size /* Each front end provides its own hooks, for toplev.c. */ const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; /* Special routine to get the alias set for C++. */ static HOST_WIDE_INT cxx_get_alias_set (t) tree t; { ! /* It's not yet safe to use alias sets for classes in C++ because ! the TYPE_FIELDs list for a class doesn't mention base classes. */ ! if (AGGREGATE_TYPE_P (t)) return 0; return c_common_get_alias_set (t); } /* Langhook for expr_size: Tell the backend that the value of an expression of non-POD class type does not include any tail padding; a derived class might have allocated something there. */ --- 140,297 ---- #undef LANG_HOOKS_EXPR_SIZE #define LANG_HOOKS_EXPR_SIZE cp_expr_size + #undef LANG_HOOKS_MAKE_TYPE + #define LANG_HOOKS_MAKE_TYPE cxx_make_type + #undef LANG_HOOKS_TYPE_FOR_MODE + #define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode + #undef LANG_HOOKS_TYPE_FOR_SIZE + #define LANG_HOOKS_TYPE_FOR_SIZE c_common_type_for_size + #undef LANG_HOOKS_SIGNED_TYPE + #define LANG_HOOKS_SIGNED_TYPE c_common_signed_type + #undef LANG_HOOKS_UNSIGNED_TYPE + #define LANG_HOOKS_UNSIGNED_TYPE c_common_unsigned_type + #undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE + #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE c_common_signed_or_unsigned_type + #undef LANG_HOOKS_INCOMPLETE_TYPE_ERROR + #define LANG_HOOKS_INCOMPLETE_TYPE_ERROR cxx_incomplete_type_error + #undef LANG_HOOKS_TYPE_PROMOTES_TO + #define LANG_HOOKS_TYPE_PROMOTES_TO cxx_type_promotes_to + /* Each front end provides its own hooks, for toplev.c. */ const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; + /* Tree code classes. */ + + #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, + + const char tree_code_type[] = { + #include "tree.def" + 'x', + #include "c-common.def" + 'x', + #include "cp-tree.def" + }; + #undef DEFTREECODE + + /* Table indexed by tree code giving number of expression + operands beyond the fixed part of the node structure. + Not used for types or decls. */ + + #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, + + const unsigned char tree_code_length[] = { + #include "tree.def" + 0, + #include "c-common.def" + 0, + #include "cp-tree.def" + }; + #undef DEFTREECODE + + /* Names of tree components. + Used for printing out the tree and error messages. */ + #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME, + + const char *const tree_code_name[] = { + #include "tree.def" + "@@dummy", + #include "c-common.def" + "@@dummy", + #include "cp-tree.def" + }; + #undef DEFTREECODE + + /* Check if a C++ type is safe for aliasing. + Return TRUE if T safe for aliasing FALSE otherwise. */ + + static bool + ok_to_generate_alias_set_for_type (t) + tree t; + { + if (TYPE_PTRMEMFUNC_P (t)) + return true; + if (AGGREGATE_TYPE_P (t)) + { + if ((TREE_CODE (t) == RECORD_TYPE) || (TREE_CODE (t) == UNION_TYPE)) + { + tree fields; + /* Backend-created structs are safe. */ + if (! CLASS_TYPE_P (t)) + return true; + /* PODs are safe. */ + if (! CLASSTYPE_NON_POD_P(t)) + return true; + /* Classes with virtual baseclasses are not. */ + if (TYPE_USES_VIRTUAL_BASECLASSES (t)) + return false; + /* Recursively check the base classes. */ + if (TYPE_BINFO (t) != NULL && TYPE_BINFO_BASETYPES (t) != NULL) + { + int i; + for (i = 0; i < TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (t)); i++) + { + tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), i); + if (!ok_to_generate_alias_set_for_type (BINFO_TYPE (binfo))) + return false; + } + } + /* Check all the fields. */ + for (fields = TYPE_FIELDS (t); fields; fields = TREE_CHAIN (fields)) + { + if (TREE_CODE (fields) != FIELD_DECL) + continue; + if (! ok_to_generate_alias_set_for_type (TREE_TYPE (fields))) + return false; + } + return true; + } + else if (TREE_CODE (t) == ARRAY_TYPE) + return ok_to_generate_alias_set_for_type (TREE_TYPE (t)); + else + /* This should never happen, we dealt with all the aggregate + types that can appear in C++ above. */ + abort (); + } + else + return true; + } + /* Special routine to get the alias set for C++. */ static HOST_WIDE_INT cxx_get_alias_set (t) tree t; { ! if (/* It's not yet safe to use alias sets for some classes in C++. */ ! !ok_to_generate_alias_set_for_type (t) ! /* Nor is it safe to use alias sets for pointers-to-member ! functions, due to the fact that there may be more than one ! RECORD_TYPE type corresponding to the same pointer-to-member ! type. */ ! || TYPE_PTRMEMFUNC_P (t)) return 0; return c_common_get_alias_set (t); } + /* Called from check_global_declarations. */ + + static bool + cxx_warn_unused_global_decl (decl) + tree decl; + { + if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl)) + return false; + if (DECL_IN_SYSTEM_HEADER (decl)) + return false; + + /* Const variables take the place of #defines in C++. */ + if (TREE_CODE (decl) == VAR_DECL && TREE_READONLY (decl)) + return false; + + return true; + } + /* Langhook for expr_size: Tell the backend that the value of an expression of non-POD class type does not include any tail padding; a derived class might have allocated something there. */ *************** cp_expr_size (exp) *** 125,132 **** { if (CLASS_TYPE_P (TREE_TYPE (exp))) { ! /* This would be wrong for a type with virtual bases, but they should ! not get here. */ return CLASSTYPE_SIZE_UNIT (TREE_TYPE (exp)); } else --- 302,317 ---- { if (CLASS_TYPE_P (TREE_TYPE (exp))) { ! /* The backend should not be interested in the size of an expression ! of a type with both of these set; all copies of such types must go ! through a constructor or assignment op. */ ! if (TYPE_HAS_COMPLEX_INIT_REF (TREE_TYPE (exp)) ! && TYPE_HAS_COMPLEX_ASSIGN_REF (TREE_TYPE (exp)) ! /* But storing a CONSTRUCTOR isn't a copy. */ ! && TREE_CODE (exp) != CONSTRUCTOR) ! abort (); ! /* This would be wrong for a type with virtual bases, but they are ! caught by the abort above. */ return CLASSTYPE_SIZE_UNIT (TREE_TYPE (exp)); } else diff -Nrc3pad gcc-3.2.3/gcc/cp/cp-tree.def gcc-3.3/gcc/cp/cp-tree.def *** gcc-3.2.3/gcc/cp/cp-tree.def 2002-03-16 01:07:59.000000000 +0000 --- gcc-3.3/gcc/cp/cp-tree.def 2003-03-09 21:35:33.000000000 +0000 *************** the Free Software Foundation, 59 Temple *** 23,33 **** Boston, MA 02111-1307, USA. */ ! /* Reference to the contents of an offset ! (a value whose type is an OFFSET_TYPE). ! Operand 0 is the object within which the offset is taken. ! Operand 1 is the offset. The language independent OFFSET_REF ! just won't work for us. */ DEFTREECODE (OFFSET_REF, "offset_ref", 'r', 2) /* A pointer-to-member constant. For a pointer-to-member constant --- 23,47 ---- Boston, MA 02111-1307, USA. */ ! /* An OFFSET_REF is used in two situations: ! ! 1. An expression of the form `A::m' where `A' is a class and `m' is ! a non-static data member. In this case, operand 0 will be a ! TYPE (corresponding to `A') and operand 1 will be a FIELD_DECL ! (corresponding to `m'. ! ! The expression is a pointer-to-member if its address is taken, ! but simply denotes a member of the object if its address isnot ! taken. In the latter case, resolve_offset_ref is used to ! convert it to a representation of the member referred to by the ! OFFSET_REF. ! ! 2. An expression of the form `x.*p'. In this case, operand 0 will ! be an expression corresponding to `x' and operand 1 will be an ! expression with pointer-to-member type. ! ! OFFSET_REFs are only used during the parsing phase; once semantic ! analysis has taken place they are eliminated. */ DEFTREECODE (OFFSET_REF, "offset_ref", 'r', 2) /* A pointer-to-member constant. For a pointer-to-member constant *************** DEFTREECODE (THROW_EXPR, "throw_expr", ' *** 75,80 **** --- 89,108 ---- these to avoid actually creating instances of the empty classes. */ DEFTREECODE (EMPTY_CLASS_EXPR, "empty_class_expr", 'e', 0) + /* A reference to a member function or member functions from a base + class. BASELINK_FUNCTIONS gives the FUNCTION_DECL, + TEMPLATE_DECL, OVERLOAD, or TEMPLATE_ID_EXPR corresponding to the + functions. BASELINK_BINFO gives the base from which the functions + come, i.e., the base to which the `this' pointer must be converted + before the functions are called. BASELINK_ACCESS_BINFO gives the + base used to name the functions. + + A BASELINK is an expression; the TREE_TYPE of the BASELINK gives + the type of the expression. This type is either a FUNCTION_TYPE, + METHOD_TYPE, or `unknown_type_node' indicating that the function is + overloaded. */ + DEFTREECODE (BASELINK, "baselink", 'e', 3) + /* Template definition. The following fields have the specified uses, although there are other macros in cp-tree.h that should be used for accessing this data. *************** DEFTREECODE (DEFAULT_ARG, "default_arg", *** 186,199 **** The second is the TREE_LIST or TREE_VEC of explicitly specified arguments. The template will be a FUNCTION_DECL, TEMPLATE_DECL, or an OVERLOAD. If the template-id refers to a member template, the ! template may be an IDENTIFIER_NODE. */ DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2) - /* An association between name and entity. Parameters are the scope - and the (non-type) value. TREE_TYPE indicates the type bound to - the name. */ - DEFTREECODE (CPLUS_BINDING, "binding", 'x', 2) - /* A list-like node for chaining overloading candidates. TREE_TYPE is the original name, and the parameter is the FUNCTION_DECL. */ DEFTREECODE (OVERLOAD, "overload", 'x', 1) --- 214,223 ---- The second is the TREE_LIST or TREE_VEC of explicitly specified arguments. The template will be a FUNCTION_DECL, TEMPLATE_DECL, or an OVERLOAD. If the template-id refers to a member template, the ! template may be an IDENTIFIER_NODE. In an uninstantiated template, ! the template may be a LOOKUP_EXPR. */ DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2) /* A list-like node for chaining overloading candidates. TREE_TYPE is the original name, and the parameter is the FUNCTION_DECL. */ DEFTREECODE (OVERLOAD, "overload", 'x', 1) *************** DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr *** 220,238 **** DEFTREECODE (TYPEID_EXPR, "typeid_expr", 'e', 1) DEFTREECODE (PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", 'e', 3) - /* A SUBOBJECT statement marks the point at which a sub-object is - fully constructed. After this point, the SUBOBJECT_CLEANUP must be - run if an exception is thrown before the end of the enclosing - function. */ - DEFTREECODE (SUBOBJECT, "subobject", 'e', 1) - /* An CTOR_STMT marks the beginning (if CTOR_BEGIN_P holds) or end of - a constructor (if CTOR_END_P) holds. At the end of a constructor, - the cleanups associated with any SUBOBJECT_CLEANUPS need no longer - be run. */ - DEFTREECODE (CTOR_STMT, "ctor_stmt", 'e', 0) /* CTOR_INITIALIZER is a placeholder in template code for a call to setup_vtbl_pointer (and appears in all functions, not just ctors). */ ! DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 2) DEFTREECODE (RETURN_INIT, "return_init", 'e', 2) DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2) DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", 'e', 2) --- 244,252 ---- DEFTREECODE (TYPEID_EXPR, "typeid_expr", 'e', 1) DEFTREECODE (PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", 'e', 3) /* CTOR_INITIALIZER is a placeholder in template code for a call to setup_vtbl_pointer (and appears in all functions, not just ctors). */ ! DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 1) DEFTREECODE (RETURN_INIT, "return_init", 'e', 2) DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2) DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", 'e', 2) *************** DEFTREECODE (MUST_NOT_THROW_EXPR, "must_ *** 248,254 **** DEFTREECODE (TAG_DEFN, "tag_defn", 'e', 0) ! /* And some codes for expressing conversions for overload resolution. */ DEFTREECODE (IDENTITY_CONV, "identity_conv", 'e', 1) DEFTREECODE (LVALUE_CONV, "lvalue_conv", 'e', 1) --- 262,274 ---- DEFTREECODE (TAG_DEFN, "tag_defn", 'e', 0) ! /* The following codes are used to represent implicit conversion ! sequences, in the sense of [over.best.ics]. The conversion ! sequences are connected through their first operands, with the ! first conversion to be performed at the end of the chain. ! ! The innermost conversion (i.e, the one at the end of the chain) is ! always an IDENTITY_CONV, corresponding to the identity conversion. */ DEFTREECODE (IDENTITY_CONV, "identity_conv", 'e', 1) DEFTREECODE (LVALUE_CONV, "lvalue_conv", 'e', 1) diff -Nrc3pad gcc-3.2.3/gcc/cp/cp-tree.h gcc-3.3/gcc/cp/cp-tree.h *** gcc-3.2.3/gcc/cp/cp-tree.h 2003-01-21 19:00:26.000000000 +0000 --- gcc-3.3/gcc/cp/cp-tree.h 2003-04-29 18:51:55.000000000 +0000 *************** along with GNU CC; see the file COPYING. *** 20,39 **** the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "function.h" #include "hashtab.h" #include "splay-tree.h" #include "varray.h" - #ifndef GCC_CP_TREE_H - #define GCC_CP_TREE_H - #ifndef __GNUC__ #error "You should be using 'make bootstrap' -- see installation instructions" #endif #include "c-common.h" /* Usage of TREE_LANG_FLAG_?: 0: BINFO_MARKED (BINFO nodes). IDENTIFIER_MARKED (IDENTIFIER_NODEs) --- 20,41 ---- the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + #ifndef GCC_CP_TREE_H + #define GCC_CP_TREE_H + #include "function.h" #include "hashtab.h" #include "splay-tree.h" #include "varray.h" #ifndef __GNUC__ #error "You should be using 'make bootstrap' -- see installation instructions" #endif #include "c-common.h" + struct diagnostic_context; + /* Usage of TREE_LANG_FLAG_?: 0: BINFO_MARKED (BINFO nodes). IDENTIFIER_MARKED (IDENTIFIER_NODEs) *************** Boston, MA 02111-1307, USA. */ *** 41,52 **** DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR). LOOKUP_EXPR_GLOBAL (in LOOKUP_EXPR). TREE_INDIRECT_USING (in NAMESPACE_DECL). - LOCAL_BINDING_P (in CPLUS_BINDING) ICS_USER_FLAG (in _CONV) CLEANUP_P (in TRY_BLOCK) AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR) - CTOR_BEGIN_P (in CTOR_STMT) - BV_USE_VCALL_INDEX_P (in the BINFO_VIRTUALS TREE_LIST) PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF) PARMLIST_ELLIPSIS_P (in PARMLIST) 1: IDENTIFIER_VIRTUAL_P. --- 43,51 ---- *************** Boston, MA 02111-1307, USA. */ *** 55,68 **** DELETE_EXPR_USE_VEC (in DELETE_EXPR). (TREE_CALLS_NEW) (in _EXPR or _REF) (commented-out). TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (in _TYPE). - INHERITED_VALUE_BINDING_P (in CPLUS_BINDING) - BASELINK_P (in TREE_LIST) ICS_ELLIPSIS_FLAG (in _CONV) BINFO_ACCESS (in BINFO) 2: IDENTIFIER_OPNAME_P. ! TYPE_POLYMORHPIC_P (in _TYPE) ICS_THIS_FLAG (in _CONV) - BINDING_HAS_LEVEL_P (in CPLUS_BINDING) BINFO_LOST_PRIMARY_P (in BINFO) TREE_PARMLIST (in TREE_LIST) 3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE). --- 54,65 ---- DELETE_EXPR_USE_VEC (in DELETE_EXPR). (TREE_CALLS_NEW) (in _EXPR or _REF) (commented-out). TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (in _TYPE). ICS_ELLIPSIS_FLAG (in _CONV) BINFO_ACCESS (in BINFO) + DECL_INITIALIZED_P (in VAR_DECL) 2: IDENTIFIER_OPNAME_P. ! TYPE_POLYMORPHIC_P (in _TYPE) ICS_THIS_FLAG (in _CONV) BINFO_LOST_PRIMARY_P (in BINFO) TREE_PARMLIST (in TREE_LIST) 3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE). *************** Boston, MA 02111-1307, USA. */ *** 96,106 **** DECL_MUTABLE_P (in FIELD_DECL) 1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL). DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL) - DECL_C_BITFIELD (in FIELD_DECL) 2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL). DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL) 3: DECL_IN_AGGR_P. ! 4: DECL_C_BIT_FIELD 5: DECL_INTERFACE_KNOWN. 6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL). 7: DECL_DEAD_FOR_LOCAL (in VAR_DECL). --- 93,103 ---- DECL_MUTABLE_P (in FIELD_DECL) 1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL). DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL) 2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL). DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL) 3: DECL_IN_AGGR_P. ! 4: DECL_C_BIT_FIELD (in a FIELD_DECL) ! DECL_VAR_MARKED_P (in a VAR_DECL) 5: DECL_INTERFACE_KNOWN. 6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL). 7: DECL_DEAD_FOR_LOCAL (in VAR_DECL). *************** Boston, MA 02111-1307, USA. */ *** 121,136 **** For a FUNCTION_TYPE or METHOD_TYPE, this is TYPE_RAISES_EXCEPTIONS BINFO_VIRTUALS ! For a binfo, this is a TREE_LIST. The BV_DELTA of each node ! gives the amount by which to adjust the `this' pointer when ! calling the function. If the method is an overriden version of a ! base class method, then it is assumed that, prior to adjustment, ! the this pointer points to an object of the base class. The BV_VCALL_INDEX of each node, if non-NULL, gives the vtable ! index of the vcall offset for this entry. If ! BV_USE_VCALL_INDEX_P then the corresponding vtable entry should ! use a virtual thunk, as opposed to an ordinary thunk. The BV_FN is the declaration for the virtual function itself. --- 118,135 ---- For a FUNCTION_TYPE or METHOD_TYPE, this is TYPE_RAISES_EXCEPTIONS BINFO_VIRTUALS ! For a binfo, this is a TREE_LIST. There is an entry for each ! virtual function declared either in BINFO or its direct and ! indirect primary bases. ! ! The BV_DELTA of each node gives the amount by which to adjust the ! `this' pointer when calling the function. If the method is an ! overriden version of a base class method, then it is assumed ! that, prior to adjustment, the this pointer points to an object ! of the base class. The BV_VCALL_INDEX of each node, if non-NULL, gives the vtable ! index of the vcall offset for this entry. The BV_FN is the declaration for the virtual function itself. *************** Boston, MA 02111-1307, USA. */ *** 153,159 **** the virtual function this one overrides, and whose TREE_CHAIN is the old DECL_VINDEX. */ ! /* Language-specific tree checkers. */ #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) --- 152,158 ---- the virtual function this one overrides, and whose TREE_CHAIN is the old DECL_VINDEX. */ ! /* Language-specific tree checkers. */ #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) *************** Boston, MA 02111-1307, USA. */ *** 212,242 **** #endif ! ! /* ABI control. */ ! /* Nonzero to use __cxa_atexit, rather than atexit, to register ! destructors for local statics and global objects. */ ! extern int flag_use_cxa_atexit; ! /* Nonzero means generate 'rtti' that give run-time type information. */ ! extern int flag_rtti; ! /* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes) ! objects. */ ! extern int flag_huge_objects; /* Language-dependent contents of an identifier. */ ! struct lang_identifier { ! struct c_common_identifier ignore; ! tree namespace_bindings; ! tree bindings; tree class_value; tree class_template_info; struct lang_id2 *x; --- 211,262 ---- #endif ! /* Returns TRUE if generated code should match ABI version N or ! greater is in use. */ ! #define abi_version_at_least(N) \ ! (flag_abi_version == 0 || flag_abi_version >= (N)) ! ! /* Datatype used to temporarily save C++ bindings (for implicit ! instantiations purposes and like). Implemented in decl.c. */ ! typedef struct cxx_saved_binding cxx_saved_binding; ! /* Datatype that represents binding established by a declaration between ! a name and a C++ entity. */ ! typedef struct cxx_binding cxx_binding; ! /* (GC-)allocate a cxx_binding object. */ ! #define cxx_binding_make() (ggc_alloc (sizeof (cxx_binding))) ! /* Zero out a cxx_binding pointed to by B. */ ! #define cxx_binding_clear(B) memset ((B), 0, sizeof (cxx_binding)) ! struct cxx_binding GTY(()) ! { ! /* Link to chain together various bindings for this name. */ ! cxx_binding *previous; ! /* The non-type entity this name is bound to. */ ! tree value; ! /* The type entity this name is bound to. */ ! tree type; ! union tree_binding_u { ! tree GTY ((tag ("0"))) scope; ! struct cp_binding_level * GTY ((tag ("1"))) level; ! } GTY ((desc ("%0.has_level"))) scope; ! unsigned has_level : 1; ! unsigned value_is_inherited : 1; ! unsigned is_local : 1; ! }; /* Language-dependent contents of an identifier. */ ! struct lang_identifier GTY(()) { ! struct c_common_identifier c_common; ! cxx_binding *namespace_bindings; ! cxx_binding *bindings; tree class_value; tree class_template_info; struct lang_id2 *x; *************** extern const short rid_to_yy[RID_MAX]; *** 254,273 **** #define LANG_IDENTIFIER_CAST(NODE) \ ((struct lang_identifier*)IDENTIFIER_NODE_CHECK (NODE)) ! struct lang_id2 { ! tree label_value, implicit_decl; tree error_locus; }; ! typedef struct { tree t; int new_type_flag; tree lookups; } flagged_type_tree; ! typedef struct { struct tree_common common; HOST_WIDE_INT index; --- 274,294 ---- #define LANG_IDENTIFIER_CAST(NODE) \ ((struct lang_identifier*)IDENTIFIER_NODE_CHECK (NODE)) ! struct lang_id2 GTY(()) { ! tree label_value; ! tree implicit_decl; tree error_locus; }; ! typedef struct flagged_type_tree_s GTY(()) { tree t; int new_type_flag; tree lookups; } flagged_type_tree; ! typedef struct template_parm_index_s GTY(()) { struct tree_common common; HOST_WIDE_INT index; *************** typedef struct *** 276,316 **** tree decl; } template_parm_index; ! typedef struct ptrmem_cst { struct tree_common common; /* This isn't used, but the middle-end expects all constants to have this field. */ rtx rtl; tree member; ! }* ptrmem_cst_t; /* Nonzero if this binding is for a local scope, as opposed to a class or namespace scope. */ ! #define LOCAL_BINDING_P(NODE) TREE_LANG_FLAG_0 (NODE) /* Nonzero if BINDING_VALUE is from a base class of the class which is currently being defined. */ ! #define INHERITED_VALUE_BINDING_P(NODE) TREE_LANG_FLAG_1 (NODE) /* For a binding between a name and an entity at a non-local scope, defines the scope where the binding is declared. (Either a class _TYPE node, or a NAMESPACE_DECL.) This macro should be used only for namespace-level bindings; on the IDENTIFIER_BINDING list BINDING_LEVEL is used instead. */ ! #define BINDING_SCOPE(NODE) \ ! (((struct tree_binding*)CPLUS_BINDING_CHECK (NODE))->scope.scope) /* Nonzero if NODE has BINDING_LEVEL, rather than BINDING_SCOPE. */ ! #define BINDING_HAS_LEVEL_P(NODE) TREE_LANG_FLAG_2 (NODE) /* This is the declaration bound to the name. Possible values: variable, overloaded function, namespace, template, enumerator. */ ! #define BINDING_VALUE(NODE) \ ! (((struct tree_binding*)CPLUS_BINDING_CHECK (NODE))->value) /* If name is bound to a type, this is the type (struct, union, enum). */ ! #define BINDING_TYPE(NODE) TREE_TYPE (NODE) #define IDENTIFIER_GLOBAL_VALUE(NODE) \ namespace_binding ((NODE), global_namespace) --- 297,336 ---- tree decl; } template_parm_index; ! struct ptrmem_cst GTY(()) { struct tree_common common; /* This isn't used, but the middle-end expects all constants to have this field. */ rtx rtl; tree member; ! }; ! typedef struct ptrmem_cst * ptrmem_cst_t; /* Nonzero if this binding is for a local scope, as opposed to a class or namespace scope. */ ! #define LOCAL_BINDING_P(NODE) ((NODE)->is_local) /* Nonzero if BINDING_VALUE is from a base class of the class which is currently being defined. */ ! #define INHERITED_VALUE_BINDING_P(NODE) ((NODE)->value_is_inherited) /* For a binding between a name and an entity at a non-local scope, defines the scope where the binding is declared. (Either a class _TYPE node, or a NAMESPACE_DECL.) This macro should be used only for namespace-level bindings; on the IDENTIFIER_BINDING list BINDING_LEVEL is used instead. */ ! #define BINDING_SCOPE(NODE) ((NODE)->scope.scope) /* Nonzero if NODE has BINDING_LEVEL, rather than BINDING_SCOPE. */ ! #define BINDING_HAS_LEVEL_P(NODE) ((NODE)->has_level) /* This is the declaration bound to the name. Possible values: variable, overloaded function, namespace, template, enumerator. */ ! #define BINDING_VALUE(NODE) ((NODE)->value) /* If name is bound to a type, this is the type (struct, union, enum). */ ! #define BINDING_TYPE(NODE) ((NODE)->type) #define IDENTIFIER_GLOBAL_VALUE(NODE) \ namespace_binding ((NODE), global_namespace) *************** typedef struct ptrmem_cst *** 333,403 **** #define same_type_ignoring_top_level_qualifiers_p(TYPE1, TYPE2) \ same_type_p (TYPE_MAIN_VARIANT (TYPE1), TYPE_MAIN_VARIANT (TYPE2)) ! /* Non-zero if we are presently building a statement tree, rather than expanding each statement as we encounter it. */ #define building_stmt_tree() (last_tree != NULL_TREE) ! /* Returns non-zero iff NODE is a declaration for the global function `main'. */ #define DECL_MAIN_P(NODE) \ (DECL_EXTERN_C_FUNCTION_P (NODE) \ && DECL_NAME (NODE) != NULL_TREE \ && MAIN_NAME_P (DECL_NAME (NODE))) ! ! struct tree_binding ! { ! struct tree_common common; ! union { ! tree scope; ! struct binding_level *level; ! } scope; ! tree value; ! }; ! ! /* The overloaded FUNCTION_DECL. */ #define OVL_FUNCTION(NODE) \ (((struct tree_overload*)OVERLOAD_CHECK (NODE))->function) #define OVL_CHAIN(NODE) TREE_CHAIN (NODE) ! /* Polymorphic access to FUNCTION and CHAIN. */ #define OVL_CURRENT(NODE) \ ((TREE_CODE (NODE) == OVERLOAD) ? OVL_FUNCTION (NODE) : (NODE)) #define OVL_NEXT(NODE) \ ((TREE_CODE (NODE) == OVERLOAD) ? TREE_CHAIN (NODE) : NULL_TREE) /* If set, this was imported in a using declaration. This is not to confuse with being used somewhere, which ! is not important for this node. */ #define OVL_USED(NODE) TREE_USED (NODE) ! struct tree_overload { struct tree_common common; tree function; }; ! /* A `baselink' is a TREE_LIST whose TREE_PURPOSE is a BINFO ! indicating a particular base class, and whose TREE_VALUE is a ! (possibly overloaded) function from that base class. */ #define BASELINK_P(NODE) \ ! (TREE_CODE (NODE) == TREE_LIST && TREE_LANG_FLAG_1 (NODE)) ! #define SET_BASELINK_P(NODE) \ ! (TREE_LANG_FLAG_1 (NODE) = 1) ! #define WRAPPER_PTR(NODE) (((struct tree_wrapper*)WRAPPER_CHECK (NODE))->u.ptr) ! #define WRAPPER_INT(NODE) (((struct tree_wrapper*)WRAPPER_CHECK (NODE))->u.i) ! struct tree_wrapper { struct tree_common common; ! union { ! void *ptr; ! int i; ! } u; }; #define SRCLOC_FILE(NODE) (((struct tree_srcloc*)SRCLOC_CHECK (NODE))->filename) #define SRCLOC_LINE(NODE) (((struct tree_srcloc*)SRCLOC_CHECK (NODE))->linenum) ! struct tree_srcloc { struct tree_common common; const char *filename; --- 353,423 ---- #define same_type_ignoring_top_level_qualifiers_p(TYPE1, TYPE2) \ same_type_p (TYPE_MAIN_VARIANT (TYPE1), TYPE_MAIN_VARIANT (TYPE2)) ! /* Nonzero if we are presently building a statement tree, rather than expanding each statement as we encounter it. */ #define building_stmt_tree() (last_tree != NULL_TREE) ! /* Returns nonzero iff NODE is a declaration for the global function `main'. */ #define DECL_MAIN_P(NODE) \ (DECL_EXTERN_C_FUNCTION_P (NODE) \ && DECL_NAME (NODE) != NULL_TREE \ && MAIN_NAME_P (DECL_NAME (NODE))) ! /* The overloaded FUNCTION_DECL. */ #define OVL_FUNCTION(NODE) \ (((struct tree_overload*)OVERLOAD_CHECK (NODE))->function) #define OVL_CHAIN(NODE) TREE_CHAIN (NODE) ! /* Polymorphic access to FUNCTION and CHAIN. */ #define OVL_CURRENT(NODE) \ ((TREE_CODE (NODE) == OVERLOAD) ? OVL_FUNCTION (NODE) : (NODE)) #define OVL_NEXT(NODE) \ ((TREE_CODE (NODE) == OVERLOAD) ? TREE_CHAIN (NODE) : NULL_TREE) /* If set, this was imported in a using declaration. This is not to confuse with being used somewhere, which ! is not important for this node. */ #define OVL_USED(NODE) TREE_USED (NODE) ! struct tree_overload GTY(()) { struct tree_common common; tree function; }; ! /* Returns true iff NODE is a BASELINK. */ #define BASELINK_P(NODE) \ ! (TREE_CODE (NODE) == BASELINK) ! /* The BINFO indicating the base from which the BASELINK_FUNCTIONS came. */ ! #define BASELINK_BINFO(NODE) \ ! (TREE_OPERAND (BASELINK_CHECK (NODE), 0)) ! /* The functions referred to by the BASELINK; either a FUNCTION_DECL, ! a TEMPLATE_DECL, an OVERLOAD, or a TEMPLATE_ID_EXPR. */ ! #define BASELINK_FUNCTIONS(NODE) \ ! (TREE_OPERAND (BASELINK_CHECK (NODE), 1)) ! /* The BINFO in which the search for the functions indicated by this baselink ! began. This base is used to determine the accessibility of functions ! selected by overload resolution. */ ! #define BASELINK_ACCESS_BINFO(NODE) \ ! (TREE_OPERAND (BASELINK_CHECK (NODE), 2)) ! /* For a type-conversion operator, the BASELINK_OPTYPE indicates the type ! to which the conversion should occur. This value is important if ! the BASELINK_FUNCTIONS include a template conversion operator -- ! the BASELINK_OPTYPE can be used to determine what type the user ! requested. */ ! #define BASELINK_OPTYPE(NODE) \ ! (TREE_CHAIN (BASELINK_CHECK (NODE))) ! #define WRAPPER_ZC(NODE) (((struct tree_wrapper*)WRAPPER_CHECK (NODE))->z_c) ! struct tree_wrapper GTY(()) { struct tree_common common; ! struct z_candidate *z_c; }; #define SRCLOC_FILE(NODE) (((struct tree_srcloc*)SRCLOC_CHECK (NODE))->filename) #define SRCLOC_LINE(NODE) (((struct tree_srcloc*)SRCLOC_CHECK (NODE))->linenum) ! struct tree_srcloc GTY(()) { struct tree_common common; const char *filename; *************** struct tree_srcloc *** 411,418 **** #define IDENTIFIER_TEMPLATE(NODE) \ (LANG_IDENTIFIER_CAST (NODE)->class_template_info) ! /* The IDENTIFIER_BINDING is the innermost CPLUS_BINDING for the ! identifier. It's TREE_CHAIN is the next outermost binding. Each BINDING_VALUE is a DECL for the associated declaration. Thus, name lookup consists simply of pulling off the node at the front of the list (modulo oddities for looking up the names of types, --- 431,438 ---- #define IDENTIFIER_TEMPLATE(NODE) \ (LANG_IDENTIFIER_CAST (NODE)->class_template_info) ! /* The IDENTIFIER_BINDING is the innermost cxx_binding for the ! identifier. It's PREVIOUS is the next outermost binding. Each BINDING_VALUE is a DECL for the associated declaration. Thus, name lookup consists simply of pulling off the node at the front of the list (modulo oddities for looking up the names of types, *************** struct tree_srcloc *** 424,432 **** /* The IDENTIFIER_VALUE is the value of the IDENTIFIER_BINDING, or NULL_TREE if there is no binding. */ #define IDENTIFIER_VALUE(NODE) \ ! (IDENTIFIER_BINDING (NODE) \ ! ? BINDING_VALUE (IDENTIFIER_BINDING (NODE)) \ ! : NULL_TREE) /* If IDENTIFIER_CLASS_VALUE is set, then NODE is bound in the current class, and IDENTIFIER_CLASS_VALUE is the value binding. This is --- 444,450 ---- /* The IDENTIFIER_VALUE is the value of the IDENTIFIER_BINDING, or NULL_TREE if there is no binding. */ #define IDENTIFIER_VALUE(NODE) \ ! (IDENTIFIER_BINDING (NODE) ? BINDING_VALUE (IDENTIFIER_BINDING (NODE)) : 0) /* If IDENTIFIER_CLASS_VALUE is set, then NODE is bound in the current class, and IDENTIFIER_CLASS_VALUE is the value binding. This is *************** struct tree_srcloc *** 439,445 **** /* TREE_TYPE only indicates on local and class scope the current type. For namespace scope, the presence of a type in any namespace is indicated with global_type_node, and the real type behind must ! be found through lookup. */ #define IDENTIFIER_TYPE_VALUE(NODE) identifier_type_value (NODE) #define REAL_IDENTIFIER_TYPE_VALUE(NODE) TREE_TYPE (NODE) #define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = (TYPE)) --- 457,463 ---- /* TREE_TYPE only indicates on local and class scope the current type. For namespace scope, the presence of a type in any namespace is indicated with global_type_node, and the real type behind must ! be found through lookup. */ #define IDENTIFIER_TYPE_VALUE(NODE) identifier_type_value (NODE) #define REAL_IDENTIFIER_TYPE_VALUE(NODE) TREE_TYPE (NODE) #define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = (TYPE)) *************** struct tree_srcloc *** 449,458 **** (LANG_IDENTIFIER_CAST (NODE)->x \ ? LANG_IDENTIFIER_CAST (NODE)->x->NAME : 0) ! #define SET_LANG_ID(NODE, VALUE, NAME) \ ! (LANG_IDENTIFIER_CAST (NODE)->x == 0 \ ! ? LANG_IDENTIFIER_CAST (NODE)->x \ ! = (struct lang_id2 *)perm_calloc (1, sizeof (struct lang_id2)) : 0, \ LANG_IDENTIFIER_CAST (NODE)->x->NAME = (VALUE)) #define IDENTIFIER_LABEL_VALUE(NODE) \ --- 467,476 ---- (LANG_IDENTIFIER_CAST (NODE)->x \ ? LANG_IDENTIFIER_CAST (NODE)->x->NAME : 0) ! #define SET_LANG_ID(NODE, VALUE, NAME) \ ! (LANG_IDENTIFIER_CAST (NODE)->x == 0 \ ! ? LANG_IDENTIFIER_CAST (NODE)->x \ ! = (struct lang_id2 *)ggc_alloc_cleared (sizeof (struct lang_id2)) : 0, \ LANG_IDENTIFIER_CAST (NODE)->x->NAME = (VALUE)) #define IDENTIFIER_LABEL_VALUE(NODE) \ *************** struct tree_srcloc *** 494,504 **** /* Store a value in that field. */ #define C_SET_EXP_ORIGINAL_CODE(EXP, CODE) \ (TREE_COMPLEXITY (EXP) = (int)(CODE)) - - /* If non-zero, a VAR_DECL whose cleanup will cause a throw to the - next exception handler. */ - extern tree exception_throw_decl; enum cp_tree_index { CPTI_JAVA_BYTE_TYPE, --- 512,546 ---- /* Store a value in that field. */ #define C_SET_EXP_ORIGINAL_CODE(EXP, CODE) \ (TREE_COMPLEXITY (EXP) = (int)(CODE)) + enum cp_tree_node_structure_enum { + TS_CP_COMMON, + TS_CP_GENERIC, + TS_CP_IDENTIFIER, + TS_CP_TPI, + TS_CP_PTRMEM, + TS_CP_OVERLOAD, + TS_CP_WRAPPER, + TS_CP_SRCLOC, + LAST_TS_CP_ENUM + }; + + /* The resulting tree type. */ + union lang_tree_node GTY((desc ("cp_tree_node_structure (&%h)"), + chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)"))) + { + struct tree_common GTY ((tag ("TS_CP_COMMON"))) common; + union tree_node GTY ((tag ("TS_CP_GENERIC"), + desc ("tree_node_structure (&%h)"))) generic; + struct template_parm_index_s GTY ((tag ("TS_CP_TPI"))) tpi; + struct ptrmem_cst GTY ((tag ("TS_CP_PTRMEM"))) ptrmem; + struct tree_overload GTY ((tag ("TS_CP_OVERLOAD"))) overload; + struct tree_wrapper GTY ((tag ("TS_CP_WRAPPER"))) wrapper; + struct tree_srcloc GTY ((tag ("TS_CP_SRCLOC"))) srcloc; + struct lang_identifier GTY ((tag ("TS_CP_IDENTIFIER"))) identifier; + }; + + enum cp_tree_index { CPTI_JAVA_BYTE_TYPE, *************** enum cp_tree_index *** 582,591 **** CPTI_DSO_HANDLE, CPTI_DCAST, CPTI_MAX }; ! extern tree cp_global_trees[CPTI_MAX]; #define java_byte_type_node cp_global_trees[CPTI_JAVA_BYTE_TYPE] #define java_short_type_node cp_global_trees[CPTI_JAVA_SHORT_TYPE] --- 624,635 ---- CPTI_DSO_HANDLE, CPTI_DCAST, + CPTI_KEYED_CLASSES, + CPTI_MAX }; ! extern GTY(()) tree cp_global_trees[CPTI_MAX]; #define java_byte_type_node cp_global_trees[CPTI_JAVA_BYTE_TYPE] #define java_short_type_node cp_global_trees[CPTI_JAVA_SHORT_TYPE] *************** extern tree cp_global_trees[CPTI_MAX]; *** 687,693 **** /* The node for `__null'. */ #define null_node cp_global_trees[CPTI_NULL] ! /* If non-NULL, a POINTER_TYPE equivalent to (java::lang::Class*). */ #define jclass_node cp_global_trees[CPTI_JCLASS] /* The declaration for `std::terminate'. */ --- 731,737 ---- /* The node for `__null'. */ #define null_node cp_global_trees[CPTI_NULL] ! /* If non-NULL, a POINTER_TYPE equivalent to (java::lang::Class*). */ #define jclass_node cp_global_trees[CPTI_JCLASS] /* The declaration for `std::terminate'. */ *************** extern tree cp_global_trees[CPTI_MAX]; *** 712,722 **** destructors. */ #define vtt_parm_type cp_global_trees[CPTI_VTT_PARM_TYPE] /* Global state. */ ! struct saved_scope { ! tree old_bindings; tree old_namespace; tree decl_ns_list; tree class_name; --- 756,771 ---- destructors. */ #define vtt_parm_type cp_global_trees[CPTI_VTT_PARM_TYPE] + /* A TREE_LIST of the dynamic classes whose vtables may have to be + emitted in this translation unit. */ + + #define keyed_classes cp_global_trees[CPTI_KEYED_CLASSES] + /* Global state. */ ! struct saved_scope GTY(()) { ! cxx_saved_binding *old_bindings; tree old_namespace; tree decl_ns_list; tree class_name; *************** struct saved_scope *** 739,746 **** struct stmt_tree_s x_stmt_tree; ! struct binding_level *class_bindings; ! struct binding_level *bindings; struct saved_scope *prev; }; --- 788,795 ---- struct stmt_tree_s x_stmt_tree; ! struct cp_binding_level *class_bindings; ! struct cp_binding_level *bindings; struct saved_scope *prev; }; *************** struct saved_scope *** 749,755 **** #define current_namespace scope_chain->old_namespace ! /* The stack for namespaces of current declarations. */ #define decl_namespace_list scope_chain->decl_ns_list --- 798,804 ---- #define current_namespace scope_chain->old_namespace ! /* The stack for namespaces of current declarations. */ #define decl_namespace_list scope_chain->decl_ns_list *************** struct saved_scope *** 797,811 **** #define type_lookups scope_chain->lookups ! extern struct saved_scope *scope_chain; struct unparsed_text; /* Global state pertinent to the current function. */ ! struct cp_language_function { ! struct language_function base; tree x_dtor_label; tree x_current_class_ptr; --- 846,860 ---- #define type_lookups scope_chain->lookups ! extern GTY(()) struct saved_scope *scope_chain; struct unparsed_text; /* Global state pertinent to the current function. */ ! struct language_function GTY(()) { ! struct c_language_function base; tree x_dtor_label; tree x_current_class_ptr; *************** struct cp_language_function *** 815,831 **** tree x_vtt_parm; tree x_return_value; - tree *x_vcalls_possible_p; - int returns_value; int returns_null; int returns_abnormally; int in_function_try_handler; int x_expanding_p; struct named_label_use_list *x_named_label_uses; struct named_label_list *x_named_labels; ! struct binding_level *bindings; varray_type x_local_names; const char *cannot_inline; --- 864,882 ---- tree x_vtt_parm; tree x_return_value; int returns_value; int returns_null; int returns_abnormally; int in_function_try_handler; + int in_base_initializer; int x_expanding_p; + /* True if this function can throw an exception. */ + bool can_throw : 1; + struct named_label_use_list *x_named_label_uses; struct named_label_list *x_named_labels; ! struct cp_binding_level *bindings; varray_type x_local_names; const char *cannot_inline; *************** struct cp_language_function *** 834,841 **** /* The current C++-specific per-function global variables. */ ! #define cp_function_chain \ ! ((struct cp_language_function *) (cfun->language)) /* In a destructor, the point at which all derived class destroying has been done, just before any base class destroying will be done. */ --- 885,891 ---- /* The current C++-specific per-function global variables. */ ! #define cp_function_chain (cfun->language) /* In a destructor, the point at which all derived class destroying has been done, just before any base class destroying will be done. */ *************** struct cp_language_function *** 866,877 **** #define current_vtt_parm cp_function_chain->x_vtt_parm - /* In destructors, this is a pointer to a condition in an - if-statement. If the pointed-to value is boolean_true_node, then - there may be virtual function calls in this destructor. */ - - #define current_vcalls_possible_p cp_function_chain->x_vcalls_possible_p - /* Set to 0 at beginning of a function definition, set to 1 if a return statement that specifies a return value is seen. */ --- 916,921 ---- *************** struct cp_language_function *** 888,904 **** #define current_function_returns_abnormally \ cp_function_chain->returns_abnormally ! /* Non-zero if we should generate RTL for functions that we process. When this is zero, we just accumulate tree structure, without interacting with the back end. */ #define expanding_p cp_function_chain->x_expanding_p ! /* Non-zero if we are in the semantic analysis phase for the current function. */ #define doing_semantic_analysis_p() (!expanding_p) #define in_function_try_handler cp_function_chain->in_function_try_handler /* Expression always returned from function, or error_mark_node --- 932,951 ---- #define current_function_returns_abnormally \ cp_function_chain->returns_abnormally ! /* Nonzero if we should generate RTL for functions that we process. When this is zero, we just accumulate tree structure, without interacting with the back end. */ #define expanding_p cp_function_chain->x_expanding_p ! /* Nonzero if we are in the semantic analysis phase for the current function. */ #define doing_semantic_analysis_p() (!expanding_p) + /* Non-zero if we are processing a base initializer. Zero elsewhere. */ + #define in_base_initializer cp_function_chain->in_base_initializer + #define in_function_try_handler cp_function_chain->in_function_try_handler /* Expression always returned from function, or error_mark_node *************** struct cp_language_function *** 907,1018 **** #define current_function_return_value \ (cp_function_chain->x_return_value) ! extern tree global_namespace; #define ansi_opname(CODE) \ (operator_name_info[(int) (CODE)].identifier) #define ansi_assopname(CODE) \ (assignment_operator_name_info[(int) (CODE)].identifier) ! /* Nonzero means `$' can be in an identifier. */ ! ! extern int dollars_in_ident; ! ! /* Nonzero means don't recognize the keyword `asm'. */ ! ! extern int flag_no_asm; ! ! /* Nonzero means don't recognize any extended keywords. */ ! ! extern int flag_no_gnu_keywords; ! ! /* Nonzero means recognize the named operators from C++98. */ ! ! extern int flag_operator_names; ! ! /* For environments where you can use GNU binutils (as, ld in particular). */ ! ! extern int flag_gnu_binutils; ! ! /* Nonzero means warn about things that will change when compiling ! with an ABI-compliant compiler. */ ! ! extern int warn_abi; ! ! /* Nonzero means warn about implicit declarations. */ ! ! extern int warn_implicit; ! ! /* Nonzero means warn when all ctors or dtors are private, and the class ! has no friends. */ ! ! extern int warn_ctor_dtor_privacy; ! ! /* Nonzero means warn about deprecated conversion from string constant to ! `char *'. */ ! ! extern int warn_write_strings; ! ! /* Nonzero means warn about multiple (redundant) decls for the same single ! variable or function. */ ! ! extern int warn_redundant_decls; ! ! /* Warn if initializer is not completely bracketed. */ ! ! extern int warn_missing_braces; ! ! /* Warn about comparison of signed and unsigned values. */ ! ! extern int warn_sign_compare; ! ! /* Warn about testing equality of floating point numbers. */ ! ! extern int warn_float_equal; ! ! /* Warn about a subscript that has type char. */ ! ! extern int warn_char_subscripts; ! ! /* Nonzero means warn about pointer casts that can drop a type qualifier ! from the pointer target type. */ ! ! extern int warn_cast_qual; ! ! /* Nonzero means warn about non virtual destructors in classes that have ! virtual functions. */ ! ! extern int warn_nonvdtor; ! ! /* Non-zero means warn when we convert a pointer to member function ! into a pointer to (void or function). */ ! ! extern int warn_pmf2ptr; ! ! /* Nonzero means warn about violation of some Effective C++ style rules. */ ! ! extern int warn_ecpp; ! ! /* Nonzero means warn where overload resolution chooses a promotion from ! unsigned to signed over a conversion to an unsigned of the same size. */ ! ! extern int warn_sign_promo; ! ! /* Non-zero means warn when an old-style cast is used. */ ! ! extern int warn_old_style_cast; ! ! /* Non-zero means warn when the compiler will reorder code. */ ! ! extern int warn_reorder; ! ! /* Non-zero means warn about deprecated features. */ ! ! extern int warn_deprecated; ! ! /* Nonzero means to treat bitfields as unsigned unless they say `signed'. */ ! extern int flag_signed_bitfields; /* INTERFACE_ONLY nonzero means that we are in an "interface" section of the compiler. INTERFACE_UNKNOWN nonzero means --- 954,971 ---- #define current_function_return_value \ (cp_function_chain->x_return_value) ! extern GTY(()) tree global_namespace; #define ansi_opname(CODE) \ (operator_name_info[(int) (CODE)].identifier) #define ansi_assopname(CODE) \ (assignment_operator_name_info[(int) (CODE)].identifier) ! /* True if NODE is an erroneous expression. */ ! #define error_operand_p(NODE) \ ! ((NODE) == error_mark_node \ ! || ((NODE) && TREE_TYPE ((NODE)) == error_mark_node)) /* INTERFACE_ONLY nonzero means that we are in an "interface" section of the compiler. INTERFACE_UNKNOWN nonzero means *************** extern int flag_signed_bitfields; *** 1020,1071 **** is zero and INTERFACE_ONLY is zero, it means that we are responsible for exporting definitions that others might need. */ extern int interface_only, interface_unknown; - - /* Nonzero means we should attempt to elide constructors when possible. */ - - extern int flag_elide_constructors; - - /* Nonzero means enable obscure standard features and disable GNU - extensions that might cause standard-compliant code to be - miscompiled. */ - - extern int flag_ansi; - - /* Nonzero means that member functions defined in class scope are - inline by default. */ - - extern int flag_default_inline; - - /* Nonzero means generate separate instantiation control files and juggle - them at link time. */ - extern int flag_use_repository; - - /* Nonzero if we want to issue diagnostics that the standard says are not - required. */ - extern int flag_optional_diags; - - /* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc. */ - extern int flag_vtable_gc; - - /* Nonzero means make the default pedwarns warnings instead of errors. - The value of this flag is ignored if -pedantic is specified. */ - extern int flag_permissive; - - /* Nonzero means to implement standard semantics for exception - specifications, calling unexpected if an exception is thrown that - doesn't match the specification. Zero means to treat them as - assertions and optimize accordingly, but not check them. */ - extern int flag_enforce_eh_specs; - - /* Nonzero if we want to obey access control semantics. */ - - extern int flag_access_control; - - /* Nonzero if we want to check the return value of new and avoid calling - constructors if it is a null pointer. */ - - extern int flag_check_new; - /* C++ language-specific tree codes. */ #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM, --- 973,978 ---- *************** enum languages { lang_c, lang_cplusplus, *** 1130,1136 **** /* In a *_TYPE, nonzero means a built-in type. */ #define TYPE_BUILT_IN(NODE) TYPE_LANG_FLAG_6 (NODE) ! /* True if this a "Java" type, defined in 'extern "Java"'. */ #define TYPE_FOR_JAVA(NODE) TYPE_LANG_FLAG_3 (NODE) /* Nonzero if this type is const-qualified. */ --- 1037,1043 ---- /* In a *_TYPE, nonzero means a built-in type. */ #define TYPE_BUILT_IN(NODE) TYPE_LANG_FLAG_6 (NODE) ! /* True if this a "Java" type, defined in 'extern "Java"'. */ #define TYPE_FOR_JAVA(NODE) TYPE_LANG_FLAG_3 (NODE) /* Nonzero if this type is const-qualified. */ *************** enum languages { lang_c, lang_cplusplus, *** 1186,1191 **** --- 1093,1114 ---- #define PUBLICLY_UNIQUELY_DERIVED_P(PARENT, TYPE) \ lookup_base ((TYPE), (PARENT), ba_not_special | ba_quiet, NULL) + /* This is a few header flags for 'struct lang_type'. Actually, + all but the first are used only for lang_type_class; they + are put in this structure to save space. */ + struct lang_type_header GTY(()) + { + unsigned is_lang_type_class : 1; + + unsigned has_type_conversion : 1; + unsigned has_init_ref : 1; + unsigned has_default_ctor : 1; + unsigned uses_multiple_inheritance : 1; + unsigned const_needs_init : 1; + unsigned ref_needs_init : 1; + unsigned has_const_assign_ref : 1; + }; + /* This structure provides additional information above and beyond what is provide in the ordinary tree_type. In the past, we used it for the types of class types, template parameters types, typename *************** enum languages { lang_c, lang_cplusplus, *** 1199,1217 **** many (i.e., thousands) of classes can easily be generated. Therefore, we should endeavor to keep the size of this structure to a minimum. */ ! struct lang_type { unsigned char align; - unsigned has_type_conversion : 1; - unsigned has_init_ref : 1; - unsigned has_default_ctor : 1; - unsigned uses_multiple_inheritance : 1; - unsigned const_needs_init : 1; - unsigned ref_needs_init : 1; - unsigned has_const_assign_ref : 1; - unsigned anon_aggr : 1; - unsigned has_mutable : 1; unsigned com_interface : 1; unsigned non_pod_class : 1; --- 1122,1133 ---- many (i.e., thousands) of classes can easily be generated. Therefore, we should endeavor to keep the size of this structure to a minimum. */ ! struct lang_type_class GTY(()) { + struct lang_type_header h; + unsigned char align; unsigned has_mutable : 1; unsigned com_interface : 1; unsigned non_pod_class : 1; *************** struct lang_type *** 1227,1233 **** unsigned has_arrow_overloaded : 1; unsigned interface_only : 1; unsigned interface_unknown : 1; - unsigned needs_virtual_reinit : 1; unsigned marks: 6; unsigned vec_new_uses_cookie : 1; --- 1143,1148 ---- *************** struct lang_type *** 1250,1256 **** --- 1165,1173 ---- unsigned is_partial_instantiation : 1; unsigned java_interface : 1; + unsigned anon_aggr : 1; unsigned non_zero_init : 1; + unsigned empty_p : 1; unsigned contains_empty_class_p : 1; /* When adding a flag here, consider whether or not it ought to *************** struct lang_type *** 1260,1290 **** /* There are some bits left to fill out a 32-bit word. Keep track of this by updating the size of this bitfield whenever you add or remove a flag. */ ! unsigned dummy : 6; ! ! int vsize; tree primary_base; tree vfields; tree typeinfo_var; tree vbases; tree tags; ! tree size; ! tree size_unit; tree pure_virtuals; tree friend_classes; - tree rtti; tree methods; tree template_info; tree befriending_classes; }; /* Indicates whether or not (and how) a template was expanded for this class. 0=no information yet/non-template class 1=implicit template instantiation 2=explicit template specialization 3=explicit template instantiation */ ! #define CLASSTYPE_USE_TEMPLATE(NODE) (TYPE_LANG_SPECIFIC (NODE)->use_template) /* Fields used for storing information before the class is defined. After the class is defined, these fields hold other information. */ --- 1177,1245 ---- /* There are some bits left to fill out a 32-bit word. Keep track of this by updating the size of this bitfield whenever you add or remove a flag. */ ! unsigned dummy : 5; tree primary_base; tree vfields; + tree vcall_indices; + tree vtables; tree typeinfo_var; tree vbases; tree tags; ! tree as_base; tree pure_virtuals; tree friend_classes; tree methods; + tree key_method; + tree decl_list; tree template_info; tree befriending_classes; }; + struct lang_type_ptrmem GTY(()) + { + struct lang_type_header h; + tree record; + }; + + struct lang_type GTY(()) + { + union lang_type_u + { + struct lang_type_header GTY((tag ("2"))) h; + struct lang_type_class GTY((tag ("1"))) c; + struct lang_type_ptrmem GTY((tag ("0"))) ptrmem; + } GTY((desc ("%h.h.is_lang_type_class"))) u; + }; + + #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) + + #define LANG_TYPE_CLASS_CHECK(NODE) \ + ({ struct lang_type *lt = TYPE_LANG_SPECIFIC (NODE); \ + if (! lt->u.h.is_lang_type_class) \ + lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \ + <->u.c; }) + + #define LANG_TYPE_PTRMEM_CHECK(NODE) \ + ({ struct lang_type *lt = TYPE_LANG_SPECIFIC (NODE); \ + if (lt->u.h.is_lang_type_class) \ + lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \ + <->u.ptrmem; }) + + #else + + #define LANG_TYPE_CLASS_CHECK(NODE) (&TYPE_LANG_SPECIFIC (NODE)->u.c) + #define LANG_TYPE_PTRMEM_CHECK(NODE) (&TYPE_LANG_SPECIFIC (NODE)->u.ptrmem) + + #endif /* ENABLE_TREE_CHECKING */ + /* Indicates whether or not (and how) a template was expanded for this class. 0=no information yet/non-template class 1=implicit template instantiation 2=explicit template specialization 3=explicit template instantiation */ ! #define CLASSTYPE_USE_TEMPLATE(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->use_template) /* Fields used for storing information before the class is defined. After the class is defined, these fields hold other information. */ *************** struct lang_type *** 1293,1371 **** #define CLASSTYPE_INLINE_FRIENDS(NODE) CLASSTYPE_PURE_VIRTUALS (NODE) /* Nonzero for _CLASSTYPE means that operator delete is defined. */ ! #define TYPE_GETS_DELETE(NODE) (TYPE_LANG_SPECIFIC (NODE)->gets_delete) #define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1) /* Nonzero if `new NODE[x]' should cause the allocation of extra storage to indicate how many array elements are in use. */ #define TYPE_VEC_NEW_USES_COOKIE(NODE) \ (CLASS_TYPE_P (NODE) \ ! && TYPE_LANG_SPECIFIC (NODE)->vec_new_uses_cookie) /* Nonzero means that this _CLASSTYPE node defines ways of converting itself to other types. */ #define TYPE_HAS_CONVERSION(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->has_type_conversion) /* Nonzero means that this _CLASSTYPE node overloads operator=(X&). */ ! #define TYPE_HAS_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_assign_ref) #define TYPE_HAS_CONST_ASSIGN_REF(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->has_const_assign_ref) /* Nonzero means that this _CLASSTYPE node has an X(X&) constructor. */ ! #define TYPE_HAS_INIT_REF(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_init_ref) #define TYPE_HAS_CONST_INIT_REF(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->has_const_init_ref) /* Nonzero if this class defines an overloaded operator new. (An operator new [] doesn't count.) */ #define TYPE_HAS_NEW_OPERATOR(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->has_new) /* Nonzero if this class defines an overloaded operator new[]. */ #define TYPE_HAS_ARRAY_NEW_OPERATOR(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->has_array_new) /* Nonzero means that this type is being defined. I.e., the left brace starting the definition of this type has been seen. */ ! #define TYPE_BEING_DEFINED(NODE) (TYPE_LANG_SPECIFIC (NODE)->being_defined) /* Nonzero means that this type has been redefined. In this case, if convenient, don't reprocess any methods that appear in its redefinition. */ ! #define TYPE_REDEFINED(NODE) (TYPE_LANG_SPECIFIC (NODE)->redefined) ! ! /* The is the basetype that contains NODE's rtti. */ ! #define CLASSTYPE_RTTI(NODE) (TYPE_LANG_SPECIFIC (NODE)->rtti) /* Nonzero means that this _CLASSTYPE node overloads operator(). */ #define TYPE_OVERLOADS_CALL_EXPR(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->has_call_overloaded) /* Nonzero means that this _CLASSTYPE node overloads operator[]. */ #define TYPE_OVERLOADS_ARRAY_REF(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->has_array_ref_overloaded) /* Nonzero means that this _CLASSTYPE node overloads operator->. */ #define TYPE_OVERLOADS_ARROW(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->has_arrow_overloaded) /* Nonzero means that this _CLASSTYPE (or one of its ancestors) uses multiple inheritance. If this is 0 for the root of a type hierarchy, then we can use more efficient search techniques. */ #define TYPE_USES_MULTIPLE_INHERITANCE(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->uses_multiple_inheritance) /* Nonzero means that this _CLASSTYPE (or one of its ancestors) uses virtual base classes. If this is 0 for the root of a type hierarchy, then we can use more efficient search techniques. */ #define TYPE_USES_VIRTUAL_BASECLASSES(NODE) (TREE_LANG_FLAG_3 (NODE)) /* Vector member functions defined in this class. Each element is either a FUNCTION_DECL, a TEMPLATE_DECL, or an OVERLOAD. All functions with the same name end up in the same slot. The first two elements are for constructors, and destructors, respectively. ! Any conversion operators are next, followed by ordinary member ! functions. There may be empty entries at the end of the vector. */ ! #define CLASSTYPE_METHOD_VEC(NODE) (TYPE_LANG_SPECIFIC (NODE)->methods) /* The slot in the CLASSTYPE_METHOD_VEC where constructors go. */ #define CLASSTYPE_CONSTRUCTOR_SLOT 0 --- 1248,1340 ---- #define CLASSTYPE_INLINE_FRIENDS(NODE) CLASSTYPE_PURE_VIRTUALS (NODE) /* Nonzero for _CLASSTYPE means that operator delete is defined. */ ! #define TYPE_GETS_DELETE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->gets_delete) #define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1) /* Nonzero if `new NODE[x]' should cause the allocation of extra storage to indicate how many array elements are in use. */ #define TYPE_VEC_NEW_USES_COOKIE(NODE) \ (CLASS_TYPE_P (NODE) \ ! && LANG_TYPE_CLASS_CHECK (NODE)->vec_new_uses_cookie) /* Nonzero means that this _CLASSTYPE node defines ways of converting itself to other types. */ #define TYPE_HAS_CONVERSION(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->h.has_type_conversion) /* Nonzero means that this _CLASSTYPE node overloads operator=(X&). */ ! #define TYPE_HAS_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_assign_ref) #define TYPE_HAS_CONST_ASSIGN_REF(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->h.has_const_assign_ref) /* Nonzero means that this _CLASSTYPE node has an X(X&) constructor. */ ! #define TYPE_HAS_INIT_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->h.has_init_ref) #define TYPE_HAS_CONST_INIT_REF(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->has_const_init_ref) /* Nonzero if this class defines an overloaded operator new. (An operator new [] doesn't count.) */ #define TYPE_HAS_NEW_OPERATOR(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->has_new) /* Nonzero if this class defines an overloaded operator new[]. */ #define TYPE_HAS_ARRAY_NEW_OPERATOR(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->has_array_new) /* Nonzero means that this type is being defined. I.e., the left brace starting the definition of this type has been seen. */ ! #define TYPE_BEING_DEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->being_defined) /* Nonzero means that this type has been redefined. In this case, if convenient, don't reprocess any methods that appear in its redefinition. */ ! #define TYPE_REDEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->redefined) /* Nonzero means that this _CLASSTYPE node overloads operator(). */ #define TYPE_OVERLOADS_CALL_EXPR(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->has_call_overloaded) /* Nonzero means that this _CLASSTYPE node overloads operator[]. */ #define TYPE_OVERLOADS_ARRAY_REF(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->has_array_ref_overloaded) /* Nonzero means that this _CLASSTYPE node overloads operator->. */ #define TYPE_OVERLOADS_ARROW(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->has_arrow_overloaded) /* Nonzero means that this _CLASSTYPE (or one of its ancestors) uses multiple inheritance. If this is 0 for the root of a type hierarchy, then we can use more efficient search techniques. */ #define TYPE_USES_MULTIPLE_INHERITANCE(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->h.uses_multiple_inheritance) /* Nonzero means that this _CLASSTYPE (or one of its ancestors) uses virtual base classes. If this is 0 for the root of a type hierarchy, then we can use more efficient search techniques. */ #define TYPE_USES_VIRTUAL_BASECLASSES(NODE) (TREE_LANG_FLAG_3 (NODE)) + /* The member function with which the vtable will be emitted: + the first noninline non-pure-virtual member function. NULL_TREE + if there is no key function or if this is a class template */ + #define CLASSTYPE_KEY_METHOD(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->key_method) + /* Vector member functions defined in this class. Each element is either a FUNCTION_DECL, a TEMPLATE_DECL, or an OVERLOAD. All functions with the same name end up in the same slot. The first two elements are for constructors, and destructors, respectively. ! All template conversion operators to innermost template dependent ! types are overloaded on the next slot, if they exist. Note, the ! names for these functions will not all be the same. The ! non-template conversion operators & templated conversions to ! non-innermost template types are next, followed by ordinary member ! functions. There may be empty entries at the end of the vector. ! The conversion operators are unsorted. The ordinary member ! functions are sorted, once the class is complete. */ ! #define CLASSTYPE_METHOD_VEC(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->methods) ! ! /* For class templates, this is a TREE_LIST of all member data, ! functions, types, and friends in the order of declaration. ! The TREE_PURPOSE of each TREE_LIST is NULL_TREE for a friend, ! and the RECORD_TYPE for the class template otherwise. */ ! #define CLASSTYPE_DECL_LIST(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->decl_list) /* The slot in the CLASSTYPE_METHOD_VEC where constructors go. */ #define CLASSTYPE_CONSTRUCTOR_SLOT 0 *************** struct lang_type *** 1391,1409 **** /* Get the value of the Nth mark bit. */ #define CLASSTYPE_MARKED_N(NODE, N) \ ! (((CLASS_TYPE_P (NODE) ? TYPE_LANG_SPECIFIC (NODE)->marks \ : ((unsigned) TYPE_ALIAS_SET (NODE))) & (1 << (N))) != 0) /* Set the Nth mark bit. */ #define SET_CLASSTYPE_MARKED_N(NODE, N) \ (CLASS_TYPE_P (NODE) \ ! ? (void) (TYPE_LANG_SPECIFIC (NODE)->marks |= (1 << (N))) \ : (void) (TYPE_ALIAS_SET (NODE) |= (1 << (N)))) /* Clear the Nth mark bit. */ #define CLEAR_CLASSTYPE_MARKED_N(NODE, N) \ (CLASS_TYPE_P (NODE) \ ! ? (void) (TYPE_LANG_SPECIFIC (NODE)->marks &= ~(1 << (N))) \ : (void) (TYPE_ALIAS_SET (NODE) &= ~(1 << (N)))) /* Get the value of the mark bits. */ --- 1360,1378 ---- /* Get the value of the Nth mark bit. */ #define CLASSTYPE_MARKED_N(NODE, N) \ ! (((CLASS_TYPE_P (NODE) ? LANG_TYPE_CLASS_CHECK (NODE)->marks \ : ((unsigned) TYPE_ALIAS_SET (NODE))) & (1 << (N))) != 0) /* Set the Nth mark bit. */ #define SET_CLASSTYPE_MARKED_N(NODE, N) \ (CLASS_TYPE_P (NODE) \ ! ? (void) (LANG_TYPE_CLASS_CHECK (NODE)->marks |= (1 << (N))) \ : (void) (TYPE_ALIAS_SET (NODE) |= (1 << (N)))) /* Clear the Nth mark bit. */ #define CLEAR_CLASSTYPE_MARKED_N(NODE, N) \ (CLASS_TYPE_P (NODE) \ ! ? (void) (LANG_TYPE_CLASS_CHECK (NODE)->marks &= ~(1 << (N))) \ : (void) (TYPE_ALIAS_SET (NODE) &= ~(1 << (N)))) /* Get the value of the mark bits. */ *************** struct lang_type *** 1432,1438 **** found within this class. The TREE_PURPOSE of each node is the name of the type; the TREE_VALUE is the type itself. This list includes nested member class templates. */ ! #define CLASSTYPE_TAGS(NODE) (TYPE_LANG_SPECIFIC (NODE)->tags) /* Nonzero if NODE has a primary base class, i.e., a base class with which it shares the virtual function table pointer. */ --- 1401,1407 ---- found within this class. The TREE_PURPOSE of each node is the name of the type; the TREE_VALUE is the type itself. This list includes nested member class templates. */ ! #define CLASSTYPE_TAGS(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->tags) /* Nonzero if NODE has a primary base class, i.e., a base class with which it shares the virtual function table pointer. */ *************** struct lang_type *** 1443,1453 **** the base class which contains the virtual function table pointer for this class. */ #define CLASSTYPE_PRIMARY_BINFO(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->primary_base) ! ! /* The number of virtual functions present in this class' virtual ! function table. */ ! #define CLASSTYPE_VSIZE(NODE) (TYPE_LANG_SPECIFIC (NODE)->vsize) /* A chain of BINFOs for the direct and indirect virtual base classes that this type uses in a post-order depth-first left-to-right --- 1412,1418 ---- the base class which contains the virtual function table pointer for this class. */ #define CLASSTYPE_PRIMARY_BINFO(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->primary_base) /* A chain of BINFOs for the direct and indirect virtual base classes that this type uses in a post-order depth-first left-to-right *************** struct lang_type *** 1457,1463 **** list are all "real"; they are the same BINFOs that will be encountered when using dfs_unmarked_real_bases_queue_p and related functions. */ ! #define CLASSTYPE_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC (NODE)->vbases) /* For a non-virtual BINFO, the BINFO itself; for a virtual BINFO, the binfo_for_vbase. C is the most derived class for the hierarchy --- 1422,1428 ---- list are all "real"; they are the same BINFOs that will be encountered when using dfs_unmarked_real_bases_queue_p and related functions. */ ! #define CLASSTYPE_VBASECLASSES(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vbases) /* For a non-virtual BINFO, the BINFO itself; for a virtual BINFO, the binfo_for_vbase. C is the most derived class for the hierarchy *************** struct lang_type *** 1471,1565 **** #define CLASSTYPE_N_BASECLASSES(NODE) \ (BINFO_N_BASETYPES (TYPE_BINFO (NODE))) /* These are the size and alignment of the type without its virtual base classes, for when we use this type as a base itself. */ ! #define CLASSTYPE_SIZE(NODE) (TYPE_LANG_SPECIFIC (NODE)->size) ! #define CLASSTYPE_SIZE_UNIT(NODE) (TYPE_LANG_SPECIFIC (NODE)->size_unit) ! #define CLASSTYPE_ALIGN(NODE) (TYPE_LANG_SPECIFIC (NODE)->align) ! #define CLASSTYPE_USER_ALIGN(NODE) (TYPE_LANG_SPECIFIC (NODE)->user_align) /* The alignment of NODE, without its virtual bases, in bytes. */ #define CLASSTYPE_ALIGN_UNIT(NODE) \ (CLASSTYPE_ALIGN (NODE) / BITS_PER_UNIT) /* True if this a Java interface type, declared with ! '__attribute__ ((java_interface))'. */ ! #define TYPE_JAVA_INTERFACE(NODE) (TYPE_LANG_SPECIFIC (NODE)->java_interface) /* A cons list of virtual functions which cannot be inherited by derived classes. When deriving from this type, the derived class must provide its own definition for each of these functions. */ ! #define CLASSTYPE_PURE_VIRTUALS(NODE) (TYPE_LANG_SPECIFIC (NODE)->pure_virtuals) /* Nonzero means that this aggr type has been `closed' by a semicolon. */ ! #define CLASSTYPE_GOT_SEMICOLON(NODE) (TYPE_LANG_SPECIFIC (NODE)->got_semicolon) ! ! /* Nonzero means that the main virtual function table pointer needs to be ! set because base constructors have placed the wrong value there. ! If this is zero, it means that they placed the right value there, ! and there is no need to change it. */ ! #define CLASSTYPE_NEEDS_VIRTUAL_REINIT(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->needs_virtual_reinit) /* Nonzero means that this type has an X() constructor. */ #define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->has_default_ctor) /* Nonzero means that this type contains a mutable member */ ! #define CLASSTYPE_HAS_MUTABLE(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_mutable) #define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE)) /* Nonzero means that this class type is a non-POD class. */ ! #define CLASSTYPE_NON_POD_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->non_pod_class) /* Nonzero means that this class contains pod types whose default initialization is not a zero initialization (namely, pointers to data members). */ ! #define CLASSTYPE_NON_ZERO_INIT_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->non_zero_init) /* Nonzero if this class is "nearly empty", i.e., contains only a virtual function table pointer. */ #define CLASSTYPE_NEARLY_EMPTY_P(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->nearly_empty_p) /* Nonzero if this class contains an empty subobject. */ #define CLASSTYPE_CONTAINS_EMPTY_CLASS_P(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->contains_empty_class_p) /* A list of class types of which this type is a friend. The TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the case of a template friend. */ #define CLASSTYPE_FRIEND_CLASSES(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->friend_classes) /* A list of the classes which grant friendship to this class. */ #define CLASSTYPE_BEFRIENDING_CLASSES(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->befriending_classes) /* Say whether this node was declared as a "class" or a "struct". */ #define CLASSTYPE_DECLARED_CLASS(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->declared_class) /* Nonzero if this class has const members which have no specified initialization. */ #define CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE) \ (TYPE_LANG_SPECIFIC (NODE) \ ! ? TYPE_LANG_SPECIFIC (NODE)->const_needs_init : 0) #define SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE, VALUE) \ ! (TYPE_LANG_SPECIFIC (NODE)->const_needs_init = (VALUE)) /* Nonzero if this class has ref members which have no specified initialization. */ #define CLASSTYPE_REF_FIELDS_NEED_INIT(NODE) \ (TYPE_LANG_SPECIFIC (NODE) \ ! ? TYPE_LANG_SPECIFIC (NODE)->ref_needs_init : 0) #define SET_CLASSTYPE_REF_FIELDS_NEED_INIT(NODE, VALUE) \ ! (TYPE_LANG_SPECIFIC (NODE)->ref_needs_init = (VALUE)) /* Nonzero if this class is included from a header file which employs `#pragma interface', and it is not included in its implementation file. */ #define CLASSTYPE_INTERFACE_ONLY(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->interface_only) /* True if we have already determined whether or not vtables, VTTs, typeinfo, and other similar per-class data should be emitted in --- 1436,1533 ---- #define CLASSTYPE_N_BASECLASSES(NODE) \ (BINFO_N_BASETYPES (TYPE_BINFO (NODE))) + /* The type corresponding to NODE when NODE is used as a base class, + i.e., NODE without virtual base classes. */ + + #define CLASSTYPE_AS_BASE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->as_base) + /* These are the size and alignment of the type without its virtual base classes, for when we use this type as a base itself. */ ! #define CLASSTYPE_SIZE(NODE) TYPE_SIZE (CLASSTYPE_AS_BASE (NODE)) ! #define CLASSTYPE_SIZE_UNIT(NODE) TYPE_SIZE_UNIT (CLASSTYPE_AS_BASE (NODE)) ! #define CLASSTYPE_ALIGN(NODE) TYPE_ALIGN (CLASSTYPE_AS_BASE (NODE)) ! #define CLASSTYPE_USER_ALIGN(NODE) TYPE_USER_ALIGN (CLASSTYPE_AS_BASE (NODE)) /* The alignment of NODE, without its virtual bases, in bytes. */ #define CLASSTYPE_ALIGN_UNIT(NODE) \ (CLASSTYPE_ALIGN (NODE) / BITS_PER_UNIT) /* True if this a Java interface type, declared with ! '__attribute__ ((java_interface))'. */ ! #define TYPE_JAVA_INTERFACE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->java_interface) /* A cons list of virtual functions which cannot be inherited by derived classes. When deriving from this type, the derived class must provide its own definition for each of these functions. */ ! #define CLASSTYPE_PURE_VIRTUALS(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->pure_virtuals) /* Nonzero means that this aggr type has been `closed' by a semicolon. */ ! #define CLASSTYPE_GOT_SEMICOLON(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->got_semicolon) /* Nonzero means that this type has an X() constructor. */ #define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->h.has_default_ctor) /* Nonzero means that this type contains a mutable member */ ! #define CLASSTYPE_HAS_MUTABLE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_mutable) #define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE)) /* Nonzero means that this class type is a non-POD class. */ ! #define CLASSTYPE_NON_POD_P(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->non_pod_class) /* Nonzero means that this class contains pod types whose default initialization is not a zero initialization (namely, pointers to data members). */ ! #define CLASSTYPE_NON_ZERO_INIT_P(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->non_zero_init) ! ! /* Nonzero if this class is "empty" in the sense of the C++ ABI. */ ! #define CLASSTYPE_EMPTY_P(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->empty_p) /* Nonzero if this class is "nearly empty", i.e., contains only a virtual function table pointer. */ #define CLASSTYPE_NEARLY_EMPTY_P(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->nearly_empty_p) /* Nonzero if this class contains an empty subobject. */ #define CLASSTYPE_CONTAINS_EMPTY_CLASS_P(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->contains_empty_class_p) /* A list of class types of which this type is a friend. The TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the case of a template friend. */ #define CLASSTYPE_FRIEND_CLASSES(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->friend_classes) /* A list of the classes which grant friendship to this class. */ #define CLASSTYPE_BEFRIENDING_CLASSES(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->befriending_classes) /* Say whether this node was declared as a "class" or a "struct". */ #define CLASSTYPE_DECLARED_CLASS(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->declared_class) /* Nonzero if this class has const members which have no specified initialization. */ #define CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE) \ (TYPE_LANG_SPECIFIC (NODE) \ ! ? LANG_TYPE_CLASS_CHECK (NODE)->h.const_needs_init : 0) #define SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE, VALUE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->h.const_needs_init = (VALUE)) /* Nonzero if this class has ref members which have no specified initialization. */ #define CLASSTYPE_REF_FIELDS_NEED_INIT(NODE) \ (TYPE_LANG_SPECIFIC (NODE) \ ! ? LANG_TYPE_CLASS_CHECK (NODE)->h.ref_needs_init : 0) #define SET_CLASSTYPE_REF_FIELDS_NEED_INIT(NODE, VALUE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->h.ref_needs_init = (VALUE)) /* Nonzero if this class is included from a header file which employs `#pragma interface', and it is not included in its implementation file. */ #define CLASSTYPE_INTERFACE_ONLY(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->interface_only) /* True if we have already determined whether or not vtables, VTTs, typeinfo, and other similar per-class data should be emitted in *************** struct lang_type *** 1567,1587 **** these items should be emitted; it only indicates that we know one way or the other. */ #define CLASSTYPE_INTERFACE_KNOWN(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->interface_unknown == 0) /* The opposite of CLASSTYPE_INTERFANCE_KNOWN. */ #define CLASSTYPE_INTERFACE_UNKNOWN(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->interface_unknown) #define SET_CLASSTYPE_INTERFACE_UNKNOWN_X(NODE,X) \ ! (TYPE_LANG_SPECIFIC (NODE)->interface_unknown = !!(X)) #define SET_CLASSTYPE_INTERFACE_UNKNOWN(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->interface_unknown = 1) #define SET_CLASSTYPE_INTERFACE_KNOWN(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->interface_unknown = 0) /* Nonzero if a _DECL node requires us to output debug info for this class. */ #define CLASSTYPE_DEBUG_REQUESTED(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->debug_requested) /* Additional macros for inheritance information. */ --- 1535,1555 ---- these items should be emitted; it only indicates that we know one way or the other. */ #define CLASSTYPE_INTERFACE_KNOWN(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown == 0) /* The opposite of CLASSTYPE_INTERFANCE_KNOWN. */ #define CLASSTYPE_INTERFACE_UNKNOWN(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown) #define SET_CLASSTYPE_INTERFACE_UNKNOWN_X(NODE,X) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = !!(X)) #define SET_CLASSTYPE_INTERFACE_UNKNOWN(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = 1) #define SET_CLASSTYPE_INTERFACE_KNOWN(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = 0) /* Nonzero if a _DECL node requires us to output debug info for this class. */ #define CLASSTYPE_DEBUG_REQUESTED(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->debug_requested) /* Additional macros for inheritance information. */ *************** struct lang_type *** 1687,1731 **** /* Used by various search routines. */ #define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE) /* The std::type_info variable representing this class, or NULL if no such variable has been created. This field is only set for the TYPE_MAIN_VARIANT of the class. */ #define CLASSTYPE_TYPEINFO_VAR(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->typeinfo_var) /* Accessor macros for the vfield slots in structures. */ ! /* The virtual function pointer fields that this type contains. For a ! vfield defined just for this class, or from a primary base, the ! TREE_PURPOSE is NULL. Otherwise, the TREE_PURPOSE is the BINFO for ! the class containing the vfield. The TREE_VALUE is the class where ! the vfield was first defined. */ ! #define CLASSTYPE_VFIELDS(NODE) (TYPE_LANG_SPECIFIC (NODE)->vfields) ! /* Get the assoc info that caused this vfield to exist. */ #define VF_BINFO_VALUE(NODE) TREE_PURPOSE (NODE) ! /* Get that same information as a _TYPE. */ #define VF_BASETYPE_VALUE(NODE) TREE_VALUE (NODE) ! /* Get the value of the top-most type dominating the non-`normal' vfields. */ ! #define VF_DERIVED_VALUE(NODE) \ ! (VF_BINFO_VALUE (NODE) ? BINFO_TYPE (VF_BINFO_VALUE (NODE)) : NULL_TREE) /* The number of bytes by which to adjust the `this' pointer when ! calling this virtual function. */ #define BV_DELTA(NODE) (TREE_PURPOSE (NODE)) /* If non-NULL, the vtable index at which to find the vcall offset ! when calling this virtual function. */ #define BV_VCALL_INDEX(NODE) (TREE_TYPE (NODE)) /* The function to call. */ #define BV_FN(NODE) (TREE_VALUE (NODE)) - /* Nonzero if we should use a virtual thunk for this entry. */ - #define BV_USE_VCALL_INDEX_P(NODE) \ - (TREE_LANG_FLAG_0 (NODE)) /* Nonzero for TREE_LIST node means that this list of things is a list of parameters, as opposed to a list of expressions. */ --- 1655,1714 ---- /* Used by various search routines. */ #define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE) + /* A TREE_LIST of the vcall indices associated with the class NODE. + The TREE_PURPOSE of each node is a FUNCTION_DECL for a virtual + function. The TREE_VALUE is the index into the virtual table where + the vcall offset for that function is stored, when NODE is a + virtual base. */ + #define CLASSTYPE_VCALL_INDICES(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->vcall_indices) + + /* The various vtables for the class NODE. The primary vtable will be + first, followed by the construction vtables and VTT, if any. */ + #define CLASSTYPE_VTABLES(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->vtables) + /* The std::type_info variable representing this class, or NULL if no such variable has been created. This field is only set for the TYPE_MAIN_VARIANT of the class. */ #define CLASSTYPE_TYPEINFO_VAR(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->typeinfo_var) /* Accessor macros for the vfield slots in structures. */ ! /* List of virtual table fields that this type contains (both the primary ! and secondaries). The TREE_VALUE is the class type where the vtable ! field was introduced. For a vtable field inherited from the primary ! base, or introduced by this class, the TREE_PURPOSE is NULL. For ! other vtable fields (those from non-primary bases), the ! TREE_PURPOSE is the BINFO of the base through which the vtable was ! inherited. */ ! #define CLASSTYPE_VFIELDS(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vfields) ! /* Get the BINFO that introduced this vtable into the hierarchy (will ! be NULL for those created at this level, or from a primary ! hierarchy). */ #define VF_BINFO_VALUE(NODE) TREE_PURPOSE (NODE) ! /* Get the TYPE that introduced this vtable into the hierarchy (always ! non-NULL). */ #define VF_BASETYPE_VALUE(NODE) TREE_VALUE (NODE) ! /* Accessor macros for the BINFO_VIRTUALS list. */ /* The number of bytes by which to adjust the `this' pointer when ! calling this virtual function. Subtract this value from the this ! pointer. Always non-NULL, might be constant zero though. */ #define BV_DELTA(NODE) (TREE_PURPOSE (NODE)) /* If non-NULL, the vtable index at which to find the vcall offset ! when calling this virtual function. Add the value at that vtable ! index to the this pointer. */ #define BV_VCALL_INDEX(NODE) (TREE_TYPE (NODE)) /* The function to call. */ #define BV_FN(NODE) (TREE_VALUE (NODE)) /* Nonzero for TREE_LIST node means that this list of things is a list of parameters, as opposed to a list of expressions. */ *************** struct lang_type *** 1760,1766 **** || TREE_CODE (NODE) == FIELD_DECL \ || TREE_CODE (NODE) == USING_DECL)) ! struct lang_decl_flags { struct c_lang_decl base; --- 1743,1749 ---- || TREE_CODE (NODE) == FIELD_DECL \ || TREE_CODE (NODE) == USING_DECL)) ! struct lang_decl_flags GTY(()) { struct c_lang_decl base; *************** struct lang_decl_flags *** 1781,1847 **** unsigned not_really_extern : 1; unsigned needs_final_overrider : 1; unsigned initialized_in_class : 1; ! unsigned pending_inline_p : 1; unsigned global_ctor_p : 1; unsigned global_dtor_p : 1; - unsigned assignment_operator_p : 1; unsigned anticipated_p : 1; ! /* Four unused bits. */ ! union { /* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this is DECL_TEMPLATE_INFO. */ ! tree template_info; /* In a NAMESPACE_DECL, this is NAMESPACE_LEVEL. */ ! struct binding_level *level; ! } u; ! union { /* This is DECL_ACCESS. */ ! tree access; /* For VAR_DECL in function, this is DECL_DISCRIMINATOR. */ int discriminator; - /* In a namespace-scope FUNCTION_DECL, this is - GLOBAL_INIT_PRIORITY. */ - int init_priority; - /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is THUNK_VCALL_OFFSET. */ ! tree vcall_offset; ! } u2; }; ! struct lang_decl { struct lang_decl_flags decl_flags; ! tree befriending_classes; ! ! /* For a virtual FUNCTION_DECL, this is DECL_VIRTUAL_CONTEXT. For a ! non-virtual FUNCTION_DECL, this is DECL_FRIEND_CONTEXT. */ ! tree context; ! /* In a FUNCTION_DECL, this is DECL_CLONED_FUNCTION. */ ! tree cloned_function; ! union ! { ! tree sorted_fields; ! struct unparsed_text *pending_inline_info; ! struct cp_language_function *saved_language_function; ! } u; ! union { ! /* In an overloaded operator, this is the value of ! DECL_OVERLOADED_OPERATOR_P. */ ! enum tree_code operator_code; ! } u2; }; #define DEFARG_POINTER(NODE) (DEFAULT_ARG_CHECK (NODE)->identifier.id.str) /* DECL_NEEDED_P holds of a declaration when we need to emit its --- 1764,1857 ---- unsigned not_really_extern : 1; unsigned needs_final_overrider : 1; unsigned initialized_in_class : 1; ! unsigned assignment_operator_p : 1; unsigned global_ctor_p : 1; unsigned global_dtor_p : 1; unsigned anticipated_p : 1; ! unsigned template_conv_p : 1; ! unsigned u1sel : 1; ! unsigned u2sel : 1; ! unsigned can_be_full : 1; ! unsigned unused : 1; /* One unused bit. */ ! union lang_decl_u { /* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this is DECL_TEMPLATE_INFO. */ ! tree GTY ((tag ("0"))) template_info; /* In a NAMESPACE_DECL, this is NAMESPACE_LEVEL. */ ! struct cp_binding_level * GTY ((tag ("1"))) level; ! } GTY ((desc ("%1.u1sel"))) u; ! union lang_decl_u2 { /* This is DECL_ACCESS. */ ! tree GTY ((tag ("0"))) access; /* For VAR_DECL in function, this is DECL_DISCRIMINATOR. */ int discriminator; /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is THUNK_VCALL_OFFSET. */ ! tree GTY((tag ("2"))) vcall_offset; ! } GTY ((desc ("%1.u2sel"))) u2; }; ! struct lang_decl GTY(()) { struct lang_decl_flags decl_flags; ! union lang_decl_u4 ! { ! struct full_lang_decl ! { ! tree befriending_classes; ! ! /* For a non-virtual FUNCTION_DECL, this is ! DECL_FRIEND_CONTEXT. For a virtual FUNCTION_DECL for which ! DECL_THUNK_P does not hold, this is DECL_THUNKS. */ ! tree context; ! /* In a FUNCTION_DECL, this is DECL_CLONED_FUNCTION. */ ! tree cloned_function; ! ! /* In a FUNCTION_DECL for which THUNK_P holds, this is ! THUNK_DELTA. */ ! HOST_WIDE_INT delta; ! /* In an overloaded operator, this is the value of ! DECL_OVERLOADED_OPERATOR_P. */ ! enum tree_code operator_code; ! unsigned u3sel : 1; ! unsigned pending_inline_p : 1; ! ! union lang_decl_u3 ! { ! tree GTY ((tag ("0"))) sorted_fields; ! struct unparsed_text * GTY ((tag ("2"))) pending_inline_info; ! struct language_function * GTY ((tag ("1"))) ! saved_language_function; ! } GTY ((desc ("%1.u3sel + %1.pending_inline_p"))) u; ! } GTY ((tag ("1"))) f; ! } GTY ((desc ("%1.decl_flags.can_be_full"))) u; }; + #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) + + #define LANG_DECL_U2_CHECK(NODE, TF) \ + ({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \ + if (lt->decl_flags.u2sel != TF) \ + lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \ + <->decl_flags.u2; }) + + #else + + #define LANG_DECL_U2_CHECK(NODE, TF) \ + (&DECL_LANG_SPECIFIC (NODE)->decl_flags.u2) + + #endif /* ENABLE_TREE_CHECKING */ + #define DEFARG_POINTER(NODE) (DEFAULT_ARG_CHECK (NODE)->identifier.id.str) /* DECL_NEEDED_P holds of a declaration when we need to emit its *************** struct lang_decl *** 1857,1863 **** && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL))) \ || (flag_syntax_only && TREE_USED (DECL))) ! /* Non-zero iff DECL is memory-based. The DECL_RTL of certain const variables might be a CONST_INT, or a REG in some cases. We cannot use `memory_operand' as a test here because on most RISC machines, a variable's address --- 1867,1873 ---- && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL))) \ || (flag_syntax_only && TREE_USED (DECL))) ! /* Nonzero iff DECL is memory-based. The DECL_RTL of certain const variables might be a CONST_INT, or a REG in some cases. We cannot use `memory_operand' as a test here because on most RISC machines, a variable's address *************** struct lang_decl *** 1949,1955 **** /* If DECL_CLONED_FUNCTION_P holds, this is the function that was cloned. */ #define DECL_CLONED_FUNCTION(NODE) \ ! (DECL_LANG_SPECIFIC (NODE)->cloned_function) /* Nonzero if NODE has DECL_DISCRIMINATOR and not DECL_ACCESS. */ #define DECL_DISCRIMINATOR_P(NODE) \ --- 1959,1965 ---- /* If DECL_CLONED_FUNCTION_P holds, this is the function that was cloned. */ #define DECL_CLONED_FUNCTION(NODE) \ ! (DECL_LANG_SPECIFIC (NODE)->u.f.cloned_function) /* Nonzero if NODE has DECL_DISCRIMINATOR and not DECL_ACCESS. */ #define DECL_DISCRIMINATOR_P(NODE) \ *************** struct lang_decl *** 1957,1983 **** && DECL_FUNCTION_SCOPE_P (NODE)) /* Discriminator for name mangling. */ ! #define DECL_DISCRIMINATOR(NODE) \ ! (DECL_LANG_SPECIFIC (NODE)->decl_flags.u2.discriminator) ! /* Non-zero if the VTT parm has been added to NODE. */ #define DECL_HAS_VTT_PARM_P(NODE) \ (DECL_LANG_SPECIFIC (NODE)->decl_flags.has_vtt_parm_p) ! /* Non-zero if NODE is a FUNCTION_DECL for which a VTT parameter is required. */ #define DECL_NEEDS_VTT_PARM_P(NODE) \ (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (NODE)) \ && (DECL_BASE_CONSTRUCTOR_P (NODE) \ || DECL_BASE_DESTRUCTOR_P (NODE))) ! /* Non-zero if NODE is a user-defined conversion operator. */ #define DECL_CONV_FN_P(NODE) \ (IDENTIFIER_TYPENAME_P (DECL_NAME (NODE))) /* Set the overloaded operator code for NODE to CODE. */ #define SET_OVERLOADED_OPERATOR_CODE(NODE, CODE) \ ! (DECL_LANG_SPECIFIC (NODE)->u2.operator_code = (CODE)) /* If NODE is an overloaded operator, then this returns the TREE_CODE associcated with the overloaded operator. --- 1967,1998 ---- && DECL_FUNCTION_SCOPE_P (NODE)) /* Discriminator for name mangling. */ ! #define DECL_DISCRIMINATOR(NODE) (LANG_DECL_U2_CHECK (NODE, 1)->discriminator) ! /* Nonzero if the VTT parm has been added to NODE. */ #define DECL_HAS_VTT_PARM_P(NODE) \ (DECL_LANG_SPECIFIC (NODE)->decl_flags.has_vtt_parm_p) ! /* Nonzero if NODE is a FUNCTION_DECL for which a VTT parameter is required. */ #define DECL_NEEDS_VTT_PARM_P(NODE) \ (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (NODE)) \ && (DECL_BASE_CONSTRUCTOR_P (NODE) \ || DECL_BASE_DESTRUCTOR_P (NODE))) ! /* Nonzero if NODE is a user-defined conversion operator. */ #define DECL_CONV_FN_P(NODE) \ (IDENTIFIER_TYPENAME_P (DECL_NAME (NODE))) + /* Nonzero if NODE, which is a TEMPLATE_DECL, is a template + conversion operator to a type dependent on the innermost template + args. */ + #define DECL_TEMPLATE_CONV_FN_P(NODE) \ + (DECL_LANG_SPECIFIC (NODE)->decl_flags.template_conv_p) + /* Set the overloaded operator code for NODE to CODE. */ #define SET_OVERLOADED_OPERATOR_CODE(NODE, CODE) \ ! (DECL_LANG_SPECIFIC (NODE)->u.f.operator_code = (CODE)) /* If NODE is an overloaded operator, then this returns the TREE_CODE associcated with the overloaded operator. *************** struct lang_decl *** 1988,1996 **** to test whether or not NODE is an overloaded operator. */ #define DECL_OVERLOADED_OPERATOR_P(NODE) \ (IDENTIFIER_OPNAME_P (DECL_NAME (NODE)) \ ! ? DECL_LANG_SPECIFIC (NODE)->u2.operator_code : ERROR_MARK) ! /* Non-zero if NODE is an assignment operator. */ #define DECL_ASSIGNMENT_OPERATOR_P(NODE) \ (DECL_LANG_SPECIFIC (NODE)->decl_flags.assignment_operator_p) --- 2003,2011 ---- to test whether or not NODE is an overloaded operator. */ #define DECL_OVERLOADED_OPERATOR_P(NODE) \ (IDENTIFIER_OPNAME_P (DECL_NAME (NODE)) \ ! ? DECL_LANG_SPECIFIC (NODE)->u.f.operator_code : ERROR_MARK) ! /* Nonzero if NODE is an assignment operator. */ #define DECL_ASSIGNMENT_OPERATOR_P(NODE) \ (DECL_LANG_SPECIFIC (NODE)->decl_flags.assignment_operator_p) *************** struct lang_decl *** 2011,2018 **** should be allocated. */ #define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3 (NODE)) /* Nonzero if the DECL was initialized in the class definition itself, ! rather than outside the class. */ #define DECL_INITIALIZED_IN_CLASS_P(DECL) \ (DECL_LANG_SPECIFIC (DECL)->decl_flags.initialized_in_class) --- 2026,2039 ---- should be allocated. */ #define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3 (NODE)) + /* Nonzero for a VAR_DECL means that the variable's initialization has + been processed. */ + #define DECL_INITIALIZED_P(NODE) \ + (TREE_LANG_FLAG_1 (VAR_DECL_CHECK (NODE))) + /* Nonzero if the DECL was initialized in the class definition itself, ! rather than outside the class. This is used for both static member ! VAR_DECLS, and FUNTION_DECLS that are defined in the class. */ #define DECL_INITIALIZED_IN_CLASS_P(DECL) \ (DECL_LANG_SPECIFIC (DECL)->decl_flags.initialized_in_class) *************** struct lang_decl *** 2023,2029 **** /* A TREE_LIST of the types which have befriended this FUNCTION_DECL. */ #define DECL_BEFRIENDING_CLASSES(NODE) \ ! (DECL_LANG_SPECIFIC (NODE)->befriending_classes) /* Nonzero for FUNCTION_DECL means that this decl is a static member function. */ --- 2044,2050 ---- /* A TREE_LIST of the types which have befriended this FUNCTION_DECL. */ #define DECL_BEFRIENDING_CLASSES(NODE) \ ! (DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes) /* Nonzero for FUNCTION_DECL means that this decl is a static member function. */ *************** struct lang_decl *** 2079,2084 **** --- 2100,2110 ---- #define DECL_NEEDS_FINAL_OVERRIDER_P(NODE) \ (DECL_LANG_SPECIFIC (NODE)->decl_flags.needs_final_overrider) + /* The thunks associated with NODE, a FUNCTION_DECL that is not itself + a thunk. */ + #define DECL_THUNKS(NODE) \ + (DECL_LANG_SPECIFIC (NODE)->u.f.context) + /* Nonzero if NODE is a thunk, rather than an ordinary function. */ #define DECL_THUNK_P(NODE) \ (TREE_CODE (NODE) == FUNCTION_DECL \ *************** struct lang_decl *** 2097,2104 **** (DECL_NON_THUNK_FUNCTION_P (NODE) && DECL_EXTERN_C_P (NODE)) /* Set DECL_THUNK_P for node. */ ! #define SET_DECL_THUNK_P(NODE) \ ! (DECL_LANG_FLAG_7 (NODE) = 1) /* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a template function. */ --- 2123,2131 ---- (DECL_NON_THUNK_FUNCTION_P (NODE) && DECL_EXTERN_C_P (NODE)) /* Set DECL_THUNK_P for node. */ ! #define SET_DECL_THUNK_P(NODE) \ ! (DECL_LANG_FLAG_7 (NODE) = 1, \ ! DECL_LANG_SPECIFIC (NODE)->u.f.u3sel = 1) /* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a template function. */ *************** struct lang_decl *** 2106,2112 **** (TREE_LANG_FLAG_0 (NODE)) /* The _TYPE context in which this _DECL appears. This field holds the ! class where a virtual function instance is actually defined. */ #define DECL_CLASS_CONTEXT(NODE) \ (DECL_CLASS_SCOPE_P (NODE) ? DECL_CONTEXT (NODE) : NULL_TREE) --- 2133,2139 ---- (TREE_LANG_FLAG_0 (NODE)) /* The _TYPE context in which this _DECL appears. This field holds the ! class where a virtual function instance is actually defined. */ #define DECL_CLASS_CONTEXT(NODE) \ (DECL_CLASS_SCOPE_P (NODE) ? DECL_CONTEXT (NODE) : NULL_TREE) *************** struct lang_decl *** 2118,2140 **** the DECL_FRIEND_CONTEXT for `f' will be `S'. */ #define DECL_FRIEND_CONTEXT(NODE) \ ((DECL_FRIEND_P (NODE) && !DECL_FUNCTION_MEMBER_P (NODE)) \ ! ? DECL_LANG_SPECIFIC (NODE)->context \ : NULL_TREE) /* Set the DECL_FRIEND_CONTEXT for NODE to CONTEXT. */ #define SET_DECL_FRIEND_CONTEXT(NODE, CONTEXT) \ ! (DECL_LANG_SPECIFIC (NODE)->context = (CONTEXT)) ! /* NULL_TREE in DECL_CONTEXT represents the global namespace. */ #define CP_DECL_CONTEXT(NODE) \ (DECL_CONTEXT (NODE) ? DECL_CONTEXT (NODE) : global_namespace) #define FROB_CONTEXT(NODE) ((NODE) == global_namespace ? NULL_TREE : (NODE)) - /* For a virtual function, the base where we find its vtable entry. - For a non-virtual function, the base where it is defined. */ - #define DECL_VIRTUAL_CONTEXT(NODE) \ - (DECL_LANG_SPECIFIC (NODE)->context) - /* 1 iff NODE has namespace scope, including the global namespace. */ #define DECL_NAMESPACE_SCOPE_P(NODE) \ (!DECL_TEMPLATE_PARM_P (NODE) \ --- 2145,2162 ---- the DECL_FRIEND_CONTEXT for `f' will be `S'. */ #define DECL_FRIEND_CONTEXT(NODE) \ ((DECL_FRIEND_P (NODE) && !DECL_FUNCTION_MEMBER_P (NODE)) \ ! ? DECL_LANG_SPECIFIC (NODE)->u.f.context \ : NULL_TREE) /* Set the DECL_FRIEND_CONTEXT for NODE to CONTEXT. */ #define SET_DECL_FRIEND_CONTEXT(NODE, CONTEXT) \ ! (DECL_LANG_SPECIFIC (NODE)->u.f.context = (CONTEXT)) ! /* NULL_TREE in DECL_CONTEXT represents the global namespace. */ #define CP_DECL_CONTEXT(NODE) \ (DECL_CONTEXT (NODE) ? DECL_CONTEXT (NODE) : global_namespace) #define FROB_CONTEXT(NODE) ((NODE) == global_namespace ? NULL_TREE : (NODE)) /* 1 iff NODE has namespace scope, including the global namespace. */ #define DECL_NAMESPACE_SCOPE_P(NODE) \ (!DECL_TEMPLATE_PARM_P (NODE) \ *************** struct lang_decl *** 2155,2165 **** /* For a NAMESPACE_DECL: the list of using namespace directives The PURPOSE is the used namespace, the value is the namespace ! that is the common ancestor. */ #define DECL_NAMESPACE_USING(NODE) DECL_VINDEX (NAMESPACE_DECL_CHECK (NODE)) /* In a NAMESPACE_DECL, the DECL_INITIAL is used to record all users ! of a namespace, to record the transitive closure of using namespace. */ #define DECL_NAMESPACE_USERS(NODE) DECL_INITIAL (NAMESPACE_DECL_CHECK (NODE)) /* In a NAMESPACE_DECL, points to the original namespace if this is --- 2177,2187 ---- /* For a NAMESPACE_DECL: the list of using namespace directives The PURPOSE is the used namespace, the value is the namespace ! that is the common ancestor. */ #define DECL_NAMESPACE_USING(NODE) DECL_VINDEX (NAMESPACE_DECL_CHECK (NODE)) /* In a NAMESPACE_DECL, the DECL_INITIAL is used to record all users ! of a namespace, to record the transitive closure of using namespace. */ #define DECL_NAMESPACE_USERS(NODE) DECL_INITIAL (NAMESPACE_DECL_CHECK (NODE)) /* In a NAMESPACE_DECL, points to the original namespace if this is *************** struct lang_decl *** 2169,2175 **** #define ORIGINAL_NAMESPACE(NODE) \ (DECL_NAMESPACE_ALIAS (NODE) ? DECL_NAMESPACE_ALIAS (NODE) : (NODE)) ! /* Non-zero if NODE is the std namespace. */ #define DECL_NAMESPACE_STD_P(NODE) \ (TREE_CODE (NODE) == NAMESPACE_DECL \ && CP_DECL_CONTEXT (NODE) == global_namespace \ --- 2191,2197 ---- #define ORIGINAL_NAMESPACE(NODE) \ (DECL_NAMESPACE_ALIAS (NODE) ? DECL_NAMESPACE_ALIAS (NODE) : (NODE)) ! /* Nonzero if NODE is the std namespace. */ #define DECL_NAMESPACE_STD_P(NODE) \ (TREE_CODE (NODE) == NAMESPACE_DECL \ && CP_DECL_CONTEXT (NODE) == global_namespace \ *************** struct lang_decl *** 2192,2208 **** the class definition. We have saved away the text of the function, but have not yet processed it. */ #define DECL_PENDING_INLINE_P(NODE) \ ! (DECL_LANG_SPECIFIC (NODE)->decl_flags.pending_inline_p) /* If DECL_PENDING_INLINE_P holds, this is the saved text of the function. */ #define DECL_PENDING_INLINE_INFO(NODE) \ ! (DECL_LANG_SPECIFIC (NODE)->u.pending_inline_info) ! /* For a TYPE_DECL: if this function has many fields, we'll sort them ! and put them into a TREE_VEC. */ #define DECL_SORTED_FIELDS(NODE) \ ! (DECL_LANG_SPECIFIC (TYPE_DECL_CHECK (NODE))->u.sorted_fields) /* True if on the deferred_fns (see decl2.c) list. */ #define DECL_DEFERRED_FN(DECL) \ --- 2214,2230 ---- the class definition. We have saved away the text of the function, but have not yet processed it. */ #define DECL_PENDING_INLINE_P(NODE) \ ! (DECL_LANG_SPECIFIC (NODE)->u.f.pending_inline_p) /* If DECL_PENDING_INLINE_P holds, this is the saved text of the function. */ #define DECL_PENDING_INLINE_INFO(NODE) \ ! (DECL_LANG_SPECIFIC (NODE)->u.f.u.pending_inline_info) ! /* For a TYPE_DECL: if this structure has many fields, we'll sort them ! and put them into a TREE_VEC. */ #define DECL_SORTED_FIELDS(NODE) \ ! (DECL_LANG_SPECIFIC (TYPE_DECL_CHECK (NODE))->u.f.u.sorted_fields) /* True if on the deferred_fns (see decl2.c) list. */ #define DECL_DEFERRED_FN(DECL) \ *************** struct lang_decl *** 2214,2222 **** (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK (NODE)) \ ->decl_flags.u.template_info) /* Template information for a RECORD_TYPE or UNION_TYPE. */ #define CLASSTYPE_TEMPLATE_INFO(NODE) \ ! (TYPE_LANG_SPECIFIC (RECORD_OR_UNION_TYPE_CHECK (NODE))->template_info) /* Template information for an ENUMERAL_TYPE. Although an enumeration may not be a primary template, it may be declared within the scope of a --- 2236,2250 ---- (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK (NODE)) \ ->decl_flags.u.template_info) + /* For a VAR_DECL, indicates that the variable has been processed. + This flag is set and unset throughout the code; it is always + used for a temporary purpose. */ + #define DECL_VAR_MARKED_P(NODE) \ + (DECL_LANG_FLAG_4 (VAR_DECL_CHECK (NODE))) + /* Template information for a RECORD_TYPE or UNION_TYPE. */ #define CLASSTYPE_TEMPLATE_INFO(NODE) \ ! (LANG_TYPE_CLASS_CHECK (RECORD_OR_UNION_TYPE_CHECK (NODE))->template_info) /* Template information for an ENUMERAL_TYPE. Although an enumeration may not be a primary template, it may be declared within the scope of a *************** struct lang_decl *** 2226,2232 **** /* Template information for a template template parameter. */ #define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) \ ! (TYPE_LANG_SPECIFIC (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK (NODE)) \ ->template_info) /* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE. */ --- 2254,2260 ---- /* Template information for a template template parameter. */ #define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) \ ! (LANG_TYPE_CLASS_CHECK (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK (NODE)) \ ->template_info) /* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE. */ *************** struct lang_decl *** 2262,2268 **** only one level of arguments, but which is a TREE_VEC containing as its only entry the TREE_VEC for that level. */ ! /* Non-zero if the template arguments is actually a vector of vectors, rather than just a vector. */ #define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \ ((NODE) != NULL_TREE \ --- 2290,2296 ---- only one level of arguments, but which is a TREE_VEC containing as its only entry the TREE_VEC for that level. */ ! /* Nonzero if the template arguments is actually a vector of vectors, rather than just a vector. */ #define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \ ((NODE) != NULL_TREE \ *************** struct lang_decl *** 2279,2285 **** #define TMPL_ARGS_DEPTH(NODE) \ (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (NODE) ? TREE_VEC_LENGTH (NODE) : 1) ! /* The LEVELth level of the template ARGS. The outermost level of of args is level 1, not level 0. */ #define TMPL_ARGS_LEVEL(ARGS, LEVEL) \ (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (ARGS) \ --- 2307,2313 ---- #define TMPL_ARGS_DEPTH(NODE) \ (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (NODE) ? TREE_VEC_LENGTH (NODE) : 1) ! /* The LEVELth level of the template ARGS. The outermost level of args is level 1, not level 0. */ #define TMPL_ARGS_LEVEL(ARGS, LEVEL) \ (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (ARGS) \ *************** struct lang_decl *** 2364,2371 **** #define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE) /* In a FUNCTION_DECL, the saved language-specific per-function data. */ ! #define DECL_SAVED_FUNCTION_DATA(NODE) \ ! (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (NODE))->u.saved_language_function) #define NEW_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) #define DELETE_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) --- 2392,2400 ---- #define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE) /* In a FUNCTION_DECL, the saved language-specific per-function data. */ ! #define DECL_SAVED_FUNCTION_DATA(NODE) \ ! (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (NODE)) \ ! ->u.f.u.saved_language_function) #define NEW_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) #define DELETE_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) *************** struct lang_decl *** 2423,2430 **** (TYPE_POLYMORPHIC_P (NODE) \ || TYPE_USES_VIRTUAL_BASECLASSES (NODE)) - extern int flag_new_for_scope; - /* This flag is true of a local VAR_DECL if it was declared in a for statement, but we are no longer in the scope of the for. */ #define DECL_DEAD_FOR_LOCAL(NODE) DECL_LANG_FLAG_7 (VAR_DECL_CHECK (NODE)) --- 2452,2457 ---- *************** extern int flag_new_for_scope; *** 2446,2452 **** /* Record whether a typedef for type `int' was actually `signed int'. */ #define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP) ! /* Returns non-zero if DECL has external linkage, as specified by the language standard. (This predicate may hold even when the corresponding entity is not actually given external linkage in the object file; see decl_linkage for details.) */ --- 2473,2479 ---- /* Record whether a typedef for type `int' was actually `signed int'. */ #define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP) ! /* Returns nonzero if DECL has external linkage, as specified by the language standard. (This predicate may hold even when the corresponding entity is not actually given external linkage in the object file; see decl_linkage for details.) */ *************** extern int flag_new_for_scope; *** 2474,2481 **** #define ARITHMETIC_TYPE_P(TYPE) \ (CP_INTEGRAL_TYPE_P (TYPE) || TREE_CODE (TYPE) == REAL_TYPE) ! /* Nonzero for _TYPE means that the _TYPE defines ! at least one constructor. */ #define TYPE_HAS_CONSTRUCTOR(NODE) (TYPE_LANG_FLAG_1 (NODE)) /* When appearing in an INDIRECT_REF, it means that the tree structure --- 2501,2529 ---- #define ARITHMETIC_TYPE_P(TYPE) \ (CP_INTEGRAL_TYPE_P (TYPE) || TREE_CODE (TYPE) == REAL_TYPE) ! /* [basic.types] ! ! Arithmetic types, enumeration types, pointer types, and ! pointer-to-member types, are collectively called scalar types. */ ! #define SCALAR_TYPE_P(TYPE) \ ! (ARITHMETIC_TYPE_P (TYPE) \ ! || TREE_CODE (TYPE) == ENUMERAL_TYPE \ ! || TYPE_PTR_P (TYPE) \ ! || TYPE_PTRMEM_P (TYPE) \ ! || TYPE_PTRMEMFUNC_P (TYPE)) ! ! /* [dcl.init.aggr] ! ! An aggregate is an array or a class with no user-declared ! constructors, no private or protected non-static data members, no ! base classes, and no virtual functions. */ ! #define CP_AGGREGATE_TYPE_P(TYPE) \ ! (TREE_CODE (TYPE) == ARRAY_TYPE \ ! || (CLASS_TYPE_P (TYPE) \ ! && !CLASSTYPE_NON_AGGREGATE (TYPE))) ! ! /* Nonzero for a class type means that the class type has a ! user-declared constructor. */ #define TYPE_HAS_CONSTRUCTOR(NODE) (TYPE_LANG_FLAG_1 (NODE)) /* When appearing in an INDIRECT_REF, it means that the tree structure *************** extern int flag_new_for_scope; *** 2504,2518 **** /* Nonzero means that an object of this type can not be initialized using an initializer list. */ #define CLASSTYPE_NON_AGGREGATE(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->non_aggregate) #define TYPE_NON_AGGREGATE_CLASS(NODE) \ (IS_AGGR_TYPE (NODE) && CLASSTYPE_NON_AGGREGATE (NODE)) /* Nonzero if there is a user-defined X::op=(x&) for this class. */ ! #define TYPE_HAS_REAL_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_real_assign_ref) ! #define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_complex_assign_ref) ! #define TYPE_HAS_ABSTRACT_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_abstract_assign_ref) ! #define TYPE_HAS_COMPLEX_INIT_REF(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_complex_init_ref) /* Nonzero if TYPE has a trivial destructor. From [class.dtor]: --- 2552,2566 ---- /* Nonzero means that an object of this type can not be initialized using an initializer list. */ #define CLASSTYPE_NON_AGGREGATE(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->non_aggregate) #define TYPE_NON_AGGREGATE_CLASS(NODE) \ (IS_AGGR_TYPE (NODE) && CLASSTYPE_NON_AGGREGATE (NODE)) /* Nonzero if there is a user-defined X::op=(x&) for this class. */ ! #define TYPE_HAS_REAL_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_real_assign_ref) ! #define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_assign_ref) ! #define TYPE_HAS_ABSTRACT_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_abstract_assign_ref) ! #define TYPE_HAS_COMPLEX_INIT_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_init_ref) /* Nonzero if TYPE has a trivial destructor. From [class.dtor]: *************** extern int flag_new_for_scope; *** 2571,2577 **** && TYPE_PTRMEMFUNC_FLAG (NODE)) #define TYPE_PTRMEMFUNC_FLAG(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->ptrmemfunc_flag) /* Indicates when overload resolution may resolve to a pointer to member function. [expr.unary.op]/3 */ --- 2619,2625 ---- && TYPE_PTRMEMFUNC_FLAG (NODE)) #define TYPE_PTRMEMFUNC_FLAG(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->ptrmemfunc_flag) /* Indicates when overload resolution may resolve to a pointer to member function. [expr.unary.op]/3 */ *************** extern int flag_new_for_scope; *** 2590,2598 **** /* These are use to manipulate the canonical RECORD_TYPE from the hashed POINTER_TYPE, and can only be used on the POINTER_TYPE. */ #define TYPE_GET_PTRMEMFUNC_TYPE(NODE) \ ! ((tree)TYPE_LANG_SPECIFIC (NODE)) ! #define TYPE_SET_PTRMEMFUNC_TYPE(NODE, VALUE) \ ! (TYPE_LANG_SPECIFIC (NODE) = ((struct lang_type *)(void*)(VALUE))) /* Returns the pfn field from a TYPE_PTRMEMFUNC_P. */ #define PFN_FROM_PTRMEMFUNC(NODE) pfn_from_ptrmemfunc ((NODE)) --- 2638,2654 ---- /* These are use to manipulate the canonical RECORD_TYPE from the hashed POINTER_TYPE, and can only be used on the POINTER_TYPE. */ #define TYPE_GET_PTRMEMFUNC_TYPE(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE) ? LANG_TYPE_PTRMEM_CHECK (NODE)->record : NULL) ! #define TYPE_SET_PTRMEMFUNC_TYPE(NODE, VALUE) \ ! do { \ ! if (TYPE_LANG_SPECIFIC (NODE) == NULL) \ ! { \ ! TYPE_LANG_SPECIFIC (NODE) = \ ! ggc_alloc_cleared (sizeof (struct lang_type_ptrmem)); \ ! TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.h.is_lang_type_class = 0; \ ! } \ ! TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.record = (VALUE); \ ! } while (0) /* Returns the pfn field from a TYPE_PTRMEMFUNC_P. */ #define PFN_FROM_PTRMEMFUNC(NODE) pfn_from_ptrmemfunc ((NODE)) *************** extern int flag_new_for_scope; *** 2637,2645 **** flag for this because "A union for which objects or pointers are declared is not an anonymous union" [class.union]. */ #define ANON_AGGR_TYPE_P(NODE) \ ! (CLASS_TYPE_P (NODE) && TYPE_LANG_SPECIFIC (NODE)->anon_aggr) #define SET_ANON_AGGR_TYPE_P(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE)->anon_aggr = 1) /* Nonzero if TYPE is an anonymous union type. */ #define ANON_UNION_TYPE_P(NODE) \ --- 2693,2701 ---- flag for this because "A union for which objects or pointers are declared is not an anonymous union" [class.union]. */ #define ANON_AGGR_TYPE_P(NODE) \ ! (CLASS_TYPE_P (NODE) && LANG_TYPE_CLASS_CHECK (NODE)->anon_aggr) #define SET_ANON_AGGR_TYPE_P(NODE) \ ! (LANG_TYPE_CLASS_CHECK (NODE)->anon_aggr = 1) /* Nonzero if TYPE is an anonymous union type. */ #define ANON_UNION_TYPE_P(NODE) \ *************** extern int flag_new_for_scope; *** 2649,2655 **** /* Define fields and accessors for nodes representing declared names. */ ! #define TYPE_WAS_ANONYMOUS(NODE) (TYPE_LANG_SPECIFIC (NODE)->was_anonymous) /* C++: all of these are overloaded! These apply only to TYPE_DECLs. */ --- 2705,2711 ---- /* Define fields and accessors for nodes representing declared names. */ ! #define TYPE_WAS_ANONYMOUS(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->was_anonymous) /* C++: all of these are overloaded! These apply only to TYPE_DECLs. */ *************** extern int flag_new_for_scope; *** 2674,2680 **** For example, if a member that would normally be public in a derived class is made protected, then the derived class and the protected_access_node will appear in the DECL_ACCESS for the node. */ ! #define DECL_ACCESS(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.u2.access) /* Nonzero if the FUNCTION_DECL is a global constructor. */ #define DECL_GLOBAL_CTOR_P(NODE) \ --- 2730,2736 ---- For example, if a member that would normally be public in a derived class is made protected, then the derived class and the protected_access_node will appear in the DECL_ACCESS for the node. */ ! #define DECL_ACCESS(NODE) (LANG_DECL_U2_CHECK (NODE, 0)->access) /* Nonzero if the FUNCTION_DECL is a global constructor. */ #define DECL_GLOBAL_CTOR_P(NODE) \ *************** extern int flag_new_for_scope; *** 2684,2696 **** #define DECL_GLOBAL_DTOR_P(NODE) \ (DECL_LANG_SPECIFIC (NODE)->decl_flags.global_dtor_p) - /* If DECL_GLOBAL_CTOR_P or DECL_GLOBAL_DTOR_P holds, this macro - returns the initialization priority for the function. Constructors - with lower numbers should be run first. Destructors should be run - in the reverse order of constructors. */ - #define GLOBAL_INIT_PRIORITY(NODE) \ - (DECL_LANG_SPECIFIC (NODE)->decl_flags.u2.init_priority) - /* Accessor macros for C++ template decl nodes. */ /* The DECL_TEMPLATE_PARMS are a list. The TREE_PURPOSE of each node --- 2740,2745 ---- *************** extern int flag_new_for_scope; *** 2819,2825 **** #define DECL_PRIMARY_TEMPLATE(NODE) \ (TREE_TYPE (DECL_INNERMOST_TEMPLATE_PARMS (NODE))) ! /* Returns non-zero if NODE is a primary template. */ #define PRIMARY_TEMPLATE_P(NODE) (DECL_PRIMARY_TEMPLATE (NODE) == (NODE)) #define CLASSTYPE_TEMPLATE_LEVEL(NODE) \ --- 2868,2874 ---- #define DECL_PRIMARY_TEMPLATE(NODE) \ (TREE_TYPE (DECL_INNERMOST_TEMPLATE_PARMS (NODE))) ! /* Returns nonzero if NODE is a primary template. */ #define PRIMARY_TEMPLATE_P(NODE) (DECL_PRIMARY_TEMPLATE (NODE) == (NODE)) #define CLASSTYPE_TEMPLATE_LEVEL(NODE) \ *************** extern int flag_new_for_scope; *** 2858,2864 **** #define SET_CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \ (CLASSTYPE_USE_TEMPLATE (NODE) = 3) ! /* Non-zero if DECL is a friend function which is an instantiation from the point of view of the compiler, but not from the point of view of the language. For example given: template struct S { friend void f(T) {}; }; --- 2907,2913 ---- #define SET_CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \ (CLASSTYPE_USE_TEMPLATE (NODE) = 3) ! /* Nonzero if DECL is a friend function which is an instantiation from the point of view of the compiler, but not from the point of view of the language. For example given: template struct S { friend void f(T) {}; }; *************** extern int flag_new_for_scope; *** 2868,2888 **** #define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \ (DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL)) ! /* Non-zero if TYPE is a partial instantiation of a template class, i.e., an instantiation whose instantiation arguments involve template types. */ #define PARTIAL_INSTANTIATION_P(TYPE) \ ! (TYPE_LANG_SPECIFIC (TYPE)->is_partial_instantiation) ! /* Non-zero iff we are currently processing a declaration for an entity with its own template parameter list, and which is not a full specialization. */ #define PROCESSING_REAL_TEMPLATE_DECL_P() \ (processing_template_decl > template_class_depth (current_class_type)) - /* This function may be a guiding decl for a template. */ - #define DECL_MAYBE_TEMPLATE(NODE) DECL_LANG_FLAG_4 (NODE) - /* Nonzero if this VAR_DECL or FUNCTION_DECL has already been instantiated, i.e. its definition has been generated from the pattern given in the the template. */ --- 2917,2934 ---- #define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \ (DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL)) ! /* Nonzero if TYPE is a partial instantiation of a template class, i.e., an instantiation whose instantiation arguments involve template types. */ #define PARTIAL_INSTANTIATION_P(TYPE) \ ! (LANG_TYPE_CLASS_CHECK (TYPE)->is_partial_instantiation) ! /* Nonzero iff we are currently processing a declaration for an entity with its own template parameter list, and which is not a full specialization. */ #define PROCESSING_REAL_TEMPLATE_DECL_P() \ (processing_template_decl > template_class_depth (current_class_type)) /* Nonzero if this VAR_DECL or FUNCTION_DECL has already been instantiated, i.e. its definition has been generated from the pattern given in the the template. */ *************** extern int flag_new_for_scope; *** 2930,2943 **** /* An integer indicating how many bytes should be subtracted from the `this' pointer when this function is called. */ ! #define THUNK_DELTA(DECL) (DECL_CHECK (DECL)->decl.u1.i) /* A tree indicating how many bytes should be subtracted from the vtable for the `this' pointer to find the vcall offset. (The vptr is always located at offset zero from the f `this' pointer.) If NULL, then there is no vcall offset. */ #define THUNK_VCALL_OFFSET(DECL) \ ! (DECL_LANG_SPECIFIC (DECL)->decl_flags.u2.vcall_offset) /* These macros provide convenient access to the various _STMT nodes created when parsing template declarations. */ --- 2976,2990 ---- /* An integer indicating how many bytes should be subtracted from the `this' pointer when this function is called. */ ! #define THUNK_DELTA(DECL) \ ! (DECL_LANG_SPECIFIC (DECL)->u.f.delta) /* A tree indicating how many bytes should be subtracted from the vtable for the `this' pointer to find the vcall offset. (The vptr is always located at offset zero from the f `this' pointer.) If NULL, then there is no vcall offset. */ #define THUNK_VCALL_OFFSET(DECL) \ ! (LANG_DECL_U2_CHECK (DECL, 0)->vcall_offset) /* These macros provide convenient access to the various _STMT nodes created when parsing template declarations. */ *************** extern int flag_new_for_scope; *** 2954,2968 **** #define HANDLER_PARMS(NODE) TREE_OPERAND (HANDLER_CHECK (NODE), 0) #define HANDLER_BODY(NODE) TREE_OPERAND (HANDLER_CHECK (NODE), 1) #define HANDLER_TYPE(NODE) TREE_TYPE (HANDLER_CHECK (NODE)) - #define SUBOBJECT_CLEANUP(NODE) TREE_OPERAND (SUBOBJECT_CHECK (NODE), 0) - - /* Nonzero if this CTOR_STMT is for the beginning of a constructor. */ - #define CTOR_BEGIN_P(NODE) \ - (TREE_LANG_FLAG_0 (CTOR_STMT_CHECK (NODE))) - - /* Nonzero if this CTOR_STMT is for the end of a constructor. */ - #define CTOR_END_P(NODE) \ - (!CTOR_BEGIN_P (NODE)) /* The parameters for a call-declarator. */ #define CALL_DECLARATOR_PARMS(NODE) \ --- 3001,3006 ---- *************** typedef enum tsubst_flags_t { *** 3075,3097 **** tf_ignore_bad_quals = 1 << 3, /* ignore bad cvr qualifiers */ tf_keep_type_decl = 1 << 4, /* retain typedef type decls (make_typename_type use) */ ! tf_ptrmem_ok = 1 << 5 /* pointers to member ok (internal instantiate_type use) */ } tsubst_flags_t; ! /* The kind of checking we can do looking in a class hierarchy. */ typedef enum base_access { ba_any = 0, /* Do not check access, allow an ambiguous base, prefer a non-virtual base */ ba_ignore = 1, /* Do not check access */ ba_check = 2, /* Check access */ ba_not_special = 3, /* Do not consider special privilege ! current_class_type might give. */ ba_quiet = 4, /* Do not issue error messages (bit mask). */ } base_access; /* The kind of base we can find, looking in a class hierarchy. ! Values <0 indicate we failed. */ typedef enum base_kind { bk_inaccessible = -3, /* The base is inaccessible */ bk_ambig = -2, /* The base is ambiguous */ --- 3113,3137 ---- tf_ignore_bad_quals = 1 << 3, /* ignore bad cvr qualifiers */ tf_keep_type_decl = 1 << 4, /* retain typedef type decls (make_typename_type use) */ ! tf_ptrmem_ok = 1 << 5, /* pointers to member ok (internal instantiate_type use) */ + tf_parsing = 1 << 6 /* called from parser + (make_typename_type use) */ } tsubst_flags_t; ! /* The kind of checking we can do looking in a class hierarchy. */ typedef enum base_access { ba_any = 0, /* Do not check access, allow an ambiguous base, prefer a non-virtual base */ ba_ignore = 1, /* Do not check access */ ba_check = 2, /* Check access */ ba_not_special = 3, /* Do not consider special privilege ! current_class_type might give. */ ba_quiet = 4, /* Do not issue error messages (bit mask). */ } base_access; /* The kind of base we can find, looking in a class hierarchy. ! Values <0 indicate we failed. */ typedef enum base_kind { bk_inaccessible = -3, /* The base is inaccessible */ bk_ambig = -2, /* The base is ambiguous */ *************** typedef enum base_kind { *** 3100,3132 **** bk_proper_base = 1, /* It is a proper base */ bk_via_virtual = 2 /* It is a proper base, but via a virtual path. This might not be the canonical ! binfo. */ } base_kind; - /* Nonzero means allow Microsoft extensions without a pedwarn. */ - extern int flag_ms_extensions; - - /* Non-zero means warn in function declared in derived class has the - same name as a virtual in the base class, but fails to match the - type signature of any virtual function in the base class. */ - extern int warn_overloaded_virtual; - - /* Nonzero means warn about use of multicharacter literals. */ - extern int warn_multichar; - /* Set by add_implicitly_declared_members() to keep those members from being flagged as deprecated or reported as using deprecated types. */ extern int adding_implicit_members; - /* Non-zero means warn if a non-templatized friend function is - declared in a templatized class. This behavior is warned about with - flag_guiding_decls in do_friend. */ - extern int warn_nontemplate_friend; - /* in decl{2}.c */ /* A node that is a list (length 1) of error_mark_nodes. */ ! extern tree error_mark_list; /* Node for "pointer to (virtual) function". This may be distinct from ptr_type_node so gdb can distinguish them. */ --- 3140,3156 ---- bk_proper_base = 1, /* It is a proper base */ bk_via_virtual = 2 /* It is a proper base, but via a virtual path. This might not be the canonical ! binfo. */ } base_kind; /* Set by add_implicitly_declared_members() to keep those members from being flagged as deprecated or reported as using deprecated types. */ extern int adding_implicit_members; /* in decl{2}.c */ /* A node that is a list (length 1) of error_mark_nodes. */ ! extern GTY(()) tree error_mark_list; /* Node for "pointer to (virtual) function". This may be distinct from ptr_type_node so gdb can distinguish them. */ *************** extern tree error_mark_list; *** 3134,3142 **** /* For building calls to `delete'. */ ! extern tree integer_two_node, integer_three_node; ! extern tree anonymous_namespace_name; /* The number of function bodies which we are currently processing. (Zero if we are at namespace scope, one inside the body of a --- 3158,3167 ---- /* For building calls to `delete'. */ ! extern GTY(()) tree integer_two_node; ! extern GTY(()) tree integer_three_node; ! extern GTY(()) tree anonymous_namespace_name; /* The number of function bodies which we are currently processing. (Zero if we are at namespace scope, one inside the body of a *************** typedef enum unification_kind_t { *** 3167,3179 **** extern int current_class_depth; - /* Points to the name of that function. May not be the DECL_NAME - of CURRENT_FUNCTION_DECL due to overloading */ - extern tree original_function_name; - /* An array of all local classes present in this translation unit, in declaration order. */ ! extern varray_type local_classes; /* Here's where we control how name mangling takes place. */ --- 3192,3200 ---- extern int current_class_depth; /* An array of all local classes present in this translation unit, in declaration order. */ ! extern GTY(()) varray_type local_classes; /* Here's where we control how name mangling takes place. */ *************** extern varray_type local_classes; *** 3261,3267 **** #endif /* NO_DOLLAR_IN_LABEL */ #define THIS_NAME "this" - #define FILE_FUNCTION_PREFIX_LEN 9 #define CTOR_NAME "__ct" #define DTOR_NAME "__dt" --- 3282,3287 ---- *************** extern varray_type local_classes; *** 3294,3300 **** && IDENTIFIER_POINTER (ID_NODE)[1] == '_') #endif /* !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL) */ ! /* Returns non-zero iff NODE is a declaration for the global function `main'. */ #define DECL_MAIN_P(NODE) \ (DECL_EXTERN_C_FUNCTION_P (NODE) \ --- 3314,3320 ---- && IDENTIFIER_POINTER (ID_NODE)[1] == '_') #endif /* !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL) */ ! /* Returns nonzero iff NODE is a declaration for the global function `main'. */ #define DECL_MAIN_P(NODE) \ (DECL_EXTERN_C_FUNCTION_P (NODE) \ *************** extern varray_type local_classes; *** 3302,3340 **** && MAIN_NAME_P (DECL_NAME (NODE))) - /* Things for handling inline functions. */ - - /* Nonzero means do emit exported implementations of functions even if - they can be inlined. */ - - extern int flag_implement_inlines; - - /* Nonzero means templates obey #pragma interface and implementation. */ - - extern int flag_external_templates; - - /* Nonzero means templates are emitted where they are instantiated. */ - - extern int flag_alt_external_templates; - - /* Nonzero means implicit template instantiations are emitted. */ - - extern int flag_implicit_templates; - - /* Nonzero if we want to emit defined symbols with common-like linkage as - weak symbols where possible, in order to conform to C++ semantics. - Otherwise, emit them as local symbols. */ - - extern int flag_weak; - /* Nonzero if we're done parsing and into end-of-file activities. */ extern int at_eof; /* Functions called along with real static constructors and destructors. */ ! extern tree static_ctors; ! extern tree static_dtors; enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG }; --- 3322,3335 ---- && MAIN_NAME_P (DECL_NAME (NODE))) /* Nonzero if we're done parsing and into end-of-file activities. */ extern int at_eof; /* Functions called along with real static constructors and destructors. */ ! extern GTY(()) tree static_ctors; ! extern GTY(()) tree static_dtors; enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG }; *************** typedef struct operator_name_info_t *** 3547,3552 **** --- 3542,3549 ---- const char *name; /* The mangled name of the operator. */ const char *mangled_name; + /* The arity of the operator. */ + int arity; } operator_name_info_t; /* A mapping from tree codes to operator name information. */ *************** extern tree build_method_call PARAMS ( *** 3567,3574 **** --- 3564,3574 ---- extern int null_ptr_cst_p PARAMS ((tree)); extern int sufficient_parms_p PARAMS ((tree)); extern tree type_decays_to PARAMS ((tree)); + extern tree resolve_scoped_fn_name PARAMS ((tree, tree)); extern tree build_user_type_conversion PARAMS ((tree, tree, int)); extern tree build_new_function_call PARAMS ((tree, tree)); + extern tree build_new_method_call (tree, tree, tree, tree, int); + extern tree build_special_member_call (tree, tree, tree, tree, int); extern tree build_new_op PARAMS ((enum tree_code, int, tree, tree, tree)); extern tree build_op_delete_call PARAMS ((enum tree_code, tree, tree, int, tree)); extern int can_convert PARAMS ((tree, tree)); *************** extern int enforce_access *** 3578,3592 **** extern tree convert_default_arg PARAMS ((tree, tree, tree, int)); extern tree convert_arg_to_ellipsis PARAMS ((tree)); extern tree build_x_va_arg PARAMS ((tree, tree)); ! extern tree convert_type_from_ellipsis PARAMS ((tree)); extern int is_properly_derived_from PARAMS ((tree, tree)); ! extern tree initialize_reference PARAMS ((tree, tree)); extern tree strip_top_quals PARAMS ((tree)); extern tree perform_implicit_conversion PARAMS ((tree, tree)); /* in class.c */ extern tree build_base_path PARAMS ((enum tree_code, tree, tree, int)); ! extern tree build_vbase_path PARAMS ((enum tree_code, tree, tree, tree, int)); extern tree build_vtbl_ref PARAMS ((tree, tree)); extern tree build_vfn_ref PARAMS ((tree, tree)); extern tree get_vtable_decl PARAMS ((tree, int)); --- 3578,3596 ---- extern tree convert_default_arg PARAMS ((tree, tree, tree, int)); extern tree convert_arg_to_ellipsis PARAMS ((tree)); extern tree build_x_va_arg PARAMS ((tree, tree)); ! extern tree cxx_type_promotes_to PARAMS ((tree)); ! extern tree type_passed_as PARAMS ((tree)); ! extern tree convert_for_arg_passing PARAMS ((tree, tree)); ! extern tree cp_convert_parm_for_inlining PARAMS ((tree, tree, tree)); extern int is_properly_derived_from PARAMS ((tree, tree)); ! extern tree initialize_reference PARAMS ((tree, tree, tree)); ! extern tree make_temporary_var_for_ref_to_temp (tree, tree); extern tree strip_top_quals PARAMS ((tree)); extern tree perform_implicit_conversion PARAMS ((tree, tree)); /* in class.c */ extern tree build_base_path PARAMS ((enum tree_code, tree, tree, int)); ! extern tree convert_to_base (tree, tree, bool); extern tree build_vtbl_ref PARAMS ((tree, tree)); extern tree build_vfn_ref PARAMS ((tree, tree)); extern tree get_vtable_decl PARAMS ((tree, int)); *************** extern void cxx_print_xnode PARAMS ((F *** 3613,3622 **** extern void cxx_print_decl PARAMS ((FILE *, tree, int)); extern void cxx_print_type PARAMS ((FILE *, tree, int)); extern void cxx_print_identifier PARAMS ((FILE *, tree, int)); ! extern void cxx_set_yydebug PARAMS ((int)); extern void build_self_reference PARAMS ((void)); extern int same_signature_p PARAMS ((tree, tree)); extern void warn_hidden PARAMS ((tree)); extern tree get_enclosing_class PARAMS ((tree)); int is_base_of_enclosing_class PARAMS ((tree, tree)); extern void unreverse_member_declarations PARAMS ((tree)); --- 3617,3628 ---- extern void cxx_print_decl PARAMS ((FILE *, tree, int)); extern void cxx_print_type PARAMS ((FILE *, tree, int)); extern void cxx_print_identifier PARAMS ((FILE *, tree, int)); ! extern void cxx_print_error_function PARAMS ((struct diagnostic_context *, ! const char *)); extern void build_self_reference PARAMS ((void)); extern int same_signature_p PARAMS ((tree, tree)); extern void warn_hidden PARAMS ((tree)); + extern void maybe_add_class_template_decl_list PARAMS ((tree, tree, int)); extern tree get_enclosing_class PARAMS ((tree)); int is_base_of_enclosing_class PARAMS ((tree, tree)); extern void unreverse_member_declarations PARAMS ((tree)); *************** extern void maybe_note_name_used_in_clas *** 3625,3630 **** --- 3631,3637 ---- extern void note_name_declared_in_class PARAMS ((tree, tree)); extern tree get_vtbl_decl_for_binfo PARAMS ((tree)); extern tree in_charge_arg_for_name PARAMS ((tree)); + extern tree build_cxx_call PARAMS ((tree, tree, tree)); extern tree get_vtt_name PARAMS ((tree)); extern tree get_primary_binfo PARAMS ((tree)); *************** extern tree get_primary_binfo *** 3632,3642 **** extern tree convert_to_reference PARAMS ((tree, tree, int, int, tree)); extern tree convert_from_reference PARAMS ((tree)); extern tree convert_lvalue PARAMS ((tree, tree)); extern tree ocp_convert PARAMS ((tree, tree, int, int)); extern tree cp_convert PARAMS ((tree, tree)); extern tree convert_to_void PARAMS ((tree, const char */*implicit context*/)); extern tree convert_force PARAMS ((tree, tree, int)); ! extern tree build_type_conversion PARAMS ((tree, tree, int)); extern tree build_expr_type_conversion PARAMS ((int, tree, int)); extern tree type_promotes_to PARAMS ((tree)); extern tree perform_qualification_conversions PARAMS ((tree, tree)); --- 3639,3650 ---- extern tree convert_to_reference PARAMS ((tree, tree, int, int, tree)); extern tree convert_from_reference PARAMS ((tree)); extern tree convert_lvalue PARAMS ((tree, tree)); + extern tree force_rvalue PARAMS ((tree)); extern tree ocp_convert PARAMS ((tree, tree, int, int)); extern tree cp_convert PARAMS ((tree, tree)); extern tree convert_to_void PARAMS ((tree, const char */*implicit context*/)); extern tree convert_force PARAMS ((tree, tree, int)); ! extern tree build_type_conversion PARAMS ((tree, tree)); extern tree build_expr_type_conversion PARAMS ((int, tree, int)); extern tree type_promotes_to PARAMS ((tree)); extern tree perform_qualification_conversions PARAMS ((tree, tree)); *************** extern void clone_function_decl *** 3644,3655 **** extern void adjust_clone_args PARAMS ((tree)); /* decl.c */ ! /* resume_binding_level */ extern void cxx_init_decl_processing PARAMS ((void)); extern int toplevel_bindings_p PARAMS ((void)); extern int namespace_bindings_p PARAMS ((void)); extern void keep_next_level PARAMS ((int)); - extern int kept_level_p PARAMS ((void)); extern int template_parm_scope_p PARAMS ((void)); extern void set_class_shadows PARAMS ((tree)); extern void maybe_push_cleanup_level PARAMS ((tree)); --- 3652,3676 ---- extern void adjust_clone_args PARAMS ((tree)); /* decl.c */ ! extern int global_bindings_p PARAMS ((void)); ! extern int kept_level_p PARAMS ((void)); ! extern tree getdecls PARAMS ((void)); ! extern void pushlevel PARAMS ((int)); ! extern tree poplevel PARAMS ((int,int, int)); ! extern void insert_block PARAMS ((tree)); ! extern void set_block PARAMS ((tree)); ! extern tree pushdecl PARAMS ((tree)); extern void cxx_init_decl_processing PARAMS ((void)); + enum cp_tree_node_structure_enum cp_tree_node_structure + PARAMS ((union lang_tree_node *)); + extern void cxx_insert_default_attributes PARAMS ((tree)); + extern bool cxx_mark_addressable PARAMS ((tree)); + extern void cxx_push_function_context PARAMS ((struct function *)); + extern void cxx_pop_function_context PARAMS ((struct function *)); + extern void cxx_mark_function_context PARAMS ((struct function *)); extern int toplevel_bindings_p PARAMS ((void)); extern int namespace_bindings_p PARAMS ((void)); extern void keep_next_level PARAMS ((int)); extern int template_parm_scope_p PARAMS ((void)); extern void set_class_shadows PARAMS ((tree)); extern void maybe_push_cleanup_level PARAMS ((tree)); *************** extern void finish_scope *** 3658,3670 **** extern void note_level_for_for PARAMS ((void)); extern void note_level_for_try PARAMS ((void)); extern void note_level_for_catch PARAMS ((void)); ! extern void resume_level PARAMS ((struct binding_level *)); extern void delete_block PARAMS ((tree)); extern void add_block_current_level PARAMS ((tree)); extern void pushlevel_class PARAMS ((void)); extern void poplevel_class PARAMS ((void)); extern void print_binding_stack PARAMS ((void)); ! extern void print_binding_level PARAMS ((struct binding_level *)); extern void push_namespace PARAMS ((tree)); extern void pop_namespace PARAMS ((void)); extern void push_nested_namespace PARAMS ((tree)); --- 3679,3691 ---- extern void note_level_for_for PARAMS ((void)); extern void note_level_for_try PARAMS ((void)); extern void note_level_for_catch PARAMS ((void)); ! extern void resume_level PARAMS ((struct cp_binding_level *)); extern void delete_block PARAMS ((tree)); extern void add_block_current_level PARAMS ((tree)); extern void pushlevel_class PARAMS ((void)); extern void poplevel_class PARAMS ((void)); extern void print_binding_stack PARAMS ((void)); ! extern void print_binding_level PARAMS ((struct cp_binding_level *)); extern void push_namespace PARAMS ((tree)); extern void pop_namespace PARAMS ((void)); extern void push_nested_namespace PARAMS ((tree)); *************** extern tree declare_local_label *** 3693,3705 **** extern tree define_label PARAMS ((const char *, int, tree)); extern void check_goto PARAMS ((tree)); extern void define_case_label PARAMS ((void)); ! extern tree binding_for_name PARAMS ((tree, tree)); extern tree namespace_binding PARAMS ((tree, tree)); extern void set_namespace_binding PARAMS ((tree, tree, tree)); extern tree lookup_namespace_name PARAMS ((tree, tree)); extern tree build_typename_type PARAMS ((tree, tree, tree, tree)); extern tree make_typename_type PARAMS ((tree, tree, tsubst_flags_t)); ! extern tree make_unbound_class_template PARAMS ((tree, tree, int)); extern tree lookup_name_nonclass PARAMS ((tree)); extern tree lookup_function_nonclass PARAMS ((tree, tree)); extern tree lookup_name PARAMS ((tree, int)); --- 3714,3726 ---- extern tree define_label PARAMS ((const char *, int, tree)); extern void check_goto PARAMS ((tree)); extern void define_case_label PARAMS ((void)); ! extern cxx_binding *binding_for_name (tree, tree); extern tree namespace_binding PARAMS ((tree, tree)); extern void set_namespace_binding PARAMS ((tree, tree, tree)); extern tree lookup_namespace_name PARAMS ((tree, tree)); extern tree build_typename_type PARAMS ((tree, tree, tree, tree)); extern tree make_typename_type PARAMS ((tree, tree, tsubst_flags_t)); ! extern tree make_unbound_class_template PARAMS ((tree, tree, tsubst_flags_t)); extern tree lookup_name_nonclass PARAMS ((tree)); extern tree lookup_function_nonclass PARAMS ((tree, tree)); extern tree lookup_name PARAMS ((tree, int)); *************** extern tree lookup_name_namespace_only *** 3709,3717 **** extern void begin_only_namespace_names PARAMS ((void)); extern void end_only_namespace_names PARAMS ((void)); extern tree namespace_ancestor PARAMS ((tree, tree)); extern tree unqualified_namespace_lookup PARAMS ((tree, int, tree *)); ! extern int lookup_using_namespace PARAMS ((tree, tree, tree, tree, int, tree *)); ! extern int qualified_lookup_using_namespace PARAMS ((tree, tree, tree, int)); extern tree build_library_fn PARAMS ((tree, tree)); extern tree build_library_fn_ptr PARAMS ((const char *, tree)); extern tree build_cp_library_fn_ptr PARAMS ((const char *, tree)); --- 3730,3740 ---- extern void begin_only_namespace_names PARAMS ((void)); extern void end_only_namespace_names PARAMS ((void)); extern tree namespace_ancestor PARAMS ((tree, tree)); + extern bool is_ancestor (tree, tree); extern tree unqualified_namespace_lookup PARAMS ((tree, int, tree *)); ! extern tree check_for_out_of_scope_variable (tree); ! extern bool lookup_using_namespace (tree, cxx_binding *, tree, tree, int, tree *); ! extern bool qualified_lookup_using_namespace (tree, tree, cxx_binding *, int); extern tree build_library_fn PARAMS ((tree, tree)); extern tree build_library_fn_ptr PARAMS ((const char *, tree)); extern tree build_cp_library_fn_ptr PARAMS ((const char *, tree)); *************** extern void start_decl_1 PARAMS ((tree *** 3727,3746 **** extern void cp_finish_decl PARAMS ((tree, tree, tree, int)); extern void finish_decl PARAMS ((tree, tree, tree)); extern void maybe_inject_for_scope_var PARAMS ((tree)); - extern void initialize_local_var PARAMS ((tree, tree, int)); - extern void expand_static_init PARAMS ((tree, tree)); extern tree start_handler_parms PARAMS ((tree, tree)); extern int complete_array_type PARAMS ((tree, tree, int)); extern tree build_ptrmemfunc_type PARAMS ((tree)); /* the grokdeclarator prototype is in decl.h */ extern int parmlist_is_exprlist PARAMS ((tree)); extern int copy_fn_p PARAMS ((tree)); extern void grok_special_member_properties PARAMS ((tree)); extern int grok_ctor_properties PARAMS ((tree, tree)); extern void grok_op_properties PARAMS ((tree, int)); ! extern tree xref_tag PARAMS ((tree, tree, int)); extern tree xref_tag_from_type PARAMS ((tree, tree, int)); ! extern void xref_basetypes PARAMS ((tree, tree, tree, tree)); extern tree start_enum PARAMS ((tree)); extern void finish_enum PARAMS ((tree)); extern void build_enumerator PARAMS ((tree, tree, tree)); --- 3750,3768 ---- extern void cp_finish_decl PARAMS ((tree, tree, tree, int)); extern void finish_decl PARAMS ((tree, tree, tree)); extern void maybe_inject_for_scope_var PARAMS ((tree)); extern tree start_handler_parms PARAMS ((tree, tree)); extern int complete_array_type PARAMS ((tree, tree, int)); extern tree build_ptrmemfunc_type PARAMS ((tree)); + extern tree build_ptrmem_type (tree, tree); /* the grokdeclarator prototype is in decl.h */ extern int parmlist_is_exprlist PARAMS ((tree)); extern int copy_fn_p PARAMS ((tree)); extern void grok_special_member_properties PARAMS ((tree)); extern int grok_ctor_properties PARAMS ((tree, tree)); extern void grok_op_properties PARAMS ((tree, int)); ! extern tree xref_tag (enum tag_types, tree, tree, bool); extern tree xref_tag_from_type PARAMS ((tree, tree, int)); ! extern void xref_basetypes PARAMS ((tree, tree)); extern tree start_enum PARAMS ((tree)); extern void finish_enum PARAMS ((tree)); extern void build_enumerator PARAMS ((tree, tree, tree)); *************** extern tree finish_method PARAMS ((tre *** 3753,3759 **** extern void maybe_register_incomplete_var PARAMS ((tree)); extern void complete_vars PARAMS ((tree)); extern void finish_stmt PARAMS ((void)); ! extern void print_other_binding_stack PARAMS ((struct binding_level *)); extern void revert_static_member_fn PARAMS ((tree)); extern void fixup_anonymous_aggr PARAMS ((tree)); extern int check_static_variable_definition PARAMS ((tree, tree)); --- 3775,3781 ---- extern void maybe_register_incomplete_var PARAMS ((tree)); extern void complete_vars PARAMS ((tree)); extern void finish_stmt PARAMS ((void)); ! extern void print_other_binding_stack PARAMS ((struct cp_binding_level *)); extern void revert_static_member_fn PARAMS ((tree)); extern void fixup_anonymous_aggr PARAMS ((tree)); extern int check_static_variable_definition PARAMS ((tree, tree)); *************** typedef int (*walk_globals_fn) *** 3772,3777 **** --- 3794,3802 ---- extern int walk_globals PARAMS ((walk_globals_pred, walk_globals_fn, void *)); + extern int walk_vtables PARAMS ((walk_globals_pred, + walk_globals_fn, + void *)); typedef int (*walk_namespaces_fn) PARAMS ((tree, void *)); extern int walk_namespaces PARAMS ((walk_namespaces_fn, void *)); *************** extern int nonstatic_local_decl_p *** 3785,3796 **** extern tree declare_global_var PARAMS ((tree, tree)); extern void register_dtor_fn PARAMS ((tree)); extern tmpl_spec_kind current_tmpl_spec_kind PARAMS ((int)); extern tree cp_fname_init PARAMS ((const char *)); /* in decl2.c */ - extern void init_decl2 PARAMS ((void)); extern int check_java_method PARAMS ((tree)); - extern int cxx_decode_option PARAMS ((int, char **)); extern int grok_method_quals PARAMS ((tree, tree, tree)); extern void warn_if_unknown_interface PARAMS ((tree)); extern void grok_x_components PARAMS ((tree)); --- 3810,3821 ---- extern tree declare_global_var PARAMS ((tree, tree)); extern void register_dtor_fn PARAMS ((tree)); extern tmpl_spec_kind current_tmpl_spec_kind PARAMS ((int)); + extern cxx_binding *cxx_scope_find_binding_for_name (tree, tree); extern tree cp_fname_init PARAMS ((const char *)); + extern bool have_extern_spec; /* in decl2.c */ extern int check_java_method PARAMS ((tree)); extern int grok_method_quals PARAMS ((tree, tree, tree)); extern void warn_if_unknown_interface PARAMS ((tree)); extern void grok_x_components PARAMS ((tree)); *************** extern void check_member_template *** 3804,3813 **** extern tree grokfield PARAMS ((tree, tree, tree, tree, tree)); extern tree grokbitfield PARAMS ((tree, tree, tree)); extern tree groktypefield PARAMS ((tree, tree)); ! extern tree grokoptypename PARAMS ((tree, tree)); extern void cplus_decl_attributes PARAMS ((tree *, tree, int)); extern tree constructor_name_full PARAMS ((tree)); extern tree constructor_name PARAMS ((tree)); extern void defer_fn PARAMS ((tree)); extern void finish_anon_union PARAMS ((tree)); extern tree finish_table PARAMS ((tree, tree, tree, int)); --- 3829,3839 ---- extern tree grokfield PARAMS ((tree, tree, tree, tree, tree)); extern tree grokbitfield PARAMS ((tree, tree, tree)); extern tree groktypefield PARAMS ((tree, tree)); ! extern tree grokoptypename PARAMS ((tree, tree, tree)); extern void cplus_decl_attributes PARAMS ((tree *, tree, int)); extern tree constructor_name_full PARAMS ((tree)); extern tree constructor_name PARAMS ((tree)); + extern bool constructor_name_p (tree, tree); extern void defer_fn PARAMS ((tree)); extern void finish_anon_union PARAMS ((tree)); extern tree finish_table PARAMS ((tree, tree, tree, int)); *************** extern void finish_file PARAMS ((void *** 3824,3829 **** --- 3850,3857 ---- extern tree reparse_absdcl_as_expr PARAMS ((tree, tree)); extern tree reparse_absdcl_as_casts PARAMS ((tree, tree)); extern tree build_expr_from_tree PARAMS ((tree)); + extern tree build_offset_ref_call_from_tree (tree, tree); + extern tree build_call_from_tree (tree, tree, bool); extern tree reparse_decl_as_expr PARAMS ((tree, tree)); extern tree finish_decl_parsing PARAMS ((tree)); extern void set_decl_namespace PARAMS ((tree, tree, int)); *************** extern tree do_class_using_decl PARAMS *** 3839,3855 **** extern void do_using_directive PARAMS ((tree)); extern void check_default_args PARAMS ((tree)); extern void mark_used PARAMS ((tree)); ! extern tree handle_class_head PARAMS ((tree, tree, tree, int, int *)); extern tree lookup_arg_dependent PARAMS ((tree, tree, tree)); extern void finish_static_data_member_decl PARAMS ((tree, tree, tree, int)); extern tree build_artificial_parm PARAMS ((tree, tree)); extern tree get_guard PARAMS ((tree)); extern tree get_guard_cond PARAMS ((tree)); extern tree set_guard PARAMS ((tree)); - /* in parse.y */ - extern void cp_parse_init PARAMS ((void)); - extern void cp_error_at PARAMS ((const char *msgid, ...)); extern void cp_warning_at PARAMS ((const char *msgid, ...)); extern void cp_pedwarn_at PARAMS ((const char *msgid, ...)); --- 3867,3881 ---- extern void do_using_directive PARAMS ((tree)); extern void check_default_args PARAMS ((tree)); extern void mark_used PARAMS ((tree)); ! extern tree handle_class_head (enum tag_types, tree, tree, tree, int, int *); extern tree lookup_arg_dependent PARAMS ((tree, tree, tree)); extern void finish_static_data_member_decl PARAMS ((tree, tree, tree, int)); + extern tree cp_build_parm_decl PARAMS ((tree, tree)); extern tree build_artificial_parm PARAMS ((tree, tree)); extern tree get_guard PARAMS ((tree)); extern tree get_guard_cond PARAMS ((tree)); extern tree set_guard PARAMS ((tree)); extern void cp_error_at PARAMS ((const char *msgid, ...)); extern void cp_warning_at PARAMS ((const char *msgid, ...)); extern void cp_pedwarn_at PARAMS ((const char *msgid, ...)); *************** extern void check_handlers PARAMS ((tr *** 3889,3896 **** extern void choose_personality_routine PARAMS ((enum languages)); /* in expr.c */ ! extern void init_cplus_expand PARAMS ((void)); ! extern int extract_init PARAMS ((tree, tree)); extern tree cplus_expand_constant PARAMS ((tree)); /* friend.c */ --- 3915,3923 ---- extern void choose_personality_routine PARAMS ((enum languages)); /* in expr.c */ ! extern rtx cxx_expand_expr PARAMS ((tree, rtx, ! enum machine_mode, ! int)); extern tree cplus_expand_constant PARAMS ((tree)); /* friend.c */ *************** extern void add_friend *** 3900,3921 **** extern tree do_friend PARAMS ((tree, tree, tree, tree, tree, enum overload_flags, tree, int)); /* in init.c */ ! extern void init_init_processing PARAMS ((void)); ! extern void emit_base_init PARAMS ((tree, tree)); ! extern tree expand_member_init PARAMS ((tree, tree, tree)); extern tree build_aggr_init PARAMS ((tree, tree, int)); extern int is_aggr_type PARAMS ((tree, int)); extern tree get_aggr_from_typedef PARAMS ((tree, int)); extern tree get_type_value PARAMS ((tree)); ! extern tree build_forced_zero_init PARAMS ((tree)); extern tree build_member_call PARAMS ((tree, tree, tree)); extern tree build_offset_ref PARAMS ((tree, tree)); extern tree resolve_offset_ref PARAMS ((tree)); extern tree build_new PARAMS ((tree, tree, tree, int)); ! extern tree build_vec_init PARAMS ((tree, tree, int)); extern tree build_x_delete PARAMS ((tree, int, tree)); extern tree build_delete PARAMS ((tree, tree, special_function_kind, int, int)); ! extern void perform_base_cleanups PARAMS ((void)); extern tree build_vbase_delete PARAMS ((tree, tree)); extern tree build_vec_delete PARAMS ((tree, tree, special_function_kind, int)); extern tree create_temporary_var PARAMS ((tree)); --- 3927,3948 ---- extern tree do_friend PARAMS ((tree, tree, tree, tree, tree, enum overload_flags, tree, int)); /* in init.c */ ! extern tree expand_member_init (tree); ! extern void emit_mem_initializers (tree); extern tree build_aggr_init PARAMS ((tree, tree, int)); + extern tree build_init PARAMS ((tree, tree, int)); extern int is_aggr_type PARAMS ((tree, int)); extern tree get_aggr_from_typedef PARAMS ((tree, int)); extern tree get_type_value PARAMS ((tree)); ! extern tree build_zero_init (tree, tree, bool); extern tree build_member_call PARAMS ((tree, tree, tree)); extern tree build_offset_ref PARAMS ((tree, tree)); extern tree resolve_offset_ref PARAMS ((tree)); extern tree build_new PARAMS ((tree, tree, tree, int)); ! extern tree build_vec_init PARAMS ((tree, tree, tree, int)); extern tree build_x_delete PARAMS ((tree, int, tree)); extern tree build_delete PARAMS ((tree, tree, special_function_kind, int, int)); ! extern void push_base_cleanups PARAMS ((void)); extern tree build_vbase_delete PARAMS ((tree, tree)); extern tree build_vec_delete PARAMS ((tree, tree, special_function_kind, int)); extern tree create_temporary_var PARAMS ((tree)); *************** extern tree build_java_class_ref *** 3927,3932 **** --- 3954,3960 ---- /* in input.c */ /* in lex.c */ + extern void cxx_dup_lang_specific_decl PARAMS ((tree)); extern tree make_pointer_declarator PARAMS ((tree, tree)); extern tree make_reference_declarator PARAMS ((tree, tree)); extern tree make_call_declarator PARAMS ((tree, tree, tree, tree)); *************** extern void note_got_semicolon PARAMS *** 3943,3961 **** extern void note_list_got_semicolon PARAMS ((tree)); extern void do_pending_lang_change PARAMS ((void)); extern void see_typename PARAMS ((void)); extern tree do_identifier PARAMS ((tree, int, tree)); ! extern tree do_scoped_id PARAMS ((tree, int)); extern tree identifier_typedecl_value PARAMS ((tree)); extern tree build_lang_decl PARAMS ((enum tree_code, tree, tree)); extern void retrofit_lang_decl PARAMS ((tree)); extern tree copy_decl PARAMS ((tree)); extern tree copy_type PARAMS ((tree)); ! extern tree cp_make_lang_type PARAMS ((enum tree_code)); extern tree make_aggr_type PARAMS ((enum tree_code)); - extern void compiler_error PARAMS ((const char *, ...)) - ATTRIBUTE_PRINTF_1; extern void yyerror PARAMS ((const char *)); - extern void clear_inline_text_obstack PARAMS ((void)); extern void yyhook PARAMS ((int)); extern int cp_type_qual_from_rid PARAMS ((tree)); extern const char *cxx_init PARAMS ((const char *)); --- 3971,3987 ---- extern void note_list_got_semicolon PARAMS ((tree)); extern void do_pending_lang_change PARAMS ((void)); extern void see_typename PARAMS ((void)); + extern void unqualified_name_lookup_error PARAMS ((tree)); extern tree do_identifier PARAMS ((tree, int, tree)); ! extern tree do_scoped_id PARAMS ((tree, tree)); extern tree identifier_typedecl_value PARAMS ((tree)); extern tree build_lang_decl PARAMS ((enum tree_code, tree, tree)); extern void retrofit_lang_decl PARAMS ((tree)); extern tree copy_decl PARAMS ((tree)); extern tree copy_type PARAMS ((tree)); ! extern tree cxx_make_type PARAMS ((enum tree_code)); extern tree make_aggr_type PARAMS ((enum tree_code)); extern void yyerror PARAMS ((const char *)); extern void yyhook PARAMS ((int)); extern int cp_type_qual_from_rid PARAMS ((tree)); extern const char *cxx_init PARAMS ((const char *)); *************** extern int calls_setjmp_p *** 3979,3985 **** extern int maybe_clone_body PARAMS ((tree)); /* in pt.c */ - extern void init_pt PARAMS ((void)); extern void check_template_shadow PARAMS ((tree)); extern tree get_innermost_template_args PARAMS ((tree, int)); extern tree tsubst PARAMS ((tree, tree, tsubst_flags_t, tree)); --- 4005,4010 ---- *************** extern tree tinst_for_decl PARAMS ((vo *** 4012,4018 **** extern void mark_decl_instantiated PARAMS ((tree, int)); extern int more_specialized PARAMS ((tree, tree, int, int)); extern void mark_class_instantiated PARAMS ((tree, int)); ! extern void do_decl_instantiation PARAMS ((tree, tree, tree)); extern void do_type_instantiation PARAMS ((tree, tree, tsubst_flags_t)); extern tree instantiate_decl PARAMS ((tree, int)); extern tree get_bindings PARAMS ((tree, tree, tree)); --- 4037,4043 ---- extern void mark_decl_instantiated PARAMS ((tree, int)); extern int more_specialized PARAMS ((tree, tree, int, int)); extern void mark_class_instantiated PARAMS ((tree, int)); ! extern void do_decl_instantiation (tree, tree); extern void do_type_instantiation PARAMS ((tree, tree, tsubst_flags_t)); extern tree instantiate_decl PARAMS ((tree, int)); extern tree get_bindings PARAMS ((tree, tree, tree)); *************** extern int push_tinst_level PARAMS ((t *** 4020,4026 **** extern void pop_tinst_level PARAMS ((void)); extern int more_specialized_class PARAMS ((tree, tree)); extern int is_member_template PARAMS ((tree)); - extern int template_parms_equal PARAMS ((tree, tree)); extern int comp_template_parms PARAMS ((tree, tree)); extern int template_class_depth PARAMS ((tree)); extern int is_specialization_of PARAMS ((tree, tree)); --- 4045,4050 ---- *************** extern void print_candidates *** 4032,4038 **** extern int instantiate_pending_templates PARAMS ((void)); extern tree tsubst_default_argument PARAMS ((tree, tree, tree)); extern tree most_general_template PARAMS ((tree)); ! extern tree get_mostly_instantiated_function_type PARAMS ((tree, tree *, tree *)); extern int problematic_instantiation_changed PARAMS ((void)); extern void record_last_problematic_instantiation PARAMS ((void)); extern tree current_instantiation PARAMS ((void)); --- 4056,4062 ---- extern int instantiate_pending_templates PARAMS ((void)); extern tree tsubst_default_argument PARAMS ((tree, tree, tree)); extern tree most_general_template PARAMS ((tree)); ! extern tree get_mostly_instantiated_function_type PARAMS ((tree)); extern int problematic_instantiation_changed PARAMS ((void)); extern void record_last_problematic_instantiation PARAMS ((void)); extern tree current_instantiation PARAMS ((void)); *************** extern tree get_vbase PARAMS ((tree, *** 4061,4066 **** --- 4085,4091 ---- extern tree get_dynamic_cast_base_type PARAMS ((tree, tree)); extern void type_access_control PARAMS ((tree, tree)); extern int accessible_p PARAMS ((tree, tree)); + extern tree lookup_field_1 (tree, tree, bool); extern tree lookup_field PARAMS ((tree, tree, int, int)); extern tree lookup_nested_field PARAMS ((tree, int)); extern int lookup_fnfields_1 PARAMS ((tree, tree)); *************** extern void init_search_processing PARA *** 4079,4084 **** --- 4104,4110 ---- extern void reinit_search_statistics PARAMS ((void)); extern tree current_scope PARAMS ((void)); extern int at_function_scope_p PARAMS ((void)); + extern bool at_class_scope_p (void); extern tree context_for_name_lookup PARAMS ((tree)); extern tree lookup_conversions PARAMS ((tree)); extern tree binfo_for_vtable PARAMS ((tree)); *************** extern tree unmarked_vtable_pathp *** 4105,4111 **** extern tree find_vbase_instance PARAMS ((tree, tree)); extern tree binfo_for_vbase PARAMS ((tree, tree)); extern tree binfo_via_virtual PARAMS ((tree, tree)); ! /* in semantics.c */ extern void init_cp_semantics PARAMS ((void)); extern tree finish_expr_stmt PARAMS ((tree)); --- 4131,4139 ---- extern tree find_vbase_instance PARAMS ((tree, tree)); extern tree binfo_for_vbase PARAMS ((tree, tree)); extern tree binfo_via_virtual PARAMS ((tree, tree)); ! extern tree build_baselink (tree, tree, tree, tree); ! extern tree adjust_result_of_qualified_name_lookup ! (tree, tree, tree); /* in semantics.c */ extern void init_cp_semantics PARAMS ((void)); extern tree finish_expr_stmt PARAMS ((tree)); *************** extern void finish_subobject *** 4157,4175 **** extern tree finish_parenthesized_expr PARAMS ((tree)); extern tree begin_stmt_expr PARAMS ((void)); extern tree finish_stmt_expr PARAMS ((tree)); ! extern tree finish_call_expr PARAMS ((tree, tree, int)); extern tree finish_increment_expr PARAMS ((tree, enum tree_code)); extern tree finish_this_expr PARAMS ((void)); extern tree finish_object_call_expr PARAMS ((tree, tree, tree)); extern tree finish_qualified_object_call_expr PARAMS ((tree, tree, tree)); extern tree finish_pseudo_destructor_call_expr PARAMS ((tree, tree, tree)); - extern tree finish_qualified_call_expr PARAMS ((tree, tree)); extern tree finish_unary_op_expr PARAMS ((enum tree_code, tree)); extern tree finish_id_expr PARAMS ((tree)); extern void save_type_access_control PARAMS ((tree)); extern void reset_type_access_control PARAMS ((void)); extern void decl_type_access_control PARAMS ((tree)); ! extern int begin_function_definition PARAMS ((tree, tree)); extern tree begin_constructor_declarator PARAMS ((tree, tree)); extern tree finish_declarator PARAMS ((tree, tree, tree, tree, int)); extern void finish_translation_unit PARAMS ((void)); --- 4185,4203 ---- extern tree finish_parenthesized_expr PARAMS ((tree)); extern tree begin_stmt_expr PARAMS ((void)); extern tree finish_stmt_expr PARAMS ((tree)); ! extern tree finish_call_expr (tree, tree, bool); extern tree finish_increment_expr PARAMS ((tree, enum tree_code)); extern tree finish_this_expr PARAMS ((void)); extern tree finish_object_call_expr PARAMS ((tree, tree, tree)); extern tree finish_qualified_object_call_expr PARAMS ((tree, tree, tree)); extern tree finish_pseudo_destructor_call_expr PARAMS ((tree, tree, tree)); extern tree finish_unary_op_expr PARAMS ((enum tree_code, tree)); extern tree finish_id_expr PARAMS ((tree)); + extern tree finish_fname (tree); extern void save_type_access_control PARAMS ((tree)); extern void reset_type_access_control PARAMS ((void)); extern void decl_type_access_control PARAMS ((tree)); ! extern int begin_function_definition (tree, tree, tree); extern tree begin_constructor_declarator PARAMS ((tree, tree)); extern tree finish_declarator PARAMS ((tree, tree, tree, tree, int)); extern void finish_translation_unit PARAMS ((void)); *************** extern tree begin_class_definition *** 4180,4186 **** extern tree finish_class_definition PARAMS ((tree, tree, int, int)); extern void finish_default_args PARAMS ((void)); extern void begin_inline_definitions PARAMS ((void)); - extern void finish_inline_definitions PARAMS ((void)); extern tree finish_member_class_template PARAMS ((tree)); extern void finish_template_decl PARAMS ((tree)); extern tree finish_template_type PARAMS ((tree, tree, int)); --- 4208,4213 ---- *************** extern tree finish_typeof PARAMS ((tre *** 4192,4212 **** extern tree finish_sizeof PARAMS ((tree)); extern tree finish_alignof PARAMS ((tree)); extern void finish_decl_cleanup PARAMS ((tree, tree)); extern void finish_named_return_value PARAMS ((tree, tree)); extern void expand_body PARAMS ((tree)); extern tree nullify_returns_r PARAMS ((tree *, int *, void *)); extern void do_pushlevel PARAMS ((void)); extern tree do_poplevel PARAMS ((void)); extern void finish_mem_initializers PARAMS ((tree)); extern void setup_vtbl_ptr PARAMS ((tree, tree)); extern void clear_out_block PARAMS ((void)); extern tree begin_global_stmt_expr PARAMS ((void)); extern tree finish_global_stmt_expr PARAMS ((tree)); ! /* in spew.c */ extern void init_spew PARAMS ((void)); - extern void mark_pending_inlines PARAMS ((PTR)); extern int peekyylex PARAMS ((void)); extern tree arbitrate_lookup PARAMS ((tree, tree, tree)); extern tree frob_opname PARAMS ((tree)); --- 4219,4240 ---- extern tree finish_sizeof PARAMS ((tree)); extern tree finish_alignof PARAMS ((tree)); extern void finish_decl_cleanup PARAMS ((tree, tree)); + extern void finish_eh_cleanup PARAMS ((tree)); extern void finish_named_return_value PARAMS ((tree, tree)); extern void expand_body PARAMS ((tree)); extern tree nullify_returns_r PARAMS ((tree *, int *, void *)); extern void do_pushlevel PARAMS ((void)); extern tree do_poplevel PARAMS ((void)); + extern void begin_mem_initializers (void); extern void finish_mem_initializers PARAMS ((tree)); extern void setup_vtbl_ptr PARAMS ((tree, tree)); extern void clear_out_block PARAMS ((void)); extern tree begin_global_stmt_expr PARAMS ((void)); extern tree finish_global_stmt_expr PARAMS ((tree)); ! extern tree check_template_template_default_arg (tree); /* in spew.c */ extern void init_spew PARAMS ((void)); extern int peekyylex PARAMS ((void)); extern tree arbitrate_lookup PARAMS ((tree, tree, tree)); extern tree frob_opname PARAMS ((tree)); *************** extern void replace_defarg PARAMS ((tr *** 4219,4224 **** --- 4247,4257 ---- extern void end_input PARAMS ((void)); /* in tree.c */ + extern void lang_check_failed PARAMS ((const char *, int, + const char *)); + extern tree stabilize_expr PARAMS ((tree, tree *)); + extern tree cxx_unsave_expr_now PARAMS ((tree)); + extern tree cxx_maybe_build_cleanup PARAMS ((tree)); extern void init_tree PARAMS ((void)); extern int pod_type_p PARAMS ((tree)); extern int zero_init_p PARAMS ((tree)); *************** extern tree canonical_type_variant *** 4226,4232 **** extern void unshare_base_binfos PARAMS ((tree)); extern int member_p PARAMS ((tree)); extern cp_lvalue_kind real_lvalue_p PARAMS ((tree)); ! extern tree build_min PARAMS ((enum tree_code, tree, ...)); extern tree build_min_nt PARAMS ((enum tree_code, ...)); extern tree build_cplus_new PARAMS ((tree, tree)); extern tree get_target_expr PARAMS ((tree)); --- 4259,4269 ---- extern void unshare_base_binfos PARAMS ((tree)); extern int member_p PARAMS ((tree)); extern cp_lvalue_kind real_lvalue_p PARAMS ((tree)); ! extern cp_lvalue_kind real_non_cast_lvalue_p (tree); ! extern int non_cast_lvalue_p PARAMS ((tree)); ! extern int non_cast_lvalue_or_else PARAMS ((tree, const char *)); ! extern tree build_min PARAMS ((enum tree_code, tree, ! ...)); extern tree build_min_nt PARAMS ((enum tree_code, ...)); extern tree build_cplus_new PARAMS ((tree, tree)); extern tree get_target_expr PARAMS ((tree)); *************** extern tree make_binfo PARAMS ((tree, *** 4241,4246 **** --- 4278,4284 ---- extern tree reverse_path PARAMS ((tree)); extern int count_functions PARAMS ((tree)); extern int is_overloaded_fn PARAMS ((tree)); + extern tree get_overloaded_fn PARAMS ((tree)); extern tree get_first_fn PARAMS ((tree)); extern int bound_pmf_p PARAMS ((tree)); extern tree ovl_cons PARAMS ((tree, tree)); *************** extern tree build_overload *** 4248,4254 **** extern tree function_arg_chain PARAMS ((tree)); extern int promotes_to_aggr_type PARAMS ((tree, enum tree_code)); extern int is_aggr_type_2 PARAMS ((tree, tree)); ! extern const char *lang_printable_name PARAMS ((tree, int)); extern tree build_exception_variant PARAMS ((tree, tree)); extern tree bind_template_template_parm PARAMS ((tree, tree)); extern tree array_type_nelts_total PARAMS ((tree)); --- 4286,4292 ---- extern tree function_arg_chain PARAMS ((tree)); extern int promotes_to_aggr_type PARAMS ((tree, enum tree_code)); extern int is_aggr_type_2 PARAMS ((tree, tree)); ! extern const char *cxx_printable_name PARAMS ((tree, int)); extern tree build_exception_variant PARAMS ((tree, tree)); extern tree bind_template_template_parm PARAMS ((tree, tree)); extern tree array_type_nelts_total PARAMS ((tree)); *************** extern tree vec_binfo_member PARAMS (( *** 4259,4266 **** extern tree decl_namespace_context PARAMS ((tree)); extern tree lvalue_type PARAMS ((tree)); extern tree error_type PARAMS ((tree)); ! extern tree build_ptr_wrapper PARAMS ((void *)); ! extern tree build_int_wrapper PARAMS ((int)); extern tree build_srcloc_here PARAMS ((void)); extern int varargs_function_p PARAMS ((tree)); extern int really_overloaded_fn PARAMS ((tree)); --- 4297,4303 ---- extern tree decl_namespace_context PARAMS ((tree)); extern tree lvalue_type PARAMS ((tree)); extern tree error_type PARAMS ((tree)); ! extern tree build_zc_wrapper PARAMS ((struct z_candidate *)); extern tree build_srcloc_here PARAMS ((void)); extern int varargs_function_p PARAMS ((tree)); extern int really_overloaded_fn PARAMS ((tree)); *************** extern void debug_binfo PARAMS ((tree *** 4270,4282 **** extern tree build_dummy_object PARAMS ((tree)); extern tree maybe_dummy_object PARAMS ((tree, tree *)); extern int is_dummy_object PARAMS ((tree)); ! extern const struct attribute_spec cp_attribute_table[]; extern tree make_ptrmem_cst PARAMS ((tree, tree)); extern tree cp_build_qualified_type_real PARAMS ((tree, int, tsubst_flags_t)); #define cp_build_qualified_type(TYPE, QUALS) \ cp_build_qualified_type_real ((TYPE), (QUALS), tf_error | tf_warning) extern tree build_shared_int_cst PARAMS ((int)); extern special_function_kind special_function_p PARAMS ((tree)); extern int count_trees PARAMS ((tree)); extern int char_type_p PARAMS ((tree)); extern void verify_stmt_tree PARAMS ((tree)); --- 4307,4320 ---- extern tree build_dummy_object PARAMS ((tree)); extern tree maybe_dummy_object PARAMS ((tree, tree *)); extern int is_dummy_object PARAMS ((tree)); ! extern const struct attribute_spec cxx_attribute_table[]; extern tree make_ptrmem_cst PARAMS ((tree, tree)); extern tree cp_build_qualified_type_real PARAMS ((tree, int, tsubst_flags_t)); #define cp_build_qualified_type(TYPE, QUALS) \ cp_build_qualified_type_real ((TYPE), (QUALS), tf_error | tf_warning) extern tree build_shared_int_cst PARAMS ((int)); extern special_function_kind special_function_p PARAMS ((tree)); + extern bool name_p (tree); extern int count_trees PARAMS ((tree)); extern int char_type_p PARAMS ((tree)); extern void verify_stmt_tree PARAMS ((tree)); *************** extern tree condition_conversion PARAMS *** 4300,4306 **** extern tree target_type PARAMS ((tree)); extern tree require_complete_type PARAMS ((tree)); extern tree complete_type PARAMS ((tree)); ! extern tree complete_type_or_else PARAMS ((tree, tree)); extern int type_unknown_p PARAMS ((tree)); extern tree commonparms PARAMS ((tree, tree)); extern tree original_type PARAMS ((tree)); --- 4338,4345 ---- extern tree target_type PARAMS ((tree)); extern tree require_complete_type PARAMS ((tree)); extern tree complete_type PARAMS ((tree)); ! extern tree complete_type_or_diagnostic PARAMS ((tree, tree, int)); ! #define complete_type_or_else(T,V) (complete_type_or_diagnostic ((T), (V), 0)) extern int type_unknown_p PARAMS ((tree)); extern tree commonparms PARAMS ((tree, tree)); extern tree original_type PARAMS ((tree)); *************** extern int compparms PARAMS ((tree, t *** 4311,4327 **** extern int comp_cv_qualification PARAMS ((tree, tree)); extern int comp_cv_qual_signature PARAMS ((tree, tree)); extern tree expr_sizeof PARAMS ((tree)); ! extern tree c_sizeof_nowarn PARAMS ((tree)); extern tree inline_conversion PARAMS ((tree)); extern tree decay_conversion PARAMS ((tree)); ! extern tree build_object_ref PARAMS ((tree, tree, tree)); ! extern tree build_component_ref_1 PARAMS ((tree, tree, int)); ! extern tree build_component_ref PARAMS ((tree, tree, tree, int)); ! extern tree build_x_component_ref PARAMS ((tree, tree, tree, int)); extern tree build_x_indirect_ref PARAMS ((tree, const char *)); extern tree build_indirect_ref PARAMS ((tree, const char *)); extern tree build_array_ref PARAMS ((tree, tree)); - extern tree build_x_function_call PARAMS ((tree, tree, tree)); extern tree get_member_function_from_ptrfunc PARAMS ((tree *, tree)); extern tree build_function_call_real PARAMS ((tree, tree, int, int)); extern tree build_function_call_maybe PARAMS ((tree, tree)); --- 4350,4364 ---- extern int comp_cv_qualification PARAMS ((tree, tree)); extern int comp_cv_qual_signature PARAMS ((tree, tree)); extern tree expr_sizeof PARAMS ((tree)); ! extern tree cxx_sizeof_or_alignof_type PARAMS ((tree, enum tree_code, int)); ! #define cxx_sizeof_nowarn(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, false) extern tree inline_conversion PARAMS ((tree)); extern tree decay_conversion PARAMS ((tree)); ! extern tree build_class_member_access_expr (tree, tree, tree, bool); ! extern tree finish_class_member_access_expr (tree, tree); extern tree build_x_indirect_ref PARAMS ((tree, const char *)); extern tree build_indirect_ref PARAMS ((tree, const char *)); extern tree build_array_ref PARAMS ((tree, tree)); extern tree get_member_function_from_ptrfunc PARAMS ((tree *, tree)); extern tree build_function_call_real PARAMS ((tree, tree, int, int)); extern tree build_function_call_maybe PARAMS ((tree, tree)); *************** extern tree merge_types PARAMS ((tree *** 4357,4376 **** extern tree check_return_expr PARAMS ((tree)); #define cp_build_binary_op(code, arg1, arg2) \ build_binary_op(code, arg1, arg2, 1) /* in typeck2.c */ extern tree error_not_base_type PARAMS ((tree, tree)); extern tree binfo_or_else PARAMS ((tree, tree)); extern void readonly_error PARAMS ((tree, const char *, int)); extern int abstract_virtuals_error PARAMS ((tree, tree)); - #define my_friendly_assert(EXP, N) (void) \ - (((EXP) == 0) ? (fancy_abort (__FILE__, __LINE__, __FUNCTION__), 0) : 0) - - extern tree force_store_init_value PARAMS ((tree, tree)); extern tree store_init_value PARAMS ((tree, tree)); extern tree digest_init PARAMS ((tree, tree, tree *)); ! extern tree build_scoped_ref PARAMS ((tree, tree)); extern tree build_x_arrow PARAMS ((tree)); extern tree build_m_component_ref PARAMS ((tree, tree)); extern tree build_functional_cast PARAMS ((tree, tree)); --- 4394,4420 ---- extern tree check_return_expr PARAMS ((tree)); #define cp_build_binary_op(code, arg1, arg2) \ build_binary_op(code, arg1, arg2, 1) + #define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true) + #define cxx_alignof(T) cxx_sizeof_or_alignof_type (T, ALIGNOF_EXPR, true) + extern tree build_ptrmemfunc_access_expr (tree, tree); + extern tree build_address (tree); + extern tree build_nop (tree, tree); /* in typeck2.c */ + extern void require_complete_eh_spec_types PARAMS ((tree, tree)); + extern void cxx_incomplete_type_diagnostic PARAMS ((tree, tree, int)); + #undef cxx_incomplete_type_error + extern void cxx_incomplete_type_error PARAMS ((tree, tree)); + #define cxx_incomplete_type_error(V,T) \ + (cxx_incomplete_type_diagnostic ((V), (T), 0)) extern tree error_not_base_type PARAMS ((tree, tree)); extern tree binfo_or_else PARAMS ((tree, tree)); extern void readonly_error PARAMS ((tree, const char *, int)); extern int abstract_virtuals_error PARAMS ((tree, tree)); extern tree store_init_value PARAMS ((tree, tree)); extern tree digest_init PARAMS ((tree, tree, tree *)); ! extern tree build_scoped_ref PARAMS ((tree, tree, tree *)); extern tree build_x_arrow PARAMS ((tree)); extern tree build_m_component_ref PARAMS ((tree, tree)); extern tree build_functional_cast PARAMS ((tree, tree)); diff -Nrc3pad gcc-3.2.3/gcc/cp/cvt.c gcc-3.3/gcc/cp/cvt.c *** gcc-3.2.3/gcc/cp/cvt.c 2002-12-13 21:54:46.000000000 +0000 --- gcc-3.3/gcc/cp/cvt.c 2003-03-29 00:50:09.000000000 +0000 *************** static void warn_ref_binding PARAMS ((tr *** 52,58 **** narrowing is always done with a NOP_EXPR: In convert.c, convert_to_integer. In c-typeck.c, build_binary_op_nodefault (boolean ops), ! and truthvalue_conversion. In expr.c: expand_expr, for operands of a MULT_EXPR. In fold-const.c: fold. In tree.c: get_narrower and get_unwidened. --- 52,58 ---- narrowing is always done with a NOP_EXPR: In convert.c, convert_to_integer. In c-typeck.c, build_binary_op_nodefault (boolean ops), ! and c_common_truthvalue_conversion. In expr.c: expand_expr, for operands of a MULT_EXPR. In fold-const.c: fold. In tree.c: get_narrower and get_unwidened. *************** cp_convert_to_pointer (type, expr, force *** 90,96 **** return error_mark_node; } ! rval = build_type_conversion (type, expr, 1); if (rval) { if (rval == error_mark_node) --- 90,96 ---- return error_mark_node; } ! rval = build_type_conversion (type, expr); if (rval) { if (rval == error_mark_node) *************** cp_convert_to_pointer (type, expr, force *** 130,135 **** --- 130,138 ---- intype = TREE_TYPE (expr); } + if (expr == error_mark_node) + return error_mark_node; + form = TREE_CODE (intype); if (POINTER_TYPE_P (intype)) *************** cp_convert_to_pointer (type, expr, force *** 145,175 **** { enum tree_code code = PLUS_EXPR; tree binfo; ! /* Try derived to base conversion. */ ! binfo = lookup_base (TREE_TYPE (intype), TREE_TYPE (type), ! ba_check, NULL); ! if (!binfo) { ! /* Try base to derived conversion. */ ! binfo = lookup_base (TREE_TYPE (type), TREE_TYPE (intype), ! ba_check, NULL); code = MINUS_EXPR; } if (binfo == error_mark_node) return error_mark_node; ! if (binfo) { ! expr = build_base_path (code, expr, binfo, 0); ! /* Add any qualifier conversions. */ ! if (!same_type_p (TREE_TYPE (TREE_TYPE (expr)), ! TREE_TYPE (type))) ! { ! expr = build1 (NOP_EXPR, type, expr); ! TREE_CONSTANT (expr) = ! TREE_CONSTANT (TREE_OPERAND (expr, 0)); ! } ! return expr; } } --- 148,180 ---- { enum tree_code code = PLUS_EXPR; tree binfo; + tree intype_class; + tree type_class; + bool same_p; ! intype_class = TREE_TYPE (intype); ! type_class = TREE_TYPE (type); ! ! same_p = same_type_p (TYPE_MAIN_VARIANT (intype_class), ! TYPE_MAIN_VARIANT (type_class)); ! binfo = NULL_TREE; ! /* Try derived to base conversion. */ ! if (!same_p) ! binfo = lookup_base (intype_class, type_class, ba_check, NULL); ! if (!same_p && !binfo) { ! /* Try base to derived conversion. */ ! binfo = lookup_base (type_class, intype_class, ba_check, NULL); code = MINUS_EXPR; } if (binfo == error_mark_node) return error_mark_node; ! if (binfo || same_p) { ! if (binfo) ! expr = build_base_path (code, expr, binfo, 0); ! /* Add any qualifier conversions. */ ! return build_nop (type, expr); } } *************** cp_convert_to_pointer (type, expr, force *** 222,230 **** return error_mark_node; } ! rval = build1 (NOP_EXPR, type, expr); ! TREE_CONSTANT (rval) = TREE_CONSTANT (expr); ! return rval; } else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)) return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0); --- 227,233 ---- return error_mark_node; } ! return build_nop (type, expr); } else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)) return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0); *************** cp_convert_to_pointer (type, expr, force *** 253,264 **** force_fit_type (expr, 0); return expr; } if (INTEGRAL_CODE_P (form)) { if (TYPE_PRECISION (intype) == POINTER_SIZE) return build1 (CONVERT_EXPR, type, expr); ! expr = cp_convert (type_for_size (POINTER_SIZE, 0), expr); /* Modes may be different but sizes should be the same. */ if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))) != GET_MODE_SIZE (TYPE_MODE (type))) --- 256,273 ---- force_fit_type (expr, 0); return expr; } + else if ((TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type)) + && INTEGRAL_CODE_P (form)) + { + error ("invalid conversion from '%T' to '%T'", intype, type); + return error_mark_node; + } if (INTEGRAL_CODE_P (form)) { if (TYPE_PRECISION (intype) == POINTER_SIZE) return build1 (CONVERT_EXPR, type, expr); ! expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr); /* Modes may be different but sizes should be the same. */ if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))) != GET_MODE_SIZE (TYPE_MODE (type))) *************** convert_to_pointer_force (type, expr) *** 313,331 **** if (binfo) { expr = build_base_path (code, expr, binfo, 0); ! if (expr == error_mark_node) ! return error_mark_node; ! /* Add any qualifier conversions. */ if (!same_type_p (TREE_TYPE (TREE_TYPE (expr)), TREE_TYPE (type))) ! { ! expr = build1 (NOP_EXPR, type, expr); ! TREE_CONSTANT (expr) = ! TREE_CONSTANT (TREE_OPERAND (expr, 0)); ! } return expr; } - } } --- 322,335 ---- if (binfo) { expr = build_base_path (code, expr, binfo, 0); ! if (expr == error_mark_node) ! return error_mark_node; ! /* Add any qualifier conversions. */ if (!same_type_p (TREE_TYPE (TREE_TYPE (expr)), TREE_TYPE (type))) ! expr = build_nop (type, expr); return expr; } } } *************** build_up_reference (type, arg, flags, de *** 348,354 **** tree rval; tree argtype = TREE_TYPE (arg); tree target_type = TREE_TYPE (type); - tree stmt_expr = NULL_TREE; my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 187); --- 352,357 ---- *************** build_up_reference (type, arg, flags, de *** 358,382 **** here because it needs to live as long as DECL. */ tree targ = arg; ! arg = build_decl (VAR_DECL, NULL_TREE, argtype); ! DECL_ARTIFICIAL (arg) = 1; ! TREE_USED (arg) = 1; ! TREE_STATIC (arg) = TREE_STATIC (decl); ! ! if (TREE_STATIC (decl)) ! { ! /* Namespace-scope or local static; give it a mangled name. */ ! tree name = mangle_ref_init_variable (decl); ! DECL_NAME (arg) = name; ! SET_DECL_ASSEMBLER_NAME (arg, name); ! arg = pushdecl_top_level (arg); ! } ! else ! { ! /* Automatic; make sure we handle the cleanup properly. */ ! maybe_push_cleanup_level (argtype); ! arg = pushdecl (arg); ! } /* Process the initializer for the declaration. */ DECL_INITIAL (arg) = targ; --- 361,367 ---- here because it needs to live as long as DECL. */ tree targ = arg; ! arg = make_temporary_var_for_ref_to_temp (decl, TREE_TYPE (arg)); /* Process the initializer for the declaration. */ DECL_INITIAL (arg) = targ; *************** build_up_reference (type, arg, flags, de *** 409,424 **** else rval = convert_to_pointer_force (build_pointer_type (target_type), rval); ! rval = build1 (NOP_EXPR, type, rval); ! TREE_CONSTANT (rval) = TREE_CONSTANT (TREE_OPERAND (rval, 0)); ! ! /* If we created and initialized a new temporary variable, add the ! representation of that initialization to the RVAL. */ ! if (stmt_expr) ! rval = build (COMPOUND_EXPR, TREE_TYPE (rval), stmt_expr, rval); ! ! /* And return the result. */ ! return rval; } /* Subroutine of convert_to_reference. REFTYPE is the target reference type. --- 394,400 ---- else rval = convert_to_pointer_force (build_pointer_type (target_type), rval); ! return build_nop (type, rval); } /* Subroutine of convert_to_reference. REFTYPE is the target reference type. *************** convert_to_reference (reftype, expr, con *** 500,506 **** /* Look for a user-defined conversion to lvalue that we can use. */ rval_as_conversion ! = build_type_conversion (reftype, expr, 1); if (rval_as_conversion && rval_as_conversion != error_mark_node && real_lvalue_p (rval_as_conversion)) --- 476,482 ---- /* Look for a user-defined conversion to lvalue that we can use. */ rval_as_conversion ! = build_type_conversion (reftype, expr); if (rval_as_conversion && rval_as_conversion != error_mark_node && real_lvalue_p (rval_as_conversion)) *************** convert_lvalue (totype, expr) *** 609,614 **** --- 585,605 ---- NULL_TREE); return convert_from_reference (expr); } + + /* Really perform an lvalue-to-rvalue conversion, including copying an + argument of class type into a temporary. */ + + tree + force_rvalue (tree expr) + { + if (IS_AGGR_TYPE (TREE_TYPE (expr)) && TREE_CODE (expr) != TARGET_EXPR) + expr = ocp_convert (TREE_TYPE (expr), expr, + CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL); + else + expr = decay_conversion (expr); + + return expr; + } /* C++ conversions, preference to static cast conversions. */ *************** ocp_convert (type, expr, convtype, flags *** 697,703 **** if (IS_AGGR_TYPE (intype)) { tree rval; ! rval = build_type_conversion (type, e, 1); if (rval) return rval; if (flags & LOOKUP_COMPLAIN) --- 688,694 ---- if (IS_AGGR_TYPE (intype)) { tree rval; ! rval = build_type_conversion (type, e); if (rval) return rval; if (flags & LOOKUP_COMPLAIN) *************** ocp_convert (type, expr, convtype, flags *** 733,739 **** if (IS_AGGR_TYPE (TREE_TYPE (e))) { tree rval; ! rval = build_type_conversion (type, e, 1); if (rval) return rval; else --- 724,730 ---- if (IS_AGGR_TYPE (TREE_TYPE (e))) { tree rval; ! rval = build_type_conversion (type, e); if (rval) return rval; else *************** ocp_convert (type, expr, convtype, flags *** 776,797 **** the target with the temp (see [dcl.init]). */ ctor = build_user_type_conversion (type, ctor, flags); else ! ctor = build_method_call (NULL_TREE, ! complete_ctor_identifier, ! build_tree_list (NULL_TREE, ctor), ! TYPE_BINFO (type), flags); if (ctor) return build_cplus_new (type, ctor); } - /* If TYPE or TREE_TYPE (E) is not on the permanent_obstack, - then it won't be hashed and hence compare as not equal, - even when it is. */ - if (code == ARRAY_TYPE - && TREE_TYPE (TREE_TYPE (e)) == TREE_TYPE (type) - && index_type_equal (TYPE_DOMAIN (TREE_TYPE (e)), TYPE_DOMAIN (type))) - return e; - if (flags & LOOKUP_COMPLAIN) error ("conversion from `%T' to non-scalar type `%T' requested", TREE_TYPE (expr), type); --- 767,780 ---- the target with the temp (see [dcl.init]). */ ctor = build_user_type_conversion (type, ctor, flags); else ! ctor = build_special_member_call (NULL_TREE, ! complete_ctor_identifier, ! build_tree_list (NULL_TREE, ctor), ! TYPE_BINFO (type), flags); if (ctor) return build_cplus_new (type, ctor); } if (flags & LOOKUP_COMPLAIN) error ("conversion from `%T' to non-scalar type `%T' requested", TREE_TYPE (expr), type); *************** convert_to_void (expr, implicit) *** 864,870 **** case NON_LVALUE_EXPR: case NOP_EXPR: ! /* These have already decayed to rvalue. */ break; case CALL_EXPR: /* we have a special meaning for volatile void fn() */ --- 847,853 ---- case NON_LVALUE_EXPR: case NOP_EXPR: ! /* These have already decayed to rvalue. */ break; case CALL_EXPR: /* we have a special meaning for volatile void fn() */ *************** convert_force (type, expr, convtype) *** 1021,1046 **** allowed (references private members, etc). If no conversion exists, NULL_TREE is returned. - If (FOR_SURE & 1) is non-zero, then we allow this type conversion - to take place immediately. Otherwise, we build a SAVE_EXPR - which can be evaluated if the results are ever needed. - - Changes to this functions should be mirrored in user_harshness. - FIXME: Ambiguity checking is wrong. Should choose one by the implicit object parameter, or by the second standard conversion sequence if that doesn't do it. This will probably wait for an overloading rewrite. (jason 8/9/95) */ tree ! build_type_conversion (xtype, expr, for_sure) tree xtype, expr; - int for_sure; { /* C++: check to see if we can convert this aggregate type into the required type. */ ! return build_user_type_conversion ! (xtype, expr, for_sure ? LOOKUP_NORMAL : 0); } /* Convert the given EXPR to one of a group of types suitable for use in an --- 1004,1021 ---- allowed (references private members, etc). If no conversion exists, NULL_TREE is returned. FIXME: Ambiguity checking is wrong. Should choose one by the implicit object parameter, or by the second standard conversion sequence if that doesn't do it. This will probably wait for an overloading rewrite. (jason 8/9/95) */ tree ! build_type_conversion (xtype, expr) tree xtype, expr; { /* C++: check to see if we can convert this aggregate type into the required type. */ ! return build_user_type_conversion (xtype, expr, LOOKUP_NORMAL); } /* Convert the given EXPR to one of a group of types suitable for use in an *************** type_promotes_to (type) *** 1186,1195 **** { int precision = MAX (TYPE_PRECISION (type), TYPE_PRECISION (integer_type_node)); ! tree totype = type_for_size (precision, 0); if (TREE_UNSIGNED (type) && ! int_fits_type_p (TYPE_MAX_VALUE (type), totype)) ! type = type_for_size (precision, 1); else type = totype; } --- 1161,1170 ---- { int precision = MAX (TYPE_PRECISION (type), TYPE_PRECISION (integer_type_node)); ! tree totype = c_common_type_for_size (precision, 0); if (TREE_UNSIGNED (type) && ! int_fits_type_p (TYPE_MAX_VALUE (type), totype)) ! type = c_common_type_for_size (precision, 1); else type = totype; } diff -Nrc3pad gcc-3.2.3/gcc/cp/decl2.c gcc-3.3/gcc/cp/decl2.c *** gcc-3.2.3/gcc/cp/decl2.c 2003-04-15 16:26:44.000000000 +0000 --- gcc-3.3/gcc/cp/decl2.c 2003-05-01 15:47:02.000000000 +0000 *************** *** 1,6 **** /* Process declarations and variables for C compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, ! 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. --- 1,6 ---- /* Process declarations and variables for C compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, ! 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. *************** Boston, MA 02111-1307, USA. */ *** 44,69 **** #include "timevar.h" #include "cpplib.h" #include "target.h" extern cpp_reader *parse_in; /* This structure contains information about the initializations and/or destructions required for a particular priority level. */ typedef struct priority_info_s { ! /* Non-zero if there have been any initializations at this priority throughout the translation unit. */ int initializations_p; ! /* Non-zero if there have been any destructions at this priority throughout the translation unit. */ int destructions_p; } *priority_info; static void mark_vtable_entries PARAMS ((tree)); static void grok_function_init PARAMS ((tree, tree)); ! static int finish_vtable_vardecl PARAMS ((tree *, void *)); ! static int prune_vtable_vardecl PARAMS ((tree *, void *)); ! static int is_namespace_ancestor PARAMS ((tree, tree)); static void add_using_namespace PARAMS ((tree, tree, int)); ! static tree ambiguous_decl PARAMS ((tree, tree, tree,int)); static tree build_anon_union_vars PARAMS ((tree, tree*, int, int)); static int acceptable_java_type PARAMS ((tree)); static void output_vtable_inherit PARAMS ((tree)); --- 44,69 ---- #include "timevar.h" #include "cpplib.h" #include "target.h" + #include "c-common.h" + #include "timevar.h" extern cpp_reader *parse_in; /* This structure contains information about the initializations and/or destructions required for a particular priority level. */ typedef struct priority_info_s { ! /* Nonzero if there have been any initializations at this priority throughout the translation unit. */ int initializations_p; ! /* Nonzero if there have been any destructions at this priority throughout the translation unit. */ int destructions_p; } *priority_info; static void mark_vtable_entries PARAMS ((tree)); static void grok_function_init PARAMS ((tree, tree)); ! static int maybe_emit_vtables (tree); static void add_using_namespace PARAMS ((tree, tree, int)); ! static cxx_binding *ambiguous_decl (tree, cxx_binding *, cxx_binding *,int); static tree build_anon_union_vars PARAMS ((tree, tree*, int, int)); static int acceptable_java_type PARAMS ((tree)); static void output_vtable_inherit PARAMS ((tree)); *************** static void finish_static_initialization *** 84,106 **** static void generate_ctor_or_dtor_function PARAMS ((int, int)); static int generate_ctor_and_dtor_functions_for_priority PARAMS ((splay_tree_node, void *)); ! static tree prune_vars_needing_no_initialization PARAMS ((tree)); static void write_out_vars PARAMS ((tree)); static void import_export_class PARAMS ((tree)); - static tree key_method PARAMS ((tree)); - static int compare_options PARAMS ((const PTR, const PTR)); static tree get_guard_bits PARAMS ((tree)); /* A list of static class variables. This is needed, because a static class variable can be declared inside the class without an initializer, and then initialized, statically, outside the class. */ ! static varray_type pending_statics; #define pending_statics_used \ (pending_statics ? pending_statics->elements_used : 0) /* A list of functions which were declared inline, but which we may need to emit outline anyway. */ ! static varray_type deferred_fns; #define deferred_fns_used \ (deferred_fns ? deferred_fns->elements_used : 0) --- 84,104 ---- static void generate_ctor_or_dtor_function PARAMS ((int, int)); static int generate_ctor_and_dtor_functions_for_priority PARAMS ((splay_tree_node, void *)); ! static tree prune_vars_needing_no_initialization PARAMS ((tree *)); static void write_out_vars PARAMS ((tree)); static void import_export_class PARAMS ((tree)); static tree get_guard_bits PARAMS ((tree)); /* A list of static class variables. This is needed, because a static class variable can be declared inside the class without an initializer, and then initialized, statically, outside the class. */ ! static GTY(()) varray_type pending_statics; #define pending_statics_used \ (pending_statics ? pending_statics->elements_used : 0) /* A list of functions which were declared inline, but which we may need to emit outline anyway. */ ! static GTY(()) varray_type deferred_fns; #define deferred_fns_used \ (deferred_fns ? deferred_fns->elements_used : 0) *************** int at_eof; *** 117,739 **** tree static_ctors; tree static_dtors; ! /* The :: namespace. */ tree global_namespace; - /* C (and C++) language-specific option variables. */ - - /* Nonzero means don't recognize the keyword `asm'. */ - - int flag_no_asm; - - /* Nonzero means don't recognize any extension keywords. */ - - int flag_no_gnu_keywords; - - /* Nonzero means do some things the same way PCC does. Only provided so - the compiler will link. */ - - int flag_traditional; - - /* Nonzero means to treat bitfields as unsigned unless they say `signed'. */ - - int flag_signed_bitfields = 1; - - /* Nonzero means enable obscure standard features and disable GNU - extensions that might cause standard-compliant code to be - miscompiled. */ - - int flag_ansi; - - /* Nonzero means do emit exported implementations of functions even if - they can be inlined. */ - - int flag_implement_inlines = 1; - - /* Nonzero means do emit exported implementations of templates, instead of - multiple static copies in each file that needs a definition. */ - - int flag_external_templates; - - /* Nonzero means that the decision to emit or not emit the implementation of a - template depends on where the template is instantiated, rather than where - it is defined. */ - - int flag_alt_external_templates; - - /* Nonzero means that implicit instantiations will be emitted if needed. */ - - int flag_implicit_templates = 1; - - /* Nonzero means that implicit instantiations of inline templates will be - emitted if needed, even if instantiations of non-inline templates - aren't. */ - - int flag_implicit_inline_templates = 1; - - /* Nonzero means warn about things that will change when compiling - with an ABI-compliant compiler. */ - - int warn_abi = 0; - - /* Nonzero means warn about implicit declarations. */ - - int warn_implicit = 1; - - /* Nonzero means warn about usage of long long when `-pedantic'. */ - - int warn_long_long = 1; - - /* Nonzero means warn when all ctors or dtors are private, and the class - has no friends. */ - - int warn_ctor_dtor_privacy = 1; - - /* Nonzero means generate separate instantiation control files and juggle - them at link time. */ - - int flag_use_repository; - - /* Nonzero if we want to issue diagnostics that the standard says are not - required. */ - - int flag_optional_diags = 1; - - /* Nonzero means give string constants the type `const char *', as mandated - by the standard. */ - - int flag_const_strings = 1; - - /* Nonzero means warn about deprecated conversion from string constant to - `char *'. */ - - int warn_write_strings; - - /* Nonzero means warn about pointer casts that can drop a type qualifier - from the pointer target type. */ - - int warn_cast_qual; - - /* Nonzero means warn about sizeof(function) or addition/subtraction - of function pointers. */ - - int warn_pointer_arith = 1; - - /* Nonzero means warn for any function def without prototype decl. */ - - int warn_missing_prototypes; - - /* Nonzero means warn about multiple (redundant) decls for the same single - variable or function. */ - - int warn_redundant_decls; - - /* Warn if initializer is not completely bracketed. */ - - int warn_missing_braces; - - /* Warn about comparison of signed and unsigned values. */ - - int warn_sign_compare; - - /* Warn about testing equality of floating point numbers. */ - - int warn_float_equal = 0; - - /* Warn about functions which might be candidates for format attributes. */ - - int warn_missing_format_attribute; - - /* Warn about a subscript that has type char. */ - - int warn_char_subscripts; - - /* Warn if a type conversion is done that might have confusing results. */ - - int warn_conversion; - - /* Warn if adding () is suggested. */ - - int warn_parentheses; - - /* Non-zero means warn in function declared in derived class has the - same name as a virtual in the base class, but fails to match the - type signature of any virtual function in the base class. */ - - int warn_overloaded_virtual; - - /* Non-zero means warn when declaring a class that has a non virtual - destructor, when it really ought to have a virtual one. */ - - int warn_nonvdtor; - - /* Non-zero means warn when the compiler will reorder code. */ - - int warn_reorder; - - /* Non-zero means warn when synthesis behavior differs from Cfront's. */ - - int warn_synth; - - /* Non-zero means warn when we convert a pointer to member function - into a pointer to (void or function). */ - - int warn_pmf2ptr = 1; - - /* Nonzero means warn about violation of some Effective C++ style rules. */ - - int warn_ecpp; - - /* Nonzero means warn where overload resolution chooses a promotion from - unsigned to signed over a conversion to an unsigned of the same size. */ - - int warn_sign_promo; - - /* Nonzero means warn when an old-style cast is used. */ - - int warn_old_style_cast; - - /* Warn about #pragma directives that are not recognised. */ - - int warn_unknown_pragmas; /* Tri state variable. */ - - /* Nonzero means warn about use of multicharacter literals. */ - - int warn_multichar = 1; - - /* Nonzero means warn when non-templatized friend functions are - declared within a template */ - - int warn_nontemplate_friend = 1; - - /* Nonzero means complain about deprecated features. */ - - int warn_deprecated = 1; - - /* Nonzero means `$' can be in an identifier. */ - - #ifndef DOLLARS_IN_IDENTIFIERS - #define DOLLARS_IN_IDENTIFIERS 1 - #endif - int dollars_in_ident = DOLLARS_IN_IDENTIFIERS; - - /* Nonzero means allow Microsoft extensions without a pedwarn. */ - - int flag_ms_extensions; - - /* C++ specific flags. */ - - /* Nonzero means we should attempt to elide constructors when possible. */ - - int flag_elide_constructors = 1; - - /* Nonzero means that member functions defined in class scope are - inline by default. */ - - int flag_default_inline = 1; - - /* Controls whether compiler generates 'type descriptor' that give - run-time type information. */ - - int flag_rtti = 1; - - /* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes) - objects. */ - - int flag_huge_objects; - - /* Nonzero if we want to conserve space in the .o files. We do this - by putting uninitialized data and runtime initialized data into - .common instead of .data at the expense of not flagging multiple - definitions. */ - - int flag_conserve_space; - - /* Nonzero if we want to obey access control semantics. */ - - int flag_access_control = 1; - - /* Nonzero if we want to understand the operator names, i.e. 'bitand'. */ - - int flag_operator_names = 1; - - /* Nonzero if we want to check the return value of new and avoid calling - constructors if it is a null pointer. */ - - int flag_check_new; - - /* Nonzero if we want the new ISO rules for pushing a new scope for `for' - initialization variables. - 0: Old rules, set by -fno-for-scope. - 2: New ISO rules, set by -ffor-scope. - 1: Try to implement new ISO rules, but with backup compatibility - (and warnings). This is the default, for now. */ - - int flag_new_for_scope = 1; - - /* Nonzero if we want to emit defined symbols with common-like linkage as - weak symbols where possible, in order to conform to C++ semantics. - Otherwise, emit them as local symbols. */ - - int flag_weak = 1; - - /* Nonzero to use __cxa_atexit, rather than atexit, to register - destructors for local statics and global objects. */ - - int flag_use_cxa_atexit = DEFAULT_USE_CXA_ATEXIT; - - /* Maximum template instantiation depth. This limit is rather - arbitrary, but it exists to limit the time it takes to notice - infinite template instantiations. */ - - int max_tinst_depth = 500; - - /* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc. */ - - int flag_vtable_gc; - - /* Nonzero means make the default pedwarns warnings instead of errors. - The value of this flag is ignored if -pedantic is specified. */ - - int flag_permissive; - - /* Nonzero means to implement standard semantics for exception - specifications, calling unexpected if an exception is thrown that - doesn't match the specification. Zero means to treat them as - assertions and optimize accordingly, but not check them. */ - - int flag_enforce_eh_specs = 1; - - /* Table of language-dependent -f options. - STRING is the option name. VARIABLE is the address of the variable. - ON_VALUE is the value to store in VARIABLE - if `-fSTRING' is seen as an option. - (If `-fno-STRING' is seen as an option, the opposite value is stored.) */ - - static const struct { const char *const string; int *const variable; const int on_value;} - lang_f_options[] = - { - /* C/C++ options. */ - {"signed-char", &flag_signed_char, 1}, - {"unsigned-char", &flag_signed_char, 0}, - {"signed-bitfields", &flag_signed_bitfields, 1}, - {"unsigned-bitfields", &flag_signed_bitfields, 0}, - {"short-enums", &flag_short_enums, 1}, - {"short-double", &flag_short_double, 1}, - {"short-wchar", &flag_short_wchar, 1}, - {"asm", &flag_no_asm, 0}, - {"builtin", &flag_no_builtin, 0}, - - /* C++-only options. */ - {"access-control", &flag_access_control, 1}, - {"check-new", &flag_check_new, 1}, - {"conserve-space", &flag_conserve_space, 1}, - {"const-strings", &flag_const_strings, 1}, - {"default-inline", &flag_default_inline, 1}, - {"dollars-in-identifiers", &dollars_in_ident, 1}, - {"elide-constructors", &flag_elide_constructors, 1}, - {"enforce-eh-specs", &flag_enforce_eh_specs, 1}, - {"external-templates", &flag_external_templates, 1}, - {"for-scope", &flag_new_for_scope, 2}, - {"gnu-keywords", &flag_no_gnu_keywords, 0}, - {"handle-exceptions", &flag_exceptions, 1}, - {"implement-inlines", &flag_implement_inlines, 1}, - {"implicit-inline-templates", &flag_implicit_inline_templates, 1}, - {"implicit-templates", &flag_implicit_templates, 1}, - {"ms-extensions", &flag_ms_extensions, 1}, - {"nonansi-builtins", &flag_no_nonansi_builtin, 0}, - {"operator-names", &flag_operator_names, 1}, - {"optional-diags", &flag_optional_diags, 1}, - {"permissive", &flag_permissive, 1}, - {"repo", &flag_use_repository, 1}, - {"rtti", &flag_rtti, 1}, - {"stats", &flag_detailed_statistics, 1}, - {"vtable-gc", &flag_vtable_gc, 1}, - {"use-cxa-atexit", &flag_use_cxa_atexit, 1}, - {"weak", &flag_weak, 1} - }; - - /* The list of `-f' options that we no longer support. The `-f' - prefix is not given in this table. The `-fno-' variants are not - listed here. This table must be kept in alphabetical order. */ - static const char * const unsupported_options[] = { - "all-virtual", - "cond-mismatch", - "enum-int-equiv", - "guiding-decls", - "honor-std", - "huge-objects", - "labels-ok", - "new-abi", - "nonnull-objects", - "squangle", - "strict-prototype", - "this-is-variable", - "vtable-thunks", - "xref" - }; - - /* Compare two option strings, pointed two by P1 and P2, for use with - bsearch. */ - - static int - compare_options (p1, p2) - const PTR p1; - const PTR p2; - { - return strcmp (*((const char *const *) p1), *((const char *const *) p2)); - } - - /* Decode the string P as a language-specific option. - Return the number of strings consumed for a valid option. - Otherwise return 0. Should not complain if it does not - recognise the option. */ - - int - cxx_decode_option (argc, argv) - int argc; - char **argv; - { - int strings_processed; - const char *p = argv[0]; - - strings_processed = cpp_handle_option (parse_in, argc, argv, 0); - - if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional")) - /* ignore */; - else if (p[0] == '-' && p[1] == 'f') - { - /* Some kind of -f option. - P's value is the option sans `-f'. - Search for it in the table of options. */ - const char *option_value = NULL; - const char *positive_option; - size_t j; - - p += 2; - /* Try special -f options. */ - - /* See if this is one of the options no longer supported. We - used to support these options, so we continue to accept them, - with a warning. */ - if (strncmp (p, "no-", strlen ("no-")) == 0) - positive_option = p + strlen ("no-"); - else - positive_option = p; - - /* If the option is present, issue a warning. Indicate to our - caller that the option was processed successfully. */ - if (bsearch (&positive_option, - unsupported_options, - (sizeof (unsupported_options) - / sizeof (unsupported_options[0])), - sizeof (unsupported_options[0]), - compare_options)) - { - warning ("-f%s is no longer supported", p); - return 1; - } - - if (!strcmp (p, "handle-exceptions") - || !strcmp (p, "no-handle-exceptions")) - warning ("-fhandle-exceptions has been renamed to -fexceptions (and is now on by default)"); - else if (! strcmp (p, "alt-external-templates")) - { - flag_external_templates = 1; - flag_alt_external_templates = 1; - cp_deprecated ("-falt-external-templates"); - } - else if (! strcmp (p, "no-alt-external-templates")) - flag_alt_external_templates = 0; - else if (!strcmp (p, "repo")) - { - flag_use_repository = 1; - flag_implicit_templates = 0; - } - else if (!strcmp (p, "external-templates")) - { - flag_external_templates = 1; - cp_deprecated ("-fexternal-templates"); - } - else if ((option_value - = skip_leading_substring (p, "template-depth-"))) - max_tinst_depth - = read_integral_parameter (option_value, p - 2, max_tinst_depth); - else if ((option_value - = skip_leading_substring (p, "name-mangling-version-"))) - { - warning ("-fname-mangling-version is no longer supported"); - return 1; - } - else if (dump_switch_p (p)) - ; - else - { - int found = 0; - - for (j = 0; - !found && j < (sizeof (lang_f_options) - / sizeof (lang_f_options[0])); - j++) - { - if (!strcmp (p, lang_f_options[j].string)) - { - *lang_f_options[j].variable = lang_f_options[j].on_value; - /* A goto here would be cleaner, - but breaks the VAX pcc. */ - found = 1; - } - else if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' - && ! strcmp (p+3, lang_f_options[j].string)) - { - *lang_f_options[j].variable = ! lang_f_options[j].on_value; - found = 1; - } - } - - return found; - } - } - else if (p[0] == '-' && p[1] == 'W') - { - int setting = 1; - - /* The -W options control the warning behavior of the compiler. */ - p += 2; - - if (p[0] == 'n' && p[1] == 'o' && p[2] == '-') - setting = 0, p += 3; - - if (!strcmp (p, "abi")) - warn_abi = setting; - else if (!strcmp (p, "implicit")) - warn_implicit = setting; - else if (!strcmp (p, "long-long")) - warn_long_long = setting; - else if (!strcmp (p, "return-type")) - warn_return_type = setting; - else if (!strcmp (p, "ctor-dtor-privacy")) - warn_ctor_dtor_privacy = setting; - else if (!strcmp (p, "write-strings")) - warn_write_strings = setting; - else if (!strcmp (p, "cast-qual")) - warn_cast_qual = setting; - else if (!strcmp (p, "char-subscripts")) - warn_char_subscripts = setting; - else if (!strcmp (p, "pointer-arith")) - warn_pointer_arith = setting; - else if (!strcmp (p, "missing-prototypes")) - warn_missing_prototypes = setting; - else if (!strcmp (p, "strict-prototypes")) - { - if (setting == 0) - warning ("-Wno-strict-prototypes is not supported in C++"); - } - else if (!strcmp (p, "redundant-decls")) - warn_redundant_decls = setting; - else if (!strcmp (p, "missing-braces")) - warn_missing_braces = setting; - else if (!strcmp (p, "sign-compare")) - warn_sign_compare = setting; - else if (!strcmp (p, "float-equal")) - warn_float_equal = setting; - else if (!strcmp (p, "format")) - set_Wformat (setting); - else if (!strcmp (p, "format=2")) - set_Wformat (2); - else if (!strcmp (p, "format-y2k")) - warn_format_y2k = setting; - else if (!strcmp (p, "format-extra-args")) - warn_format_extra_args = setting; - else if (!strcmp (p, "format-nonliteral")) - warn_format_nonliteral = setting; - else if (!strcmp (p, "format-security")) - warn_format_security = setting; - else if (!strcmp (p, "missing-format-attribute")) - warn_missing_format_attribute = setting; - else if (!strcmp (p, "conversion")) - warn_conversion = setting; - else if (!strcmp (p, "parentheses")) - warn_parentheses = setting; - else if (!strcmp (p, "non-virtual-dtor")) - warn_nonvdtor = setting; - else if (!strcmp (p, "reorder")) - warn_reorder = setting; - else if (!strcmp (p, "synth")) - warn_synth = setting; - else if (!strcmp (p, "pmf-conversions")) - warn_pmf2ptr = setting; - else if (!strcmp (p, "effc++")) - warn_ecpp = setting; - else if (!strcmp (p, "sign-promo")) - warn_sign_promo = setting; - else if (!strcmp (p, "old-style-cast")) - warn_old_style_cast = setting; - else if (!strcmp (p, "overloaded-virtual")) - warn_overloaded_virtual = setting; - else if (!strcmp (p, "multichar")) - warn_multichar = setting; - else if (!strcmp (p, "unknown-pragmas")) - /* Set to greater than 1, so that even unknown pragmas in - system headers will be warned about. */ - warn_unknown_pragmas = setting * 2; - else if (!strcmp (p, "non-template-friend")) - warn_nontemplate_friend = setting; - else if (!strcmp (p, "deprecated")) - warn_deprecated = setting; - else if (!strcmp (p, "comment")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "comments")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "trigraphs")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "import")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "all")) - { - warn_return_type = setting; - set_Wunused (setting); - warn_implicit = setting; - warn_switch = setting; - set_Wformat (setting); - warn_parentheses = setting; - warn_missing_braces = setting; - warn_sign_compare = setting; - warn_multichar = setting; - /* We save the value of warn_uninitialized, since if they put - -Wuninitialized on the command line, we need to generate a - warning about not using it without also specifying -O. */ - if (warn_uninitialized != 1) - warn_uninitialized = (setting ? 2 : 0); - /* Only warn about unknown pragmas that are not in system - headers. */ - warn_unknown_pragmas = 1; - - /* C++-specific warnings. */ - warn_ctor_dtor_privacy = setting; - warn_nonvdtor = setting; - warn_reorder = setting; - warn_nontemplate_friend = setting; - } - else return strings_processed; - } - else if (!strcmp (p, "-ansi")) - flag_no_nonansi_builtin = 1, flag_ansi = 1, - flag_noniso_default_format_attributes = 0, flag_no_gnu_keywords = 1; - #ifdef SPEW_DEBUG - /* Undocumented, only ever used when you're invoking cc1plus by hand, since - it's probably safe to assume no sane person would ever want to use this - under normal circumstances. */ - else if (!strcmp (p, "-spew-debug")) - spew_debug = 1; - #endif - else - return strings_processed; - - return 1; - } - /* Incorporate `const' and `volatile' qualifiers for member functions. FUNCTION is a TYPE_DECL or a FUNCTION_DECL. QUALS is a list of qualifiers. Returns any explicit --- 115,124 ---- tree static_ctors; tree static_dtors; ! /* The :: namespace. */ tree global_namespace; /* Incorporate `const' and `volatile' qualifiers for member functions. FUNCTION is a TYPE_DECL or a FUNCTION_DECL. QUALS is a list of qualifiers. Returns any explicit *************** grok_x_components (specs) *** 836,841 **** --- 221,239 ---- finish_member_declaration (build_decl (FIELD_DECL, NULL_TREE, t)); } + /* Build a PARM_DECL with NAME and TYPE, and set DECL_ARG_TYPE + appropriately. */ + + tree + cp_build_parm_decl (name, type) + tree name; + tree type; + { + tree parm = build_decl (PARM_DECL, name, type); + DECL_ARG_TYPE (parm) = type_passed_as (type); + return parm; + } + /* Returns a PARM_DECL for a parameter of the indicated TYPE, with the indicated NAME. */ *************** build_artificial_parm (name, type) *** 844,857 **** tree name; tree type; { ! tree parm; ! ! parm = build_decl (PARM_DECL, name, type); DECL_ARTIFICIAL (parm) = 1; /* All our artificial parms are implicitly `const'; they cannot be assigned to. */ TREE_READONLY (parm) = 1; - DECL_ARG_TYPE (parm) = type; return parm; } --- 242,252 ---- tree name; tree type; { ! tree parm = cp_build_parm_decl (name, type); DECL_ARTIFICIAL (parm) = 1; /* All our artificial parms are implicitly `const'; they cannot be assigned to. */ TREE_READONLY (parm) = 1; return parm; } *************** delete_sanity (exp, size, doing_vec, use *** 1139,1145 **** return error_mark_node; } ! /* Deleting ptr to void is undefined behaviour [expr.delete/3]. */ if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE) { warning ("deleting `%T' is undefined", type); --- 534,540 ---- return error_mark_node; } ! /* Deleting ptr to void is undefined behavior [expr.delete/3]. */ if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE) { warning ("deleting `%T' is undefined", type); *************** check_member_template (tmpl) *** 1183,1189 **** if (current_function_decl) /* 14.5.2.2 [temp.mem] ! A local class shall not have member templates. */ error ("invalid declaration of member template `%#D' in local class", decl); --- 578,584 ---- if (current_function_decl) /* 14.5.2.2 [temp.mem] ! A local class shall not have member templates. */ error ("invalid declaration of member template `%#D' in local class", decl); *************** check_member_template (tmpl) *** 1206,1212 **** error ("template declaration of `%#D'", decl); } ! /* Return true iff TYPE is a valid Java parameter or return type. */ static int acceptable_java_type (type) --- 601,607 ---- error ("template declaration of `%#D'", decl); } ! /* Return true iff TYPE is a valid Java parameter or return type. */ static int acceptable_java_type (type) *************** tree *** 1278,1288 **** check_classfn (ctype, function) tree ctype, function; { ! tree fn_name = DECL_NAME (function); ! tree fndecl, fndecls; ! tree method_vec = CLASSTYPE_METHOD_VEC (complete_type (ctype)); ! tree *methods = 0; ! tree *end = 0; if (DECL_USE_TEMPLATE (function) && !(TREE_CODE (function) == TEMPLATE_DECL --- 673,680 ---- check_classfn (ctype, function) tree ctype, function; { ! int ix; ! int is_template; if (DECL_USE_TEMPLATE (function) && !(TREE_CODE (function) == TEMPLATE_DECL *************** check_classfn (ctype, function) *** 1299,1379 **** reason we should, either. We let our callers know we didn't find the method, but we don't complain. */ return NULL_TREE; ! ! if (method_vec != 0) { ! methods = &TREE_VEC_ELT (method_vec, 0); ! end = TREE_VEC_END (method_vec); ! /* First suss out ctors and dtors. */ ! if (*methods && fn_name == DECL_NAME (OVL_CURRENT (*methods)) ! && DECL_CONSTRUCTOR_P (function)) ! goto got_it; ! if (*++methods && fn_name == DECL_NAME (OVL_CURRENT (*methods)) ! && DECL_DESTRUCTOR_P (function)) ! goto got_it; ! while (++methods != end && *methods) { ! fndecl = *methods; ! if (fn_name == DECL_NAME (OVL_CURRENT (*methods))) { ! got_it: ! for (fndecls = *methods; fndecls != NULL_TREE; ! fndecls = OVL_NEXT (fndecls)) { ! fndecl = OVL_CURRENT (fndecls); ! ! /* We cannot simply call decls_match because this ! doesn't work for static member functions that are ! pretending to be methods, and because the name ! may have been changed by asm("new_name"). */ ! 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 (same_type_p (TREE_TYPE (TREE_TYPE (function)), ! TREE_TYPE (TREE_TYPE (fndecl))) ! && compparms (p1, p2) ! && (DECL_TEMPLATE_SPECIALIZATION (function) ! == DECL_TEMPLATE_SPECIALIZATION (fndecl)) ! && (!DECL_TEMPLATE_SPECIALIZATION (function) ! || (DECL_TI_TEMPLATE (function) ! == DECL_TI_TEMPLATE (fndecl)))) ! return fndecl; } } ! break; /* loser */ } } } ! ! if (methods != end && *methods) ! { ! tree fndecl = *methods; ! error ("prototype for `%#D' does not match any in class `%T'", ! function, ctype); ! cp_error_at ("candidate%s: %+#D", OVL_NEXT (fndecl) ? "s are" : " is", ! OVL_CURRENT (fndecl)); ! while (fndecl = OVL_NEXT (fndecl), fndecl) ! cp_error_at (" %#D", OVL_CURRENT(fndecl)); ! } else ! { ! methods = 0; ! if (!COMPLETE_TYPE_P (ctype)) ! incomplete_type_error (function, ctype); ! else ! error ("no `%#D' member function declared in class `%T'", ! function, ctype); ! } /* If we did not find the method in the class, add it to avoid spurious errors (unless the CTYPE is not yet defined, in which --- 691,789 ---- reason we should, either. We let our callers know we didn't find the method, but we don't complain. */ return NULL_TREE; ! ! /* OK, is this a definition of a member template? */ ! is_template = (TREE_CODE (function) == TEMPLATE_DECL ! || (processing_template_decl - template_class_depth (ctype))); ! ! ix = lookup_fnfields_1 (complete_type (ctype), ! DECL_CONSTRUCTOR_P (function) ? ctor_identifier : ! DECL_DESTRUCTOR_P (function) ? dtor_identifier : ! DECL_NAME (function)); ! ! if (ix >= 0) { ! tree methods = CLASSTYPE_METHOD_VEC (ctype); ! tree fndecls, fndecl = 0; ! bool is_conv_op; ! const char *format = NULL; ! ! for (fndecls = TREE_VEC_ELT (methods, ix); ! fndecls; fndecls = OVL_NEXT (fndecls)) ! { ! tree p1, p2; ! ! fndecl = OVL_CURRENT (fndecls); ! p1 = TYPE_ARG_TYPES (TREE_TYPE (function)); ! p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); ! /* We cannot simply call decls_match because this doesn't ! work for static member functions that are pretending to ! be methods, and because the name may have been changed by ! asm("new_name"). */ ! ! /* 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); ! /* A member template definition only matches a member template ! declaration. */ ! if (is_template != (TREE_CODE (fndecl) == TEMPLATE_DECL)) ! continue; ! ! if (same_type_p (TREE_TYPE (TREE_TYPE (function)), ! TREE_TYPE (TREE_TYPE (fndecl))) ! && compparms (p1, p2) ! && (DECL_TEMPLATE_SPECIALIZATION (function) ! == DECL_TEMPLATE_SPECIALIZATION (fndecl)) ! && (!DECL_TEMPLATE_SPECIALIZATION (function) ! || (DECL_TI_TEMPLATE (function) ! == DECL_TI_TEMPLATE (fndecl)))) ! return fndecl; ! } ! error ("prototype for `%#D' does not match any in class `%T'", ! function, ctype); ! is_conv_op = DECL_CONV_FN_P (fndecl); ! ! if (is_conv_op) ! ix = CLASSTYPE_FIRST_CONVERSION_SLOT; ! fndecls = TREE_VEC_ELT (methods, ix); ! while (fndecls) { ! fndecl = OVL_CURRENT (fndecls); ! fndecls = OVL_NEXT (fndecls); ! ! if (!fndecls && is_conv_op) { ! if (TREE_VEC_LENGTH (methods) > ix) { ! ix++; ! fndecls = TREE_VEC_ELT (methods, ix); ! if (!DECL_CONV_FN_P (OVL_CURRENT (fndecls))) { ! fndecls = NULL_TREE; ! is_conv_op = false; } } ! else ! is_conv_op = false; } + if (format) + format = " %#D"; + else if (fndecls) + format = "candidates are: %#D"; + else + format = "candidate is: %#D"; + cp_error_at (format, fndecl); } } ! else if (!COMPLETE_TYPE_P (ctype)) ! cxx_incomplete_type_error (function, ctype); else ! error ("no `%#D' member function declared in class `%T'", ! function, ctype); /* If we did not find the method in the class, add it to avoid spurious errors (unless the CTYPE is not yet defined, in which *************** grokbitfield (declarator, declspecs, wid *** 1722,1732 **** return value; } tree ! grokoptypename (declspecs, declarator) tree declspecs, declarator; { tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL); return mangle_conv_op_name_for_type (t); } --- 1132,1160 ---- return value; } + /* Convert a conversion operator name to an identifier. SCOPE is the + scope of the conversion operator, if explicit. */ + tree ! grokoptypename (declspecs, declarator, scope) tree declspecs, declarator; + tree scope; { tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL); + + /* Resolve any TYPENAME_TYPEs that refer to SCOPE, before mangling + the name, so that we mangle the right thing. */ + if (scope && current_template_parms + && uses_template_parms (t) + && uses_template_parms (scope)) + { + tree args = current_template_args (); + + push_scope (scope); + t = tsubst (t, args, tf_error | tf_warning, NULL_TREE); + pop_scope (scope); + } + return mangle_conv_op_name_for_type (t); } *************** constructor_name (thing) *** 1845,1850 **** --- 1273,1288 ---- return thing; return t; } + + /* Returns TRUE if NAME is the name for the constructor for TYPE. */ + + bool + constructor_name_p (tree name, tree type) + { + return (name == constructor_name (type) + || name == constructor_name_full (type)); + } + /* Defer the compilation of the FN until the end of compilation. */ *************** finish_anon_union (anon_union_decl) *** 1971,1977 **** int static_p = TREE_STATIC (anon_union_decl); int external_p = DECL_EXTERNAL (anon_union_decl); ! /* The VAR_DECL's context is the same as the TYPE's context. */ DECL_CONTEXT (anon_union_decl) = DECL_CONTEXT (TYPE_NAME (type)); if (TYPE_FIELDS (type) == NULL_TREE) --- 1409,1415 ---- int static_p = TREE_STATIC (anon_union_decl); int external_p = DECL_EXTERNAL (anon_union_decl); ! /* The VAR_DECL's context is the same as the TYPE's context. */ DECL_CONTEXT (anon_union_decl) = DECL_CONTEXT (TYPE_NAME (type)); if (TYPE_FIELDS (type) == NULL_TREE) *************** comdat_linkage (decl) *** 2191,2197 **** DECL_COMMON (decl) = 1; DECL_INITIAL (decl) = error_mark_node; } ! else { /* We can't do anything useful; leave vars for explicit instantiation. */ --- 1629,1635 ---- DECL_COMMON (decl) = 1; DECL_INITIAL (decl) = error_mark_node; } ! else if (!DECL_EXPLICIT_INSTANTIATION (decl)) { /* We can't do anything useful; leave vars for explicit instantiation. */ *************** maybe_make_one_only (decl) *** 2217,2223 **** one. However, that's not actually the case in SVR4; a strong definition after a weak one is an error. Also, not making explicit instantiations one_only means that we can end up with two copies of ! some template instantiations. */ if (! flag_weak) return; --- 1655,1661 ---- one. However, that's not actually the case in SVR4; a strong definition after a weak one is an error. Also, not making explicit instantiations one_only means that we can end up with two copies of ! some template instantiations. */ if (! flag_weak) return; *************** maybe_make_one_only (decl) *** 2236,2269 **** } } - /* Returns the virtual function with which the vtable for TYPE is - emitted, or NULL_TREE if that heuristic is not applicable to TYPE. */ - - static tree - key_method (type) - tree type; - { - tree method; - - if (TYPE_FOR_JAVA (type) - || CLASSTYPE_TEMPLATE_INSTANTIATION (type) - || CLASSTYPE_INTERFACE_KNOWN (type)) - return NULL_TREE; - - for (method = TYPE_METHODS (type); method != NULL_TREE; - method = TREE_CHAIN (method)) - if (DECL_VINDEX (method) != NULL_TREE - && ! DECL_DECLARED_INLINE_P (method) - && (! DECL_PURE_VIRTUAL_P (method) - #if 0 - /* This would be nice, but we didn't think of it in time. */ - || DECL_DESTRUCTOR_P (method) - #endif - )) - return method; - - return NULL_TREE; - } /* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL, based on TYPE and other static flags. --- 1674,1679 ---- *************** import_export_vtable (decl, type, final) *** 2297,2303 **** functions in our class, or if we come from a template. */ int found = (CLASSTYPE_TEMPLATE_INSTANTIATION (type) ! || key_method (type)); if (final || ! found) { --- 1707,1713 ---- functions in our class, or if we come from a template. */ int found = (CLASSTYPE_TEMPLATE_INSTANTIATION (type) ! || CLASSTYPE_KEY_METHOD (type) != NULL_TREE); if (final || ! found) { *************** import_export_class (ctype) *** 2357,2363 **** if (import_export == 0 && TYPE_POLYMORPHIC_P (ctype)) { ! tree method = key_method (ctype); if (method) import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1); } --- 1767,1773 ---- if (import_export == 0 && TYPE_POLYMORPHIC_P (ctype)) { ! tree method = CLASSTYPE_KEY_METHOD (ctype); if (method) import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1); } *************** output_vtable_inherit (vars) *** 2401,2428 **** assemble_vtable_inherit (child_rtx, parent_rtx); } static int ! finish_vtable_vardecl (t, data) ! tree *t; ! void *data ATTRIBUTE_UNUSED; { ! tree vars = *t; ! tree ctype = DECL_CONTEXT (vars); import_export_class (ctype); ! import_export_vtable (vars, ctype, 1); ! if (! DECL_EXTERNAL (vars) ! && DECL_NEEDED_P (vars) ! && ! TREE_ASM_WRITTEN (vars)) { - if (TREE_TYPE (vars) == void_type_node) - /* It is a dummy vtable made by get_vtable_decl. Ignore it. */ - return 0; - /* Write it out. */ ! mark_vtable_entries (vars); ! if (TREE_TYPE (DECL_INITIAL (vars)) == 0) ! store_init_value (vars, DECL_INITIAL (vars)); if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG) { --- 1811,1862 ---- assemble_vtable_inherit (child_rtx, parent_rtx); } + /* If necessary, write out the vtables for the dynamic class CTYPE. + Returns nonzero if any vtables were emitted. */ + static int ! maybe_emit_vtables (tree ctype) { ! tree vtbl; ! tree primary_vtbl; ! ! /* If the vtables for this class have already been emitted there is ! nothing more to do. */ ! primary_vtbl = CLASSTYPE_VTABLES (ctype); ! if (TREE_ASM_WRITTEN (primary_vtbl)) ! return 0; ! /* Ignore dummy vtables made by get_vtable_decl. */ ! if (TREE_TYPE (primary_vtbl) == void_type_node) ! return 0; ! import_export_class (ctype); ! import_export_vtable (primary_vtbl, ctype, 1); ! /* See if any of the vtables are needed. */ ! for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl)) ! if (!DECL_EXTERNAL (vtbl) && DECL_NEEDED_P (vtbl)) ! break; ! ! if (!vtbl) ! { ! /* If the references to this class' vtables are optimized away, ! still emit the appropriate debugging information. See ! dfs_debug_mark. */ ! if (DECL_COMDAT (primary_vtbl) ! && CLASSTYPE_DEBUG_REQUESTED (ctype)) ! note_debug_info_needed (ctype); ! return 0; ! } ! ! /* The ABI requires that we emit all of the vtables if we emit any ! of them. */ ! for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl)) { /* Write it out. */ ! import_export_vtable (vtbl, ctype, 1); ! mark_vtable_entries (vtbl); ! if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0) ! store_init_value (vtbl, DECL_INITIAL (vtbl)); if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG) { *************** finish_vtable_vardecl (t, data) *** 2447,2491 **** `S' get written (which would solve the problem) but that would require more intrusive changes to the g++ front end. */ ! DECL_IGNORED_P (vars) = 1; } /* Always make vtables weak. */ if (flag_weak) ! comdat_linkage (vars); ! rest_of_decl_compilation (vars, NULL, 1, 1); if (flag_vtable_gc) ! output_vtable_inherit (vars); /* Because we're only doing syntax-checking, we'll never end up actually marking the variable as written. */ if (flag_syntax_only) ! TREE_ASM_WRITTEN (vars) = 1; ! ! /* Since we're writing out the vtable here, also write the debug ! info. */ ! note_debug_info_needed (ctype); ! ! return 1; } ! /* If the references to this class' vtables were optimized away, still ! emit the appropriate debugging information. See dfs_debug_mark. */ ! if (DECL_COMDAT (vars) ! && CLASSTYPE_DEBUG_REQUESTED (ctype)) ! note_debug_info_needed (ctype); ! ! return 0; ! } - static int - prune_vtable_vardecl (t, data) - tree *t; - void *data ATTRIBUTE_UNUSED; - { - *t = TREE_CHAIN (*t); return 1; } --- 1881,1908 ---- `S' get written (which would solve the problem) but that would require more intrusive changes to the g++ front end. */ ! DECL_IGNORED_P (vtbl) = 1; } /* Always make vtables weak. */ if (flag_weak) ! comdat_linkage (vtbl); ! rest_of_decl_compilation (vtbl, NULL, 1, 1); if (flag_vtable_gc) ! output_vtable_inherit (vtbl); /* Because we're only doing syntax-checking, we'll never end up actually marking the variable as written. */ if (flag_syntax_only) ! TREE_ASM_WRITTEN (vtbl) = 1; } ! /* Since we're writing out the vtable here, also write the debug ! info. */ ! note_debug_info_needed (ctype); return 1; } *************** import_export_decl (decl) *** 2556,2562 **** } /* Here, we only decide whether or not the tinfo node should be ! emitted with the vtable. IS_IN_LIBRARY is non-zero iff the typeinfo for TYPE should be in the runtime library. */ void --- 1973,1979 ---- } /* Here, we only decide whether or not the tinfo node should be ! emitted with the vtable. IS_IN_LIBRARY is nonzero iff the typeinfo for TYPE should be in the runtime library. */ void *************** import_export_tinfo (decl, type, is_in_l *** 2587,2593 **** DECL_COMDAT (decl) = 1; } ! /* Now override some cases. */ if (flag_weak) DECL_COMDAT (decl) = 1; else if (is_in_library) --- 2004,2010 ---- DECL_COMDAT (decl) = 1; } ! /* Now override some cases. */ if (flag_weak) DECL_COMDAT (decl) = 1; else if (is_in_library) *************** import_export_tinfo (decl, type, is_in_l *** 2596,2601 **** --- 2013,2022 ---- DECL_INTERFACE_KNOWN (decl) = 1; } + /* Return an expression that performs the destruction of DECL, which + must be a VAR_DECL whose type has a non-trivial destructor, or is + an array whose (innermost) elements have a non-trivial destructor. */ + tree build_cleanup (decl) tree decl; *************** build_cleanup (decl) *** 2603,2613 **** tree temp; tree type = TREE_TYPE (decl); if (TREE_CODE (type) == ARRAY_TYPE) temp = decl; else { ! mark_addressable (decl); temp = build1 (ADDR_EXPR, build_pointer_type (type), decl); } temp = build_delete (TREE_TYPE (temp), temp, --- 2024,2042 ---- tree temp; tree type = TREE_TYPE (decl); + /* This function should only be called for declarations that really + require cleanups. */ + my_friendly_assert (!TYPE_HAS_TRIVIAL_DESTRUCTOR (type), 20030106); + + /* Treat all objects with destructors as used; the destructor may do + something substantive. */ + mark_used (decl); + if (TREE_CODE (type) == ARRAY_TYPE) temp = decl; else { ! cxx_mark_addressable (decl); temp = build1 (ADDR_EXPR, build_pointer_type (type), decl); } temp = build_delete (TREE_TYPE (temp), temp, *************** get_guard (decl) *** 2637,2643 **** guard_type = long_long_integer_type_node; guard = build_decl (VAR_DECL, sname, guard_type); ! /* The guard should have the same linkage as what it guards. */ TREE_PUBLIC (guard) = TREE_PUBLIC (decl); TREE_STATIC (guard) = TREE_STATIC (decl); DECL_COMMON (guard) = DECL_COMMON (decl); --- 2066,2072 ---- guard_type = long_long_integer_type_node; guard = build_decl (VAR_DECL, sname, guard_type); ! /* The guard should have the same linkage as what it guards. */ TREE_PUBLIC (guard) = TREE_PUBLIC (decl); TREE_STATIC (guard) = TREE_STATIC (decl); DECL_COMMON (guard) = DECL_COMMON (decl); *************** start_objects (method_type, initp) *** 2754,2760 **** DECL_GLOBAL_CTOR_P (current_function_decl) = 1; else DECL_GLOBAL_DTOR_P (current_function_decl) = 1; ! GLOBAL_INIT_PRIORITY (current_function_decl) = initp; body = begin_compound_stmt (/*has_no_scope=*/0); --- 2183,2189 ---- DECL_GLOBAL_CTOR_P (current_function_decl) = 1; else DECL_GLOBAL_DTOR_P (current_function_decl) = 1; ! DECL_LANG_SPECIFIC (current_function_decl)->decl_flags.u2sel = 1; body = begin_compound_stmt (/*has_no_scope=*/0); *************** finish_objects (method_type, initp, body *** 2810,2826 **** #define SSDF_IDENTIFIER "__static_initialization_and_destruction" /* The declaration for the __INITIALIZE_P argument. */ ! static tree initialize_p_decl; /* The declaration for the __PRIORITY argument. */ ! static tree priority_decl; /* The declaration for the static storage duration function. */ ! static tree ssdf_decl; /* All the static storage duration functions created in this translation unit. */ ! static varray_type ssdf_decls; /* A map from priority levels to information about that priority level. There may be many such levels, so efficient lookup is --- 2239,2255 ---- #define SSDF_IDENTIFIER "__static_initialization_and_destruction" /* The declaration for the __INITIALIZE_P argument. */ ! static GTY(()) tree initialize_p_decl; /* The declaration for the __PRIORITY argument. */ ! static GTY(()) tree priority_decl; /* The declaration for the static storage duration function. */ ! static GTY(()) tree ssdf_decl; /* All the static storage duration functions created in this translation unit. */ ! static GTY(()) varray_type ssdf_decls; /* A map from priority levels to information about that priority level. There may be many such levels, so efficient lookup is *************** static splay_tree priority_info_map; *** 2831,2837 **** initialization and destruction of objects with static storage duration. The function generated takes two parameters of type `int': __INITIALIZE_P and __PRIORITY. If __INITIALIZE_P is ! non-zero, it performs initializations. Otherwise, it performs destructions. It only performs those initializations or destructions with the indicated __PRIORITY. The generated function returns no value. --- 2260,2266 ---- initialization and destruction of objects with static storage duration. The function generated takes two parameters of type `int': __INITIALIZE_P and __PRIORITY. If __INITIALIZE_P is ! nonzero, it performs initializations. Otherwise, it performs destructions. It only performs those initializations or destructions with the indicated __PRIORITY. The generated function returns no value. *************** start_static_storage_duration_function ( *** 2880,2886 **** VARRAY_TREE_INIT (ssdf_decls, 32, "ssdf_decls"); /* Take this opportunity to initialize the map from priority ! numbers to information about that priority level. */ priority_info_map = splay_tree_new (splay_tree_compare_ints, /*delete_key_fn=*/0, /*delete_value_fn=*/ --- 2309,2315 ---- VARRAY_TREE_INIT (ssdf_decls, 32, "ssdf_decls"); /* Take this opportunity to initialize the map from priority ! numbers to information about that priority level. */ priority_info_map = splay_tree_new (splay_tree_compare_ints, /*delete_key_fn=*/0, /*delete_value_fn=*/ *************** start_static_storage_duration_function ( *** 2896,2911 **** VARRAY_PUSH_TREE (ssdf_decls, ssdf_decl); /* Create the argument list. */ ! initialize_p_decl = build_decl (PARM_DECL, ! get_identifier (INITIALIZE_P_IDENTIFIER), ! integer_type_node); DECL_CONTEXT (initialize_p_decl) = ssdf_decl; - DECL_ARG_TYPE (initialize_p_decl) = integer_type_node; TREE_USED (initialize_p_decl) = 1; ! priority_decl = build_decl (PARM_DECL, get_identifier (PRIORITY_IDENTIFIER), ! integer_type_node); DECL_CONTEXT (priority_decl) = ssdf_decl; - DECL_ARG_TYPE (priority_decl) = integer_type_node; TREE_USED (priority_decl) = 1; TREE_CHAIN (initialize_p_decl) = priority_decl; --- 2325,2337 ---- VARRAY_PUSH_TREE (ssdf_decls, ssdf_decl); /* Create the argument list. */ ! initialize_p_decl = cp_build_parm_decl ! (get_identifier (INITIALIZE_P_IDENTIFIER), integer_type_node); DECL_CONTEXT (initialize_p_decl) = ssdf_decl; TREE_USED (initialize_p_decl) = 1; ! priority_decl = cp_build_parm_decl ! (get_identifier (PRIORITY_IDENTIFIER), integer_type_node); DECL_CONTEXT (priority_decl) = ssdf_decl; TREE_USED (priority_decl) = 1; TREE_CHAIN (initialize_p_decl) = priority_decl; *************** get_priority_info (priority) *** 2981,2987 **** } /* Set up to handle the initialization or destruction of DECL. If ! INITP is non-zero, we are initializing the variable. Otherwise, we are destroying it. */ static tree --- 2407,2413 ---- } /* Set up to handle the initialization or destruction of DECL. If ! INITP is nonzero, we are initializing the variable. Otherwise, we are destroying it. */ static tree *************** finish_static_initialization_or_destruct *** 3121,3154 **** DECL_STATIC_FUNCTION_P (current_function_decl) = 0; } ! /* Generate code to do the static initialization of DECL. The ! initialization is INIT. If DECL may be initialized more than once ! in different object files, GUARD is the guard variable to ! check. PRIORITY is the priority for the initialization. */ static void do_static_initialization (decl, init) tree decl; tree init; { - tree expr; tree guard_if_stmt; /* Set up for the initialization. */ guard_if_stmt = start_static_initialization_or_destruction (decl, /*initp=*/1); ! ! /* Do the initialization itself. */ ! if (IS_AGGR_TYPE (TREE_TYPE (decl)) ! || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) ! expr = build_aggr_init (decl, init, 0); ! else ! { ! expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init); ! TREE_SIDE_EFFECTS (expr) = 1; ! } ! finish_expr_stmt (expr); /* If we're using __cxa_atexit, register a a function that calls the destructor for the object. */ --- 2547,2570 ---- DECL_STATIC_FUNCTION_P (current_function_decl) = 0; } ! /* Generate code to do the initialization of DECL, a VAR_DECL with ! static storage duration. The initialization is INIT. */ static void do_static_initialization (decl, init) tree decl; tree init; { tree guard_if_stmt; /* Set up for the initialization. */ guard_if_stmt = start_static_initialization_or_destruction (decl, /*initp=*/1); ! ! /* Perform the initialization. */ ! if (init) ! finish_expr_stmt (init); /* If we're using __cxa_atexit, register a a function that calls the destructor for the object. */ *************** do_static_destruction (decl) *** 3180,3186 **** /* Actually do the destruction. */ guard_if_stmt = start_static_initialization_or_destruction (decl, ! /*initp=*/0); finish_expr_stmt (build_cleanup (decl)); finish_static_initialization_or_destruction (guard_if_stmt); } --- 2596,2602 ---- /* Actually do the destruction. */ guard_if_stmt = start_static_initialization_or_destruction (decl, ! /*initp=*/0); finish_expr_stmt (build_cleanup (decl)); finish_static_initialization_or_destruction (guard_if_stmt); } *************** do_static_destruction (decl) *** 3195,3215 **** static tree prune_vars_needing_no_initialization (vars) ! tree vars; { ! tree var; ! tree result; ! for (var = vars, result = NULL_TREE; ! var; ! var = TREE_CHAIN (var)) { ! tree decl = TREE_VALUE (var); ! tree init = TREE_PURPOSE (var); /* Deal gracefully with error. */ if (decl == error_mark_node) ! continue; /* The only things that can be initialized are variables. */ my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 19990420); --- 2611,2633 ---- static tree prune_vars_needing_no_initialization (vars) ! tree *vars; { ! tree *var = vars; ! tree result = NULL_TREE; ! while (*var) { ! tree t = *var; ! tree decl = TREE_VALUE (t); ! tree init = TREE_PURPOSE (t); /* Deal gracefully with error. */ if (decl == error_mark_node) ! { ! var = &TREE_CHAIN (t); ! continue; ! } /* The only things that can be initialized are variables. */ my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 19990420); *************** prune_vars_needing_no_initialization (va *** 3217,3233 **** /* If this object is not defined, we don't need to do anything here. */ if (DECL_EXTERNAL (decl)) ! continue; /* Also, if the initializer already contains errors, we can bail out now. */ if (init && TREE_CODE (init) == TREE_LIST && value_member (error_mark_node, init)) ! continue; /* This variable is going to need initialization and/or finalization, so we add it to the list. */ ! result = tree_cons (init, decl, result); } return result; --- 2635,2659 ---- /* If this object is not defined, we don't need to do anything here. */ if (DECL_EXTERNAL (decl)) ! { ! var = &TREE_CHAIN (t); ! continue; ! } /* Also, if the initializer already contains errors, we can bail out now. */ if (init && TREE_CODE (init) == TREE_LIST && value_member (error_mark_node, init)) ! { ! var = &TREE_CHAIN (t); ! continue; ! } /* This variable is going to need initialization and/or finalization, so we add it to the list. */ ! *var = TREE_CHAIN (t); ! TREE_CHAIN (t) = result; ! result = t; } return result; *************** finish_file () *** 3364,3370 **** All of these may cause others to be needed. For example, instantiating one function may cause another to be needed, and ! generating the intiailzer for an object may cause templates to be instantiated, etc., etc. */ timevar_push (TV_VARCONST); --- 2790,2796 ---- All of these may cause others to be needed. For example, instantiating one function may cause another to be needed, and ! generating the initializer for an object may cause templates to be instantiated, etc., etc. */ timevar_push (TV_VARCONST); *************** finish_file () *** 3373,3378 **** --- 2799,2806 ---- do { + tree t; + reconsider = 0; /* If there are templates that we've put off instantiating, do *************** finish_file () *** 3380,3391 **** instantiate_pending_templates (); /* Write out virtual tables as required. Note that writing out ! the virtual table for a template class may cause the ! instantiation of members of that class. */ ! if (walk_globals (vtable_decl_p, ! finish_vtable_vardecl, ! /*data=*/0)) ! reconsider = 1; /* Write out needed type info variables. Writing out one variable might cause others to be needed. */ --- 2808,2843 ---- instantiate_pending_templates (); /* Write out virtual tables as required. Note that writing out ! the virtual table for a template class may cause the ! instantiation of members of that class. If we write out ! vtables then we remove the class from our list so we don't ! have to look at it again. */ ! ! while (keyed_classes != NULL_TREE ! && maybe_emit_vtables (TREE_VALUE (keyed_classes))) ! { ! reconsider = 1; ! keyed_classes = TREE_CHAIN (keyed_classes); ! } ! ! t = keyed_classes; ! if (t != NULL_TREE) ! { ! tree next = TREE_CHAIN (t); ! ! while (next) ! { ! if (maybe_emit_vtables (TREE_VALUE (next))) ! { ! reconsider = 1; ! TREE_CHAIN (t) = TREE_CHAIN (next); ! } ! else ! t = next; ! ! next = TREE_CHAIN (t); ! } ! } /* Write out needed type info variables. Writing out one variable might cause others to be needed. */ *************** finish_file () *** 3397,3404 **** aggregates added during the initialization of these will be initialized in the correct order when we next come around the loop. */ ! vars = prune_vars_needing_no_initialization (static_aggregates); ! static_aggregates = NULL_TREE; if (vars) { --- 2849,2855 ---- aggregates added during the initialization of these will be initialized in the correct order when we next come around the loop. */ ! vars = prune_vars_needing_no_initialization (&static_aggregates); if (vars) { *************** finish_file () *** 3446,3457 **** reconsider = 1; } - /* Go through the various inline functions, and see if any need - synthesizing. */ for (i = 0; i < deferred_fns_used; ++i) { tree decl = VARRAY_TREE (deferred_fns, i); ! import_export_decl (decl); if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl) && TREE_USED (decl) && (! DECL_REALLY_EXTERN (decl) || DECL_INLINE (decl))) --- 2897,2907 ---- reconsider = 1; } for (i = 0; i < deferred_fns_used; ++i) { tree decl = VARRAY_TREE (deferred_fns, i); ! ! /* Does it need synthesizing? */ if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl) && TREE_USED (decl) && (! DECL_REALLY_EXTERN (decl) || DECL_INLINE (decl))) *************** finish_file () *** 3466,3495 **** pop_from_top_level (); reconsider = 1; } - } ! /* We lie to the back-end, pretending that some functions are ! not defined when they really are. This keeps these functions ! from being put out unnecessarily. But, we must stop lying ! when the functions are referenced, or if they are not comdat ! since they need to be put out now. ! This is done in a separate for cycle, because if some deferred ! function is contained in another deferred function later in ! deferred_fns varray, rest_of_compilation would skip this ! function and we really cannot expand the same function twice. */ ! for (i = 0; i < deferred_fns_used; ++i) ! { ! tree decl = VARRAY_TREE (deferred_fns, i); ! if (DECL_NOT_REALLY_EXTERN (decl) && DECL_INITIAL (decl) && DECL_NEEDED_P (decl)) DECL_EXTERNAL (decl) = 0; - } - - for (i = 0; i < deferred_fns_used; ++i) - { - tree decl = VARRAY_TREE (deferred_fns, i); /* If we're going to need to write this function out, and there's already a body for it, create RTL for it now. --- 2916,2947 ---- pop_from_top_level (); reconsider = 1; } ! /* If the function has no body, avoid calling ! import_export_decl. On a system without weak symbols, ! calling import_export_decl will make an inline template ! instantiation "static", which will result in errors about ! the use of undefined functions if there is no body for ! the function. */ ! if (!DECL_SAVED_TREE (decl)) ! continue; ! ! import_export_decl (decl); ! ! /* We lie to the back-end, pretending that some functions ! are not defined when they really are. This keeps these ! functions from being put out unnecessarily. But, we must ! stop lying when the functions are referenced, or if they ! are not comdat since they need to be put out now. This ! is done in a separate for cycle, because if some deferred ! function is contained in another deferred function later ! in deferred_fns varray, rest_of_compilation would skip ! this function and we really cannot expand the same ! function twice. */ if (DECL_NOT_REALLY_EXTERN (decl) && DECL_INITIAL (decl) && DECL_NEEDED_P (decl)) DECL_EXTERNAL (decl) = 0; /* If we're going to need to write this function out, and there's already a body for it, create RTL for it now. *************** finish_file () *** 3545,3550 **** --- 2997,3016 ---- } while (reconsider); + /* All used inline functions must have a definition at this point. */ + for (i = 0; i < deferred_fns_used; ++i) + { + tree decl = VARRAY_TREE (deferred_fns, i); + + if (TREE_USED (decl) && DECL_DECLARED_INLINE_P (decl) + && !(TREE_ASM_WRITTEN (decl) || DECL_SAVED_TREE (decl) + /* An explicit instantiation can be used to specify + that the body is in another unit. It will have + already verified there was a definition. */ + || DECL_EXPLICIT_INSTANTIATION (decl))) + cp_warning_at ("inline function `%D' used but never defined", decl); + } + /* We give C linkage to static constructors and destructors. */ push_lang_context (lang_name_c); *************** finish_file () *** 3563,3575 **** linkage now. */ pop_lang_context (); - /* Now delete from the chain of variables all virtual function tables. - We output them all ourselves, because each will be treated - specially. We don't do this if we're just doing semantic - analysis, and not code-generation. */ - if (!flag_syntax_only) - walk_globals (vtable_decl_p, prune_vtable_vardecl, /*data=*/0); - /* Now, issue warnings about static, but not defined, functions, etc., and emit debugging information. */ walk_namespaces (wrapup_globals_for_namespace, /*data=*/&reconsider); --- 3029,3034 ---- *************** finish_file () *** 3580,3586 **** finish_repo (); /* The entire file is now complete. If requested, dump everything ! to a file. */ { int flags; FILE *stream = dump_begin (TDI_all, &flags); --- 3039,3045 ---- finish_repo (); /* The entire file is now complete. If requested, dump everything ! to a file. */ { int flags; FILE *stream = dump_begin (TDI_all, &flags); *************** reparse_absdcl_as_expr (type, decl) *** 3621,3634 **** /* recurse */ decl = reparse_absdcl_as_expr (type, TREE_OPERAND (decl, 0)); ! decl = build_x_function_call (decl, NULL_TREE, current_class_ref); ! ! if (TREE_CODE (decl) == CALL_EXPR ! && (! TREE_TYPE (decl) ! || TREE_CODE (TREE_TYPE (decl)) != VOID_TYPE)) ! decl = require_complete_type (decl); ! ! return decl; } /* This is something of the form `int ((int)(int)(int)1)' that has turned --- 3080,3086 ---- /* recurse */ decl = reparse_absdcl_as_expr (type, TREE_OPERAND (decl, 0)); ! return finish_call_expr (decl, NULL_TREE, /*disallow_virtual=*/false); } /* This is something of the form `int ((int)(int)(int)1)' that has turned *************** reparse_absdcl_as_casts (decl, expr) *** 3681,3687 **** return expr; } ! /* Given plain tree nodes for an expression, build up the full semantics. */ tree build_expr_from_tree (t) --- 3133,3140 ---- return expr; } ! /* T is the parse tree for an expression. Return the expression after ! performing semantic analysis. */ tree build_expr_from_tree (t) *************** build_expr_from_tree (t) *** 3697,3710 **** case LOOKUP_EXPR: if (LOOKUP_EXPR_GLOBAL (t)) ! return do_scoped_id (TREE_OPERAND (t, 0), 0); else return do_identifier (TREE_OPERAND (t, 0), 0, NULL_TREE); case TEMPLATE_ID_EXPR: ! return (lookup_template_function ! (build_expr_from_tree (TREE_OPERAND (t, 0)), ! build_expr_from_tree (TREE_OPERAND (t, 1)))); case INDIRECT_REF: return build_x_indirect_ref --- 3150,3186 ---- case LOOKUP_EXPR: if (LOOKUP_EXPR_GLOBAL (t)) ! { ! tree token = TREE_OPERAND (t, 0); ! return do_scoped_id (token, IDENTIFIER_GLOBAL_VALUE (token)); ! } else return do_identifier (TREE_OPERAND (t, 0), 0, NULL_TREE); case TEMPLATE_ID_EXPR: ! { ! tree template; ! tree args; ! tree object; ! ! template = build_expr_from_tree (TREE_OPERAND (t, 0)); ! args = build_expr_from_tree (TREE_OPERAND (t, 1)); ! ! if (TREE_CODE (template) == COMPONENT_REF) ! { ! object = TREE_OPERAND (template, 0); ! template = TREE_OPERAND (template, 1); ! } ! else ! object = NULL_TREE; ! ! template = lookup_template_function (template, args); ! if (object) ! return build (COMPONENT_REF, TREE_TYPE (template), ! object, template); ! else ! return template; ! } case INDIRECT_REF: return build_x_indirect_ref *************** build_expr_from_tree (t) *** 3803,3810 **** case ALIGNOF_EXPR: { tree r = build_expr_from_tree (TREE_OPERAND (t, 0)); ! return (TREE_CODE (t) == SIZEOF_EXPR ! ? finish_sizeof (r) : finish_alignof (r)); } case MODOP_EXPR: --- 3279,3288 ---- case ALIGNOF_EXPR: { tree r = build_expr_from_tree (TREE_OPERAND (t, 0)); ! if (!TYPE_P (r)) ! return TREE_CODE (t) == SIZEOF_EXPR ? expr_sizeof (r) : c_alignof_expr (r); ! else ! return cxx_sizeof_or_alignof_type (r, TREE_CODE (t), true); } case MODOP_EXPR: *************** build_expr_from_tree (t) *** 3884,3899 **** { tree ref = TREE_OPERAND (t, 0); tree name = TREE_OPERAND (ref, 1); if (TREE_CODE (name) == TEMPLATE_ID_EXPR) name = build_nt (TEMPLATE_ID_EXPR, TREE_OPERAND (name, 0), build_expr_from_tree (TREE_OPERAND (name, 1))); ! ! return build_member_call ! (build_expr_from_tree (TREE_OPERAND (ref, 0)), ! name, ! build_expr_from_tree (TREE_OPERAND (t, 1))); } else { --- 3362,3379 ---- { tree ref = TREE_OPERAND (t, 0); tree name = TREE_OPERAND (ref, 1); + tree fn, scope, args; if (TREE_CODE (name) == TEMPLATE_ID_EXPR) name = build_nt (TEMPLATE_ID_EXPR, TREE_OPERAND (name, 0), build_expr_from_tree (TREE_OPERAND (name, 1))); ! ! scope = build_expr_from_tree (TREE_OPERAND (ref, 0)); ! args = build_expr_from_tree (TREE_OPERAND (t, 1)); ! fn = resolve_scoped_fn_name (scope, name); ! ! return build_call_from_tree (fn, args, 1); } else { *************** build_expr_from_tree (t) *** 3906,3918 **** && (!current_class_type || !lookup_member (current_class_type, id, 0, 0))) { ! /* Do Koenig lookup if there are no class members. */ name = do_identifier (id, 0, args); } else if (TREE_CODE (name) == TEMPLATE_ID_EXPR ! || ! really_overloaded_fn (name)) name = build_expr_from_tree (name); ! return build_x_function_call (name, args, current_class_ref); } case COND_EXPR: --- 3386,3407 ---- && (!current_class_type || !lookup_member (current_class_type, id, 0, 0))) { ! /* Do Koenig lookup if there are no class members. */ name = do_identifier (id, 0, args); } else if (TREE_CODE (name) == TEMPLATE_ID_EXPR ! || ! really_overloaded_fn (name)) name = build_expr_from_tree (name); ! ! if (TREE_CODE (name) == OFFSET_REF) ! return build_offset_ref_call_from_tree (name, args); ! if (TREE_CODE (name) == COMPONENT_REF) ! return finish_object_call_expr (TREE_OPERAND (name, 1), ! TREE_OPERAND (name, 0), ! args); ! name = convert_from_reference (name); ! return build_call_from_tree (name, args, ! /*disallow_virtual=*/false); } case COND_EXPR: *************** build_expr_from_tree (t) *** 3949,3966 **** case COMPONENT_REF: { tree object = build_expr_from_tree (TREE_OPERAND (t, 0)); ! tree field = TREE_OPERAND (t, 1); ! ! /* We use a COMPONENT_REF to indicate things of the form `x.b' ! and `x.A::b'. We must distinguish between those cases ! here. */ ! if (TREE_CODE (field) == SCOPE_REF) ! return build_object_ref (object, ! TREE_OPERAND (field, 0), ! TREE_OPERAND (field, 1)); ! else ! return build_x_component_ref (object, field, ! NULL_TREE, 1); } case THROW_EXPR: --- 3438,3445 ---- case COMPONENT_REF: { tree object = build_expr_from_tree (TREE_OPERAND (t, 0)); ! return finish_class_member_access_expr (object, ! TREE_OPERAND (t, 1)); } case THROW_EXPR: *************** build_expr_from_tree (t) *** 4018,4023 **** --- 3497,3604 ---- } } + /* FN is an OFFSET_REF indicating the function to call in parse-tree + form; it has not yet been semantically analyzed. ARGS are the + arguments to the function. They have already been semantically + analzyed. */ + + tree + build_offset_ref_call_from_tree (tree fn, tree args) + { + tree object_addr; + + my_friendly_assert (TREE_CODE (fn) == OFFSET_REF, 20020725); + + /* A qualified name corresponding to a non-static member + function or a pointer-to-member is represented as an + OFFSET_REF. + + For both of these function calls, FN will be an OFFSET_REF. + + struct A { void f(); }; + void A::f() { (A::f) (); } + + struct B { void g(); }; + void (B::*p)(); + void B::g() { (this->*p)(); } */ + + /* This code is not really correct (for example, it does not + handle the case that `A::f' is overloaded), but it is + historically how we have handled this situation. */ + if (TREE_CODE (TREE_OPERAND (fn, 1)) == FIELD_DECL) + fn = resolve_offset_ref (fn); + else + { + object_addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (fn, 0), 0); + fn = TREE_OPERAND (fn, 1); + fn = get_member_function_from_ptrfunc (&object_addr, fn); + args = tree_cons (NULL_TREE, object_addr, args); + } + return build_function_call (fn, args); + } + + /* FN indicates the function to call. Name resolution has been + performed on FN. ARGS are the arguments to the function. They + have already been semantically analyzed. DISALLOW_VIRTUAL is true + if the function call should be determined at compile time, even if + FN is virtual. */ + + tree + build_call_from_tree (tree fn, tree args, bool disallow_virtual) + { + tree template_args; + tree template_id; + tree f; + + /* Check to see that name lookup has already been performed. */ + my_friendly_assert (TREE_CODE (fn) != OFFSET_REF, 20020725); + my_friendly_assert (TREE_CODE (fn) != SCOPE_REF, 20020725); + + /* In the future all of this should be eliminated. Instead, + name-lookup for a member function should simply return a + baselink, instead of a FUNCTION_DECL, TEMPLATE_DECL, or + TEMPLATE_ID_EXPR. */ + + if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) + { + template_id = fn; + template_args = TREE_OPERAND (fn, 1); + fn = TREE_OPERAND (fn, 0); + } + else + { + template_id = NULL_TREE; + template_args = NULL_TREE; + } + + f = (TREE_CODE (fn) == OVERLOAD) ? get_first_fn (fn) : fn; + /* Make sure we have a baselink (rather than simply a + FUNCTION_DECL) for a member function. */ + if (current_class_type + && ((TREE_CODE (f) == FUNCTION_DECL + && DECL_FUNCTION_MEMBER_P (f)) + || (DECL_FUNCTION_TEMPLATE_P (f) + && DECL_FUNCTION_MEMBER_P (f)))) + { + f = lookup_member (current_class_type, DECL_NAME (f), + /*protect=*/1, /*want_type=*/0); + if (f) + fn = f; + } + + if (template_id) + { + if (BASELINK_P (fn)) + BASELINK_FUNCTIONS (fn) = build_nt (TEMPLATE_ID_EXPR, + BASELINK_FUNCTIONS (fn), + template_args); + else + fn = template_id; + } + + return finish_call_expr (fn, args, disallow_virtual); + } + /* This is something of the form `int (*a)++' that has turned out to be an expr. It was only converted into parse nodes, so we need to go through and build up the semantics. Most of the work is done by *************** finish_decl_parsing (decl) *** 4076,4107 **** } } ! /* Return 1 if root encloses child. */ ! static int ! is_namespace_ancestor (root, child) ! tree root, child; { ! if (root == child) ! return 1; if (root == global_namespace) ! return 1; ! if (child == global_namespace) ! return 0; ! return is_namespace_ancestor (root, CP_DECL_CONTEXT (child)); } - /* Return the namespace that is the common ancestor ! of two given namespaces. */ tree namespace_ancestor (ns1, ns2) tree ns1, ns2; { ! if (is_namespace_ancestor (ns1, ns2)) ! return ns1; ! return namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2); } /* Insert used into the using list of user. Set indirect_flag if this --- 3657,3707 ---- } } ! /* Returns true if ROOT (a namespace, class, or function) encloses ! CHILD. CHILD may be either a class type or a namespace. */ ! bool ! is_ancestor (tree root, tree child) { ! my_friendly_assert ((TREE_CODE (root) == NAMESPACE_DECL ! || TREE_CODE (root) == FUNCTION_DECL ! || CLASS_TYPE_P (root)), 20030307); ! my_friendly_assert ((TREE_CODE (child) == NAMESPACE_DECL ! || TREE_CODE (root) == FUNCTION_DECL ! || CLASS_TYPE_P (child)), ! 20030307); ! ! /* The global namespace encloses everything. */ if (root == global_namespace) ! return true; ! ! while (true) ! { ! /* If we've run out of scopes, stop. */ ! if (!child) ! return false; ! /* If we've reached the ROOT, it encloses CHILD. */ ! if (root == child) ! return true; ! /* Go out one level. */ ! if (TYPE_P (child)) ! child = TYPE_NAME (child); ! child = DECL_CONTEXT (child); ! } } /* Return the namespace that is the common ancestor ! of two given namespaces. */ tree namespace_ancestor (ns1, ns2) tree ns1, ns2; { ! timevar_push (TV_NAME_LOOKUP); ! if (is_ancestor (ns1, ns2)) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ns1); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ! namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2)); } /* Insert used into the using list of user. Set indirect_flag if this *************** add_using_namespace (user, used, indirec *** 4114,4153 **** int indirect; { tree t; ! /* Using oneself is a no-op. */ if (user == used) ! return; my_friendly_assert (TREE_CODE (user) == NAMESPACE_DECL, 380); my_friendly_assert (TREE_CODE (used) == NAMESPACE_DECL, 380); ! /* Check if we already have this. */ t = purpose_member (used, DECL_NAMESPACE_USING (user)); if (t != NULL_TREE) { if (!indirect) ! /* Promote to direct usage. */ TREE_INDIRECT_USING (t) = 0; ! return; } ! /* Add used to the user's using list. */ DECL_NAMESPACE_USING (user) = tree_cons (used, namespace_ancestor (user, used), DECL_NAMESPACE_USING (user)); TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect; ! /* Add user to the used's users list. */ DECL_NAMESPACE_USERS (used) = tree_cons (user, 0, DECL_NAMESPACE_USERS (used)); ! /* Recursively add all namespaces used. */ for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t)) /* indirect usage */ add_using_namespace (user, TREE_PURPOSE (t), 1); ! /* Tell everyone using us about the new used namespaces. */ for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t)) add_using_namespace (TREE_PURPOSE (t), used, 1); } /* Combines two sets of overloaded functions into an OVERLOAD chain, removing --- 3714,3755 ---- int indirect; { tree t; ! timevar_push (TV_NAME_LOOKUP); ! /* Using oneself is a no-op. */ if (user == used) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0); my_friendly_assert (TREE_CODE (user) == NAMESPACE_DECL, 380); my_friendly_assert (TREE_CODE (used) == NAMESPACE_DECL, 380); ! /* Check if we already have this. */ t = purpose_member (used, DECL_NAMESPACE_USING (user)); if (t != NULL_TREE) { if (!indirect) ! /* Promote to direct usage. */ TREE_INDIRECT_USING (t) = 0; ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0); } ! /* Add used to the user's using list. */ DECL_NAMESPACE_USING (user) = tree_cons (used, namespace_ancestor (user, used), DECL_NAMESPACE_USING (user)); TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect; ! /* Add user to the used's users list. */ DECL_NAMESPACE_USERS (used) = tree_cons (user, 0, DECL_NAMESPACE_USERS (used)); ! /* Recursively add all namespaces used. */ for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t)) /* indirect usage */ add_using_namespace (user, TREE_PURPOSE (t), 1); ! /* Tell everyone using us about the new used namespaces. */ for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t)) add_using_namespace (TREE_PURPOSE (t), used, 1); + timevar_pop (TV_NAME_LOOKUP); } /* Combines two sets of overloaded functions into an OVERLOAD chain, removing *************** merge_functions (s1, s2) *** 4196,4218 **** XXX In what way should I treat extern declarations? XXX I don't want to repeat the entire duplicate_decls here */ ! static tree ! ambiguous_decl (name, old, new, flags) ! tree name; ! tree old; ! tree new; ! int flags; { tree val, type; ! my_friendly_assert (old != NULL_TREE, 393); ! /* Copy the value. */ val = BINDING_VALUE (new); if (val) switch (TREE_CODE (val)) { case TEMPLATE_DECL: /* If we expect types or namespaces, and not templates, ! or this is not a template class. */ if (LOOKUP_QUALIFIERS_ONLY (flags) && !DECL_CLASS_TEMPLATE_P (val)) val = NULL_TREE; --- 3798,3816 ---- XXX In what way should I treat extern declarations? XXX I don't want to repeat the entire duplicate_decls here */ ! static cxx_binding * ! ambiguous_decl (tree name, cxx_binding *old, cxx_binding *new, int flags) { tree val, type; ! my_friendly_assert (old != NULL, 393); ! /* Copy the value. */ val = BINDING_VALUE (new); if (val) switch (TREE_CODE (val)) { case TEMPLATE_DECL: /* If we expect types or namespaces, and not templates, ! or this is not a template class. */ if (LOOKUP_QUALIFIERS_ONLY (flags) && !DECL_CLASS_TEMPLATE_P (val)) val = NULL_TREE; *************** ambiguous_decl (name, old, new, flags) *** 4247,4253 **** } else { ! /* Some declarations are functions, some are not. */ if (flags & LOOKUP_COMPLAIN) { /* If we've already given this error for this lookup, --- 3845,3851 ---- } else { ! /* Some declarations are functions, some are not. */ if (flags & LOOKUP_COMPLAIN) { /* If we've already given this error for this lookup, *************** ambiguous_decl (name, old, new, flags) *** 4264,4270 **** BINDING_VALUE (old) = error_mark_node; } } ! /* ... and copy the type. */ type = BINDING_TYPE (new); if (LOOKUP_NAMESPACES_ONLY (flags)) type = NULL_TREE; --- 3862,3868 ---- BINDING_VALUE (old) = error_mark_node; } } ! /* ... and copy the type. */ type = BINDING_TYPE (new); if (LOOKUP_NAMESPACES_ONLY (flags)) type = NULL_TREE; *************** ambiguous_decl (name, old, new, flags) *** 4287,4346 **** We are currently looking for names in namespace SCOPE, so we look through USINGS for using-directives of namespaces which have SCOPE as a common ancestor with the current scope. ! Returns zero on errors. */ ! int ! lookup_using_namespace (name, val, usings, scope, flags, spacesp) ! tree name, val, usings, scope; ! int flags; ! tree *spacesp; { tree iter; ! tree val1; /* Iterate over all used namespaces in current, searching for using ! directives of scope. */ for (iter = usings; iter; iter = TREE_CHAIN (iter)) if (TREE_VALUE (iter) == scope) { if (spacesp) *spacesp = tree_cons (TREE_PURPOSE (iter), NULL_TREE, *spacesp); ! val1 = binding_for_name (name, TREE_PURPOSE (iter)); ! /* Resolve ambiguities. */ ! val = ambiguous_decl (name, val, val1, flags); } ! return BINDING_VALUE (val) != error_mark_node; } /* [namespace.qual] Accepts the NAME to lookup and its qualifying SCOPE. ! Returns the name/type pair found into the CPLUS_BINDING RESULT, ! or 0 on error. */ ! int ! qualified_lookup_using_namespace (name, scope, result, flags) ! tree name; ! tree scope; ! tree result; ! int flags; { ! /* Maintain a list of namespaces visited... */ tree seen = NULL_TREE; ! /* ... and a list of namespace yet to see. */ tree todo = NULL_TREE; tree usings; /* Look through namespace aliases. */ scope = ORIGINAL_NAMESPACE (scope); ! while (scope && (result != error_mark_node)) { ! seen = tree_cons (scope, NULL_TREE, seen); ! result = ambiguous_decl (name, result, ! binding_for_name (name, scope), flags); if (!BINDING_VALUE (result) && !BINDING_TYPE (result)) ! /* Consider using directives. */ for (usings = DECL_NAMESPACE_USING (scope); usings; usings = TREE_CHAIN (usings)) ! /* If this was a real directive, and we have not seen it. */ if (!TREE_INDIRECT_USING (usings) && !purpose_member (TREE_PURPOSE (usings), seen)) todo = tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo); --- 3885,3948 ---- We are currently looking for names in namespace SCOPE, so we look through USINGS for using-directives of namespaces which have SCOPE as a common ancestor with the current scope. ! Returns zero on errors. */ ! bool ! lookup_using_namespace (tree name, cxx_binding *val, tree usings, ! tree scope, int flags, tree *spacesp) { tree iter; ! cxx_binding *val1; ! timevar_push (TV_NAME_LOOKUP); /* Iterate over all used namespaces in current, searching for using ! directives of scope. */ for (iter = usings; iter; iter = TREE_CHAIN (iter)) if (TREE_VALUE (iter) == scope) { if (spacesp) *spacesp = tree_cons (TREE_PURPOSE (iter), NULL_TREE, *spacesp); ! val1 = cxx_scope_find_binding_for_name (TREE_PURPOSE (iter), name); ! /* Resolve possible ambiguities. */ ! if (val1) ! val = ambiguous_decl (name, val, val1, flags); } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ! BINDING_VALUE (val) != error_mark_node); } /* [namespace.qual] Accepts the NAME to lookup and its qualifying SCOPE. ! Returns the name/type pair found into the cxx_binding *RESULT, ! or 0 on error. */ ! bool ! qualified_lookup_using_namespace (tree name, tree scope, cxx_binding *result, ! int flags) { ! /* Maintain a list of namespaces visited... */ tree seen = NULL_TREE; ! /* ... and a list of namespace yet to see. */ tree todo = NULL_TREE; tree usings; + timevar_push (TV_NAME_LOOKUP); /* Look through namespace aliases. */ scope = ORIGINAL_NAMESPACE (scope); ! while (scope && result->value != error_mark_node) { ! cxx_binding *b = cxx_scope_find_binding_for_name (scope, name); ! /* Record SCOPE and resolve declaration ambiguities if NAME was ! bound in SCOPE. */ ! if (b) ! { ! seen = tree_cons (scope, NULL_TREE, seen); ! result = ambiguous_decl (name, result, b, flags); ! } if (!BINDING_VALUE (result) && !BINDING_TYPE (result)) ! /* Consider using directives. */ for (usings = DECL_NAMESPACE_USING (scope); usings; usings = TREE_CHAIN (usings)) ! /* If this was a real directive, and we have not seen it. */ if (!TREE_INDIRECT_USING (usings) && !purpose_member (TREE_PURPOSE (usings), seen)) todo = tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo); *************** qualified_lookup_using_namespace (name, *** 4350,4364 **** todo = TREE_CHAIN (todo); } else ! scope = NULL_TREE; /* If there never was a todo list. */ } ! return result != error_mark_node; } /* [namespace.memdef]/2 */ /* Set the context of a declaration to scope. Complain if we are not ! outside scope. */ void set_decl_namespace (decl, scope, friendp) --- 3952,3966 ---- todo = TREE_CHAIN (todo); } else ! scope = NULL_TREE; /* If there never was a todo list. */ } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node); } /* [namespace.memdef]/2 */ /* Set the context of a declaration to scope. Complain if we are not ! outside scope. */ void set_decl_namespace (decl, scope, friendp) *************** set_decl_namespace (decl, scope, friendp *** 4368,4387 **** { tree old; ! /* Get rid of namespace aliases. */ scope = ORIGINAL_NAMESPACE (scope); /* It is ok for friends to be qualified in parallel space. */ ! if (!friendp && !is_namespace_ancestor (current_namespace, scope)) error ("declaration of `%D' not in a namespace surrounding `%D'", decl, scope); DECL_CONTEXT (decl) = FROB_CONTEXT (scope); if (scope != current_namespace) { ! /* See whether this has been declared in the namespace. */ old = namespace_binding (DECL_NAME (decl), scope); if (!old) ! /* No old declaration at all. */ goto complain; /* A template can be explicitly specialized in any namespace. */ if (processing_explicit_instantiation) --- 3970,3989 ---- { tree old; ! /* Get rid of namespace aliases. */ scope = ORIGINAL_NAMESPACE (scope); /* It is ok for friends to be qualified in parallel space. */ ! if (!friendp && !is_ancestor (current_namespace, scope)) error ("declaration of `%D' not in a namespace surrounding `%D'", decl, scope); DECL_CONTEXT (decl) = FROB_CONTEXT (scope); if (scope != current_namespace) { ! /* See whether this has been declared in the namespace. */ old = namespace_binding (DECL_NAME (decl), scope); if (!old) ! /* No old declaration at all. */ goto complain; /* A template can be explicitly specialized in any namespace. */ if (processing_explicit_instantiation) *************** set_decl_namespace (decl, scope, friendp *** 4391,4397 **** since it can't check for the correct constness at this point. pushdecl will find those errors later. */ return; ! /* Since decl is a function, old should contain a function decl. */ if (!is_overloaded_fn (old)) goto complain; if (processing_template_decl || processing_specialization) --- 3993,3999 ---- since it can't check for the correct constness at this point. pushdecl will find those errors later. */ return; ! /* Since decl is a function, old should contain a function decl. */ if (!is_overloaded_fn (old)) goto complain; if (processing_template_decl || processing_specialization) *************** set_decl_namespace (decl, scope, friendp *** 4411,4444 **** decl, scope); } ! /* Compute the namespace where a declaration is defined. */ static tree decl_namespace (decl) tree decl; { if (TYPE_P (decl)) decl = TYPE_STUB_DECL (decl); while (DECL_CONTEXT (decl)) { decl = DECL_CONTEXT (decl); if (TREE_CODE (decl) == NAMESPACE_DECL) ! return decl; if (TYPE_P (decl)) decl = TYPE_STUB_DECL (decl); my_friendly_assert (DECL_P (decl), 390); } ! return global_namespace; } ! /* Return the namespace where the current declaration is declared. */ tree current_decl_namespace () { tree result; ! /* If we have been pushed into a different namespace, use it. */ if (decl_namespace_list) return TREE_PURPOSE (decl_namespace_list); --- 4013,4047 ---- decl, scope); } ! /* Compute the namespace where a declaration is defined. */ static tree decl_namespace (decl) tree decl; { + timevar_push (TV_NAME_LOOKUP); if (TYPE_P (decl)) decl = TYPE_STUB_DECL (decl); while (DECL_CONTEXT (decl)) { decl = DECL_CONTEXT (decl); if (TREE_CODE (decl) == NAMESPACE_DECL) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); if (TYPE_P (decl)) decl = TYPE_STUB_DECL (decl); my_friendly_assert (DECL_P (decl), 390); } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, global_namespace); } ! /* Return the namespace where the current declaration is declared. */ tree current_decl_namespace () { tree result; ! /* If we have been pushed into a different namespace, use it. */ if (decl_namespace_list) return TREE_PURPOSE (decl_namespace_list); *************** current_decl_namespace () *** 4451,4457 **** return result; } ! /* Temporarily set the namespace for the current declaration. */ void push_decl_namespace (decl) --- 4054,4060 ---- return result; } ! /* Temporarily set the namespace for the current declaration. */ void push_decl_namespace (decl) *************** pop_decl_namespace () *** 4469,4475 **** decl_namespace_list = TREE_CHAIN (decl_namespace_list); } ! /* Enter a class or namespace scope. */ void push_scope (t) --- 4072,4078 ---- decl_namespace_list = TREE_CHAIN (decl_namespace_list); } ! /* Enter a class or namespace scope. */ void push_scope (t) *************** push_scope (t) *** 4477,4487 **** { if (TREE_CODE (t) == NAMESPACE_DECL) push_decl_namespace (t); ! else pushclass (t, 2); } ! /* Leave scope pushed by push_scope. */ void pop_scope (t) --- 4080,4090 ---- { if (TREE_CODE (t) == NAMESPACE_DECL) push_decl_namespace (t); ! else if (CLASS_TYPE_P (t)) pushclass (t, 2); } ! /* Leave scope pushed by push_scope. */ void pop_scope (t) *************** pop_scope (t) *** 4489,4501 **** { if (TREE_CODE (t) == NAMESPACE_DECL) pop_decl_namespace (); ! else popclass (); } /* [basic.lookup.koenig] */ ! /* A non-zero return value in the functions below indicates an error. ! All nodes allocated in the procedure are on the scratch obstack. */ struct arg_lookup { --- 4092,4103 ---- { if (TREE_CODE (t) == NAMESPACE_DECL) pop_decl_namespace (); ! else if (CLASS_TYPE_P (t)) popclass (); } /* [basic.lookup.koenig] */ ! /* A nonzero return value in the functions below indicates an error. */ struct arg_lookup { *************** add_function (k, fn) *** 4528,4534 **** total number of functions being compared, which should usually be the case. */ ! /* We must find only functions, or exactly one non-function. */ if (!k->functions) k->functions = fn; else if (is_overloaded_fn (k->functions) && is_overloaded_fn (fn)) --- 4130,4136 ---- total number of functions being compared, which should usually be the case. */ ! /* We must find only functions, or exactly one non-function. */ if (!k->functions) k->functions = fn; else if (is_overloaded_fn (k->functions) && is_overloaded_fn (fn)) *************** arg_assoc_class (k, type) *** 4642,4662 **** if (arg_assoc_namespace (k, context)) return 1; ! /* Process baseclasses. */ for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); i++) if (arg_assoc_class (k, TYPE_BINFO_BASETYPE (type, i))) return 1; ! /* Process friends. */ for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list; list = TREE_CHAIN (list)) if (k->name == TREE_PURPOSE (list)) for (friends = TREE_VALUE (list); friends; friends = TREE_CHAIN (friends)) /* Only interested in global functions with potentially hidden ! (i.e. unqualified) declarations. */ if (TREE_PURPOSE (friends) == error_mark_node && TREE_VALUE (friends) ! && decl_namespace (TREE_VALUE (friends)) == context) if (add_function (k, TREE_VALUE (friends))) return 1; --- 4244,4264 ---- if (arg_assoc_namespace (k, context)) return 1; ! /* Process baseclasses. */ for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); i++) if (arg_assoc_class (k, TYPE_BINFO_BASETYPE (type, i))) return 1; ! /* Process friends. */ for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list; list = TREE_CHAIN (list)) if (k->name == TREE_PURPOSE (list)) for (friends = TREE_VALUE (list); friends; friends = TREE_CHAIN (friends)) /* Only interested in global functions with potentially hidden ! (i.e. unqualified) declarations. */ if (TREE_PURPOSE (friends) == error_mark_node && TREE_VALUE (friends) ! && CP_DECL_CONTEXT (TREE_VALUE (friends)) == context) if (add_function (k, TREE_VALUE (friends))) return 1; *************** arg_assoc_type (k, type) *** 4701,4707 **** case ENUMERAL_TYPE: return arg_assoc_namespace (k, decl_namespace (TYPE_MAIN_DECL (type))); case OFFSET_TYPE: ! /* Pointer to member: associate class type and value type. */ if (arg_assoc_type (k, TYPE_OFFSET_BASETYPE (type))) return 1; return arg_assoc_type (k, TREE_TYPE (type)); --- 4303,4309 ---- case ENUMERAL_TYPE: return arg_assoc_namespace (k, decl_namespace (TYPE_MAIN_DECL (type))); case OFFSET_TYPE: ! /* Pointer to member: associate class type and value type. */ if (arg_assoc_type (k, TYPE_OFFSET_BASETYPE (type))) return 1; return arg_assoc_type (k, TREE_TYPE (type)); *************** arg_assoc_type (k, type) *** 4709,4718 **** /* The basetype is referenced in the first arg type, so just fall through. */ case FUNCTION_TYPE: ! /* Associate the parameter types. */ if (arg_assoc_args (k, TYPE_ARG_TYPES (type))) return 1; ! /* Associate the return type. */ return arg_assoc_type (k, TREE_TYPE (type)); case TEMPLATE_TYPE_PARM: case BOUND_TEMPLATE_TEMPLATE_PARM: --- 4311,4320 ---- /* The basetype is referenced in the first arg type, so just fall through. */ case FUNCTION_TYPE: ! /* Associate the parameter types. */ if (arg_assoc_args (k, TYPE_ARG_TYPES (type))) return 1; ! /* Associate the return type. */ return arg_assoc_type (k, TREE_TYPE (type)); case TEMPLATE_TYPE_PARM: case BOUND_TEMPLATE_TEMPLATE_PARM: *************** arg_assoc (k, n) *** 4766,4771 **** --- 4368,4375 ---- n = TREE_OPERAND (n, 1); while (TREE_CODE (n) == TREE_LIST) n = TREE_VALUE (n); + if (TREE_CODE (n) == BASELINK) + n = BASELINK_FUNCTIONS (n); if (TREE_CODE (n) == FUNCTION_DECL) return arg_assoc_type (k, TREE_TYPE (n)); *************** arg_assoc (k, n) *** 4819,4825 **** } /* Performs Koenig lookup depending on arguments, where fns ! are the functions found in normal lookup. */ tree lookup_arg_dependent (name, fns, args) --- 4423,4429 ---- } /* Performs Koenig lookup depending on arguments, where fns ! are the functions found in normal lookup. */ tree lookup_arg_dependent (name, fns, args) *************** lookup_arg_dependent (name, fns, args) *** 4830,4835 **** --- 4434,4443 ---- struct arg_lookup k; tree fn = NULL_TREE; + if (fns == error_mark_node) + fns = NULL_TREE; + + timevar_push (TV_NAME_LOOKUP); k.name = name; k.functions = fns; k.classes = NULL_TREE; *************** lookup_arg_dependent (name, fns, args) *** 4844,4853 **** unqualified_namespace_lookup (name, 0, &k.namespaces); arg_assoc_args (&k, args); ! return k.functions; } ! /* Process a namespace-alias declaration. */ void do_namespace_alias (alias, namespace) --- 4452,4461 ---- unqualified_namespace_lookup (name, 0, &k.namespaces); arg_assoc_args (&k, args); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, k.functions); } ! /* Process a namespace-alias declaration. */ void do_namespace_alias (alias, namespace) *************** do_namespace_alias (alias, namespace) *** 4855,4875 **** { if (TREE_CODE (namespace) != NAMESPACE_DECL) { ! /* The parser did not find it, so it's not there. */ error ("unknown namespace `%D'", namespace); return; } namespace = ORIGINAL_NAMESPACE (namespace); ! /* Build the alias. */ alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node); DECL_NAMESPACE_ALIAS (alias) = namespace; pushdecl (alias); } /* Check a non-member using-declaration. Return the name and scope ! being used, and the USING_DECL, or NULL_TREE on failure. */ static tree validate_nonmember_using_decl (decl, scope, name) --- 4463,4483 ---- { if (TREE_CODE (namespace) != NAMESPACE_DECL) { ! /* The parser did not find it, so it's not there. */ error ("unknown namespace `%D'", namespace); return; } namespace = ORIGINAL_NAMESPACE (namespace); ! /* Build the alias. */ alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node); DECL_NAMESPACE_ALIAS (alias) = namespace; pushdecl (alias); } /* Check a non-member using-declaration. Return the name and scope ! being used, and the USING_DECL, or NULL_TREE on failure. */ static tree validate_nonmember_using_decl (decl, scope, name) *************** validate_nonmember_using_decl (decl, sco *** 4922,4932 **** abort (); if (DECL_P (*name)) *name = DECL_NAME (*name); ! /* Make a USING_DECL. */ return push_using_decl (*scope, *name); } ! /* Process local and global using-declarations. */ static void do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype) --- 4530,4540 ---- abort (); if (DECL_P (*name)) *name = DECL_NAME (*name); ! /* Make a USING_DECL. */ return push_using_decl (*scope, *name); } ! /* Process local and global using-declarations. */ static void do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype) *************** do_nonmember_using_decl (scope, name, ol *** 4934,4966 **** tree oldval, oldtype; tree *newval, *newtype; { ! tree decls; *newval = *newtype = NULL_TREE; ! decls = make_node (CPLUS_BINDING); ! if (!qualified_lookup_using_namespace (name, scope, decls, 0)) /* Lookup error */ return; ! if (!BINDING_VALUE (decls) && !BINDING_TYPE (decls)) { error ("`%D' not declared", name); return; } ! /* Check for using functions. */ ! if (BINDING_VALUE (decls) && is_overloaded_fn (BINDING_VALUE (decls))) { tree tmp, tmp1; if (oldval && !is_overloaded_fn (oldval)) { ! duplicate_decls (OVL_CURRENT (BINDING_VALUE (decls)), oldval); oldval = NULL_TREE; } *newval = oldval; ! for (tmp = BINDING_VALUE (decls); tmp; tmp = OVL_NEXT (tmp)) { tree new_fn = OVL_CURRENT (tmp); --- 4542,4575 ---- tree oldval, oldtype; tree *newval, *newtype; { ! cxx_binding decls; *newval = *newtype = NULL_TREE; ! cxx_binding_clear (&decls); ! if (!qualified_lookup_using_namespace (name, scope, &decls, 0)) /* Lookup error */ return; ! if (!decls.value && !decls.type) { error ("`%D' not declared", name); return; } ! /* Check for using functions. */ ! if (decls.value && is_overloaded_fn (decls.value)) { tree tmp, tmp1; if (oldval && !is_overloaded_fn (oldval)) { ! if (!DECL_IMPLICIT_TYPEDEF_P (oldval)) ! error ("`%D' is already declared in this scope", name); oldval = NULL_TREE; } *newval = oldval; ! for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp)) { tree new_fn = OVL_CURRENT (tmp); *************** do_nonmember_using_decl (scope, name, ol *** 4982,5002 **** else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)), TYPE_ARG_TYPES (TREE_TYPE (old_fn)))) { - /* If this using declaration introduces a function - recognized as a built-in, no longer mark it as - anticipated in this scope. */ - if (DECL_ANTICIPATED (old_fn)) - { - DECL_ANTICIPATED (old_fn) = 0; - break; - } - /* There was already a non-using declaration in this scope with the same parameter types. If both are the same extern "C" functions, that's ok. */ ! if (!decls_match (new_fn, old_fn)) ! error ("`%D' is already declared in this scope", name); ! break; } } --- 4591,4617 ---- else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)), TYPE_ARG_TYPES (TREE_TYPE (old_fn)))) { /* There was already a non-using declaration in this scope with the same parameter types. If both are the same extern "C" functions, that's ok. */ ! if (decls_match (new_fn, old_fn)) ! { ! /* If the OLD_FN was a builtin, there is now a ! real declaration. */ ! if (DECL_ANTICIPATED (old_fn)) ! DECL_ANTICIPATED (old_fn) = 0; ! break; ! } ! else if (!DECL_ANTICIPATED (old_fn)) ! { ! /* If the OLD_FN was really declared, the ! declarations don't match. */ ! error ("`%D' is already declared in this scope", name); ! break; ! } ! ! /* If the OLD_FN was not really there, just ignore ! it and keep going. */ } } *************** do_nonmember_using_decl (scope, name, ol *** 5014,5026 **** } else { ! *newval = BINDING_VALUE (decls); ! if (oldval) ! duplicate_decls (*newval, oldval); } ! *newtype = BINDING_TYPE (decls); ! if (oldtype && *newtype && oldtype != *newtype) { error ("using declaration `%D' introduced ambiguous type `%T'", name, oldtype); --- 4629,4641 ---- } else { ! *newval = decls.value; ! if (oldval && !decls_match (*newval, oldval)) ! error ("`%D' is already declared in this scope", name); } ! *newtype = decls.type; ! if (oldtype && *newtype && !same_type_p (oldtype, *newtype)) { error ("using declaration `%D' introduced ambiguous type `%T'", name, oldtype); *************** do_nonmember_using_decl (scope, name, ol *** 5028,5046 **** } } ! /* Process a using-declaration not appearing in class or local scope. */ void do_toplevel_using_decl (decl) tree decl; { ! tree scope, name, binding; tree oldval, oldtype, newval, newtype; decl = validate_nonmember_using_decl (decl, &scope, &name); if (decl == NULL_TREE) return; ! binding = binding_for_name (name, current_namespace); oldval = BINDING_VALUE (binding); --- 4643,4664 ---- } } ! /* Process a using-declaration not appearing in class or local scope. */ void do_toplevel_using_decl (decl) tree decl; { ! tree scope, name; tree oldval, oldtype, newval, newtype; + cxx_binding *binding; decl = validate_nonmember_using_decl (decl, &scope, &name); if (decl == NULL_TREE) return; ! ! /* A multiple using-declaration is valid, so we call binding_for_name, ! not just cxx_binding_make. */ binding = binding_for_name (name, current_namespace); oldval = BINDING_VALUE (binding); *************** do_toplevel_using_decl (decl) *** 5048,5054 **** do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype); ! /* Copy declarations found. */ if (newval) BINDING_VALUE (binding) = newval; if (newtype) --- 4666,4672 ---- do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype); ! /* Copy declarations found. */ if (newval) BINDING_VALUE (binding) = newval; if (newtype) *************** do_class_using_decl (decl) *** 5130,5135 **** --- 4748,4760 ---- } if (TREE_CODE (name) == TYPE_DECL || TREE_CODE (name) == TEMPLATE_DECL) name = DECL_NAME (name); + else if (BASELINK_P (name)) + { + name = BASELINK_FUNCTIONS (name); + if (TREE_CODE (name) == TEMPLATE_ID_EXPR) + name = TREE_OPERAND (name, 0); + name = DECL_NAME (get_first_fn (name)); + } my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716); *************** do_class_using_decl (decl) *** 5138,5144 **** return value; } ! /* Process a using-directive. */ void do_using_directive (namespace) --- 4763,4769 ---- return value; } ! /* Process a using-directive. */ void do_using_directive (namespace) *************** do_using_directive (namespace) *** 5152,5158 **** namespace = TREE_OPERAND (namespace, 1); if (TREE_CODE (namespace) == IDENTIFIER_NODE) { ! /* Lookup in lexer did not find a namespace. */ if (!processing_template_decl) error ("namespace `%T' undeclared", namespace); return; --- 4777,4783 ---- namespace = TREE_OPERAND (namespace, 1); if (TREE_CODE (namespace) == IDENTIFIER_NODE) { ! /* Lookup in lexer did not find a namespace. */ if (!processing_template_decl) error ("namespace `%T' undeclared", namespace); return; *************** mark_used (decl) *** 5198,5203 **** --- 4823,4833 ---- if (processing_template_decl || skip_evaluation) return; + if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl) + && !TREE_ASM_WRITTEN (decl)) + /* Remember it, so we can check it was defined. */ + defer_fn (decl); + assemble_external (decl); /* Is it a synthesized method that needs to be synthesized? */ *************** mark_used (decl) *** 5222,5242 **** && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) && (!DECL_EXPLICIT_INSTANTIATION (decl) || (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl)))) ! instantiate_decl (decl, /*defer_ok=*/1); } /* Helper function for class_head_decl and class_head_defn nonterminals. AGGR is the class, union or struct tag. SCOPE is the explicit scope used (NULL for no scope resolution). ID is the name. DEFN_P is true, if this is a definition of the class and ! NEW_TYPE_P is set to non-zero, if we push into the scope containing the to be defined aggregate. Return a TYPE_DECL for the type declared by ID in SCOPE. */ tree ! handle_class_head (aggr, scope, id, defn_p, new_type_p) ! tree aggr, scope, id; int defn_p; int *new_type_p; { --- 4852,4899 ---- && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) && (!DECL_EXPLICIT_INSTANTIATION (decl) || (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl)))) ! { ! bool defer; ! ! /* Normally, we put off instantiating functions in order to ! improve compile times. Maintaining a stack of active ! functions is expensive, and the inliner knows to ! instantiate any functions it might need. ! ! However, if instantiating this function might help us mark ! the current function TREE_NOTHROW, we go ahead and ! instantiate it now. */ ! defer = (!flag_exceptions ! || TREE_CODE (decl) != FUNCTION_DECL ! /* If the called function can't throw, we don't need to ! generate its body to find that out. */ ! || TREE_NOTHROW (decl) ! || !cfun ! /* If we already know the current function can't throw, ! then we don't need to work hard to prove it. */ ! || TREE_NOTHROW (current_function_decl) ! /* If we already know that the current function *can* ! throw, there's no point in gathering more ! information. */ ! || cp_function_chain->can_throw); ! ! instantiate_decl (decl, defer); ! } } /* Helper function for class_head_decl and class_head_defn nonterminals. AGGR is the class, union or struct tag. SCOPE is the explicit scope used (NULL for no scope resolution). ID is the name. DEFN_P is true, if this is a definition of the class and ! NEW_TYPE_P is set to nonzero, if we push into the scope containing the to be defined aggregate. Return a TYPE_DECL for the type declared by ID in SCOPE. */ tree ! handle_class_head (tag_kind, scope, id, attributes, defn_p, new_type_p) ! enum tag_types tag_kind; ! tree scope, id, attributes; int defn_p; int *new_type_p; { *************** handle_class_head (aggr, scope, id, defn *** 5286,5292 **** if (!decl) { ! decl = TYPE_MAIN_DECL (xref_tag (aggr, id, !defn_p)); xrefd_p = true; } --- 4943,4952 ---- if (!decl) { ! decl = xref_tag (tag_kind, id, attributes, !defn_p); ! if (decl == error_mark_node) ! return error_mark_node; ! decl = TYPE_MAIN_DECL (decl); xrefd_p = true; } *************** handle_class_head (aggr, scope, id, defn *** 5319,5324 **** --- 4979,4996 ---- is different to the current scope. */ tree context = CP_DECL_CONTEXT (decl); + if (IMPLICIT_TYPENAME_P (context)) + context = TREE_TYPE (context); + + /* If that scope does not contain the scope in which the + class was originally declared, the program is invalid. */ + if (current && !is_ancestor (current, context)) + { + error ("declaration of `%D' in `%D' which does not " + "enclose `%D'", decl, current, CP_DECL_CONTEXT (decl)); + return NULL_TREE; + } + *new_type_p = (current != context && TREE_CODE (context) != TEMPLATE_TYPE_PARM && TREE_CODE (context) != BOUND_TEMPLATE_TEMPLATE_PARM); *************** handle_class_head (aggr, scope, id, defn *** 5326,5335 **** push_scope (context); if (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE) ! /* It is legal to define a class with a different class key, and this changes the default member access. */ CLASSTYPE_DECLARED_CLASS (TREE_TYPE (decl)) ! = aggr == class_type_node; if (!xrefd_p && PROCESSING_REAL_TEMPLATE_DECL_P ()) decl = push_template_decl (decl); --- 4998,5007 ---- push_scope (context); if (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE) ! /* It is valid to define a class with a different class key, and this changes the default member access. */ CLASSTYPE_DECLARED_CLASS (TREE_TYPE (decl)) ! = (tag_kind == class_type); if (!xrefd_p && PROCESSING_REAL_TEMPLATE_DECL_P ()) decl = push_template_decl (decl); *************** handle_class_head (aggr, scope, id, defn *** 5338,5352 **** return decl; } ! /* Initialize decl2.c. */ ! ! void ! init_decl2 () ! { ! ggc_add_tree_varray_root (&deferred_fns, 1); ! ggc_add_tree_varray_root (&pending_statics, 1); ! ggc_add_tree_varray_root (&ssdf_decls, 1); ! ggc_add_tree_root (&ssdf_decl, 1); ! ggc_add_tree_root (&priority_decl, 1); ! ggc_add_tree_root (&initialize_p_decl, 1); ! } --- 5010,5013 ---- return decl; } ! #include "gt-cp-decl2.h" diff -Nrc3pad gcc-3.2.3/gcc/cp/decl.c gcc-3.3/gcc/cp/decl.c *** gcc-3.2.3/gcc/cp/decl.c 2003-03-17 23:16:55.000000000 +0000 --- gcc-3.3/gcc/cp/decl.c 2003-04-29 18:51:56.000000000 +0000 *************** Boston, MA 02111-1307, USA. */ *** 41,74 **** #include "output.h" #include "except.h" #include "toplev.h" ! #include "../hash.h" #include "ggc.h" #include "tm_p.h" #include "target.h" #include "c-common.h" #include "c-pragma.h" #include "diagnostic.h" ! ! extern const struct attribute_spec *lang_attribute_table; static tree grokparms PARAMS ((tree)); static const char *redeclaration_error_message PARAMS ((tree, tree)); ! static void push_binding_level PARAMS ((struct binding_level *, int, int)); static void pop_binding_level PARAMS ((void)); static void suspend_binding_level PARAMS ((void)); ! static void resume_binding_level PARAMS ((struct binding_level *)); ! static struct binding_level *make_binding_level PARAMS ((void)); static void declare_namespace_level PARAMS ((void)); static int decl_jump_unsafe PARAMS ((tree)); static void storedecls PARAMS ((tree)); static void require_complete_types_for_parms PARAMS ((tree)); static int ambi_op_p PARAMS ((enum tree_code)); static int unary_op_p PARAMS ((enum tree_code)); ! static tree store_bindings PARAMS ((tree, tree)); static tree lookup_tag_reverse PARAMS ((tree, tree)); - static tree obscure_complex_init PARAMS ((tree, tree)); static tree lookup_name_real PARAMS ((tree, int, int, int)); static void push_local_name PARAMS ((tree)); static void warn_extern_redeclared_static PARAMS ((tree, tree)); --- 41,73 ---- #include "output.h" #include "except.h" #include "toplev.h" ! #include "hashtab.h" #include "ggc.h" #include "tm_p.h" #include "target.h" #include "c-common.h" #include "c-pragma.h" #include "diagnostic.h" ! #include "debug.h" ! #include "timevar.h" static tree grokparms PARAMS ((tree)); static const char *redeclaration_error_message PARAMS ((tree, tree)); ! static void push_binding_level PARAMS ((struct cp_binding_level *, int, int)); static void pop_binding_level PARAMS ((void)); static void suspend_binding_level PARAMS ((void)); ! static void resume_binding_level PARAMS ((struct cp_binding_level *)); ! static struct cp_binding_level *make_binding_level PARAMS ((void)); static void declare_namespace_level PARAMS ((void)); static int decl_jump_unsafe PARAMS ((tree)); static void storedecls PARAMS ((tree)); static void require_complete_types_for_parms PARAMS ((tree)); static int ambi_op_p PARAMS ((enum tree_code)); static int unary_op_p PARAMS ((enum tree_code)); ! static cxx_saved_binding *store_bindings (tree, cxx_saved_binding *); static tree lookup_tag_reverse PARAMS ((tree, tree)); static tree lookup_name_real PARAMS ((tree, int, int, int)); static void push_local_name PARAMS ((tree)); static void warn_extern_redeclared_static PARAMS ((tree, tree)); *************** static tree grokfndecl PARAMS ((tree, tr *** 79,138 **** static tree grokvardecl PARAMS ((tree, tree, RID_BIT_TYPE *, int, int, tree)); static tree follow_tag_typedef PARAMS ((tree)); static tree lookup_tag PARAMS ((enum tree_code, tree, ! struct binding_level *, int)); static void set_identifier_type_value_with_scope ! PARAMS ((tree, tree, struct binding_level *)); static void record_unknown_type PARAMS ((tree, const char *)); static tree builtin_function_1 PARAMS ((const char *, tree, tree, int, ! enum built_in_class, const char *)); static tree build_library_fn_1 PARAMS ((tree, enum tree_code, tree)); static int member_function_or_else PARAMS ((tree, tree, enum overload_flags)); static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int, int)); ! static tree maybe_process_template_type_declaration PARAMS ((tree, int, struct binding_level*)); static void check_for_uninitialized_const_var PARAMS ((tree)); ! static unsigned long typename_hash PARAMS ((hash_table_key)); ! static bool typename_compare PARAMS ((hash_table_key, hash_table_key)); ! static void push_binding PARAMS ((tree, tree, struct binding_level*)); static int add_binding PARAMS ((tree, tree)); static void pop_binding PARAMS ((tree, tree)); static tree local_variable_p_walkfn PARAMS ((tree *, int *, void *)); ! static tree find_binding PARAMS ((tree, tree)); ! static tree select_decl PARAMS ((tree, int)); static int lookup_flags PARAMS ((int, int)); static tree qualify_lookup PARAMS ((tree, int)); static tree record_builtin_java_type PARAMS ((const char *, int)); static const char *tag_name PARAMS ((enum tag_types code)); static void find_class_binding_level PARAMS ((void)); ! static struct binding_level *innermost_nonclass_level PARAMS ((void)); static void warn_about_implicit_typename_lookup PARAMS ((tree, tree)); static int walk_namespaces_r PARAMS ((tree, walk_namespaces_fn, void *)); static int walk_globals_r PARAMS ((tree, void *)); ! static void add_decl_to_level PARAMS ((tree, struct binding_level *)); static tree make_label_decl PARAMS ((tree, int)); static void use_label PARAMS ((tree)); ! static void check_previous_goto_1 PARAMS ((tree, struct binding_level *, tree, const char *, int)); static void check_previous_goto PARAMS ((struct named_label_use_list *)); ! static void check_switch_goto PARAMS ((struct binding_level *)); static void check_previous_gotos PARAMS ((tree)); static void pop_label PARAMS ((tree, tree)); static void pop_labels PARAMS ((tree)); static void maybe_deduce_size_from_array_init PARAMS ((tree, tree)); static void layout_var_decl PARAMS ((tree)); static void maybe_commonize_var PARAMS ((tree)); ! static tree check_initializer PARAMS ((tree, tree)); static void make_rtl_for_nonlocal_decl PARAMS ((tree, tree, const char *)); - static void push_cp_function_context PARAMS ((struct function *)); - static void pop_cp_function_context PARAMS ((struct function *)); - static void mark_binding_level PARAMS ((void *)); - static void mark_named_label_lists PARAMS ((void *, void *)); - static void mark_cp_function_context PARAMS ((struct function *)); - static void mark_saved_scope PARAMS ((void *)); - static void mark_lang_function PARAMS ((struct cp_language_function *)); static void save_function_data PARAMS ((tree)); static void check_function_type PARAMS ((tree, tree)); - static void destroy_local_var PARAMS ((tree)); static void begin_constructor_body PARAMS ((void)); static void finish_constructor_body PARAMS ((void)); static void begin_destructor_body PARAMS ((void)); --- 78,131 ---- static tree grokvardecl PARAMS ((tree, tree, RID_BIT_TYPE *, int, int, tree)); static tree follow_tag_typedef PARAMS ((tree)); static tree lookup_tag PARAMS ((enum tree_code, tree, ! struct cp_binding_level *, int)); static void set_identifier_type_value_with_scope ! PARAMS ((tree, tree, struct cp_binding_level *)); static void record_unknown_type PARAMS ((tree, const char *)); static tree builtin_function_1 PARAMS ((const char *, tree, tree, int, ! enum built_in_class, const char *, ! tree)); static tree build_library_fn_1 PARAMS ((tree, enum tree_code, tree)); static int member_function_or_else PARAMS ((tree, tree, enum overload_flags)); static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int, int)); ! static tree maybe_process_template_type_declaration PARAMS ((tree, int, struct cp_binding_level*)); static void check_for_uninitialized_const_var PARAMS ((tree)); ! static hashval_t typename_hash PARAMS ((const void *)); ! static int typename_compare PARAMS ((const void *, const void *)); ! static void push_binding PARAMS ((tree, tree, struct cp_binding_level*)); static int add_binding PARAMS ((tree, tree)); static void pop_binding PARAMS ((tree, tree)); static tree local_variable_p_walkfn PARAMS ((tree *, int *, void *)); ! static cxx_binding *find_binding (tree, tree, cxx_binding *); ! static tree select_decl (cxx_binding *, int); static int lookup_flags PARAMS ((int, int)); static tree qualify_lookup PARAMS ((tree, int)); static tree record_builtin_java_type PARAMS ((const char *, int)); static const char *tag_name PARAMS ((enum tag_types code)); static void find_class_binding_level PARAMS ((void)); ! static struct cp_binding_level *innermost_nonclass_level PARAMS ((void)); static void warn_about_implicit_typename_lookup PARAMS ((tree, tree)); static int walk_namespaces_r PARAMS ((tree, walk_namespaces_fn, void *)); static int walk_globals_r PARAMS ((tree, void *)); ! static int walk_vtables_r PARAMS ((tree, void*)); ! static void add_decl_to_level PARAMS ((tree, struct cp_binding_level *)); static tree make_label_decl PARAMS ((tree, int)); static void use_label PARAMS ((tree)); ! static void check_previous_goto_1 PARAMS ((tree, struct cp_binding_level *, tree, const char *, int)); static void check_previous_goto PARAMS ((struct named_label_use_list *)); ! static void check_switch_goto PARAMS ((struct cp_binding_level *)); static void check_previous_gotos PARAMS ((tree)); static void pop_label PARAMS ((tree, tree)); static void pop_labels PARAMS ((tree)); static void maybe_deduce_size_from_array_init PARAMS ((tree, tree)); static void layout_var_decl PARAMS ((tree)); static void maybe_commonize_var PARAMS ((tree)); ! static tree check_initializer (tree, tree, int); static void make_rtl_for_nonlocal_decl PARAMS ((tree, tree, const char *)); static void save_function_data PARAMS ((tree)); static void check_function_type PARAMS ((tree, tree)); static void begin_constructor_body PARAMS ((void)); static void finish_constructor_body PARAMS ((void)); static void begin_destructor_body PARAMS ((void)); *************** static tree push_cp_library_fn PARAMS (( *** 150,157 **** static tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree)); static void store_parm_decls PARAMS ((tree)); static int cp_missing_noreturn_ok_p PARAMS ((tree)); ! #if defined (DEBUG_CP_BINDING_LEVELS) static void indent PARAMS ((void)); #endif --- 143,154 ---- static tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree)); static void store_parm_decls PARAMS ((tree)); static int cp_missing_noreturn_ok_p PARAMS ((tree)); + static void initialize_local_var (tree, tree); + static void expand_static_init (tree, tree); + static tree next_initializable_field (tree); + static tree reshape_init (tree, tree *); ! #if defined (DEBUG_BINDING_LEVELS) static void indent PARAMS ((void)); #endif *************** tree cp_global_trees[CPTI_MAX]; *** 208,224 **** /* Indicates that there is a type value in some namespace, although that is not necessarily in scope at the moment. */ ! static tree global_type_node; ! /* Expect only namespace names now. */ static int only_namespace_names; /* Used only for jumps to as-yet undefined labels, since jumps to defined labels can have their validity checked immediately. */ ! struct named_label_use_list { ! struct binding_level *binding_level; tree names_in_scope; tree label_decl; const char *filename_o_goto; --- 205,221 ---- /* Indicates that there is a type value in some namespace, although that is not necessarily in scope at the moment. */ ! static GTY(()) tree global_type_node; ! /* Expect only namespace names now. */ static int only_namespace_names; /* Used only for jumps to as-yet undefined labels, since jumps to defined labels can have their validity checked immediately. */ ! struct named_label_use_list GTY(()) { ! struct cp_binding_level *binding_level; tree names_in_scope; tree label_decl; const char *filename_o_goto; *************** tree last_function_parms; *** 249,257 **** we can clear out their names' definitions at the end of the function, and so we can check the validity of jumps to these labels. */ ! struct named_label_list { ! struct binding_level *binding_level; tree names_in_scope; tree old_value; tree label_decl; --- 246,254 ---- we can clear out their names' definitions at the end of the function, and so we can check the validity of jumps to these labels. */ ! struct named_label_list GTY(()) { ! struct cp_binding_level *binding_level; tree names_in_scope; tree old_value; tree label_decl; *************** struct named_label_list *** 262,297 **** }; #define named_labels cp_function_chain->x_named_labels - - /* Nonzero means use the ISO C94 dialect of C. */ - - int flag_isoc94; - - /* Nonzero means use the ISO C99 dialect of C. */ - - int flag_isoc99; - - /* Nonzero means we are a hosted implementation for code shared with C. */ - - int flag_hosted = 1; - - /* Nonzero means add default format_arg attributes for functions not - in ISO C. */ - - int flag_noniso_default_format_attributes = 1; - - /* Nonzero if we want to conserve space in the .o files. We do this - by putting uninitialized data and runtime initialized data into - .common instead of .data at the expense of not flagging multiple - definitions. */ - extern int flag_conserve_space; - /* C and C++ flags are in decl2.c. */ - - /* A expression of value 0 with the same precision as a sizetype - node, but signed. */ - tree signed_size_zero_node; - /* The name of the anonymous namespace, throughout this translation unit. */ tree anonymous_namespace_name; --- 259,265 ---- *************** static enum deprecated_states deprecated *** 317,322 **** --- 285,295 ---- being flagged as deprecated or reported as using deprecated types. */ int adding_implicit_members = 0; + + /* True if a declaration with an `extern' linkage specifier is being + processed. */ + bool have_extern_spec; + /* For each binding contour we allocate a binding_level structure which records the names defined in that contour. *************** int adding_implicit_members = 0; *** 342,348 **** /* Note that the information in the `names' component of the global contour is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */ ! struct binding_level { /* A chain of _DECL nodes for all variables, constants, functions, and typedef types. These are in the reverse of the order --- 315,321 ---- /* Note that the information in the `names' component of the global contour is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */ ! struct cp_binding_level GTY(()) { /* A chain of _DECL nodes for all variables, constants, functions, and typedef types. These are in the reverse of the order *************** struct binding_level *** 350,355 **** --- 323,340 ---- are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */ tree names; + /* Count of elements in names chain. */ + size_t names_size; + + /* A chain of NAMESPACE_DECL nodes. */ + tree namespaces; + + /* An array of static functions and variables (for namespaces only) */ + varray_type static_decls; + + /* A chain of VTABLE_DECL nodes. */ + tree vtables; + /* A list of structure, union and enum definitions, for looking up tag names. It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name, *************** struct binding_level *** 360,370 **** component_bindings. */ tree tags; ! /* A list of USING_DECL nodes. */ tree usings; /* A list of used namespaces. PURPOSE is the namespace, ! VALUE the common ancestor with this binding_level's namespace. */ tree using_directives; /* If this binding level is the binding level for a class, then --- 345,355 ---- component_bindings. */ tree tags; ! /* A list of USING_DECL nodes. */ tree usings; /* A list of used namespaces. PURPOSE is the namespace, ! VALUE the common ancestor with this binding_level's namespace. */ tree using_directives; /* If this binding level is the binding level for a class, then *************** struct binding_level *** 392,398 **** tree this_class; /* The binding level which this one is contained in (inherits from). */ ! struct binding_level *level_chain; /* List of VAR_DECLS saved from a previous for statement. These would be dead in ISO-conforming code, but might --- 377,383 ---- tree this_class; /* The binding level which this one is contained in (inherits from). */ ! struct cp_binding_level *level_chain; /* List of VAR_DECLS saved from a previous for statement. These would be dead in ISO-conforming code, but might *************** struct binding_level *** 443,455 **** /* Three bits left for this word. */ - #if defined(DEBUG_CP_BINDING_LEVELS) /* Binding depth at which this level began. */ unsigned binding_depth; - #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ }; ! #define NULL_BINDING_LEVEL ((struct binding_level *) NULL) /* The binding level currently in effect. */ --- 428,438 ---- /* Three bits left for this word. */ /* Binding depth at which this level began. */ unsigned binding_depth; }; ! #define NULL_BINDING_LEVEL ((struct cp_binding_level *) NULL) /* The binding level currently in effect. */ *************** struct binding_level *** 464,476 **** /* A chain of binding_level structures awaiting reuse. */ ! static struct binding_level *free_binding_level; /* The outermost binding level, for names of file scope. This is created when the compiler is started and exists through the entire run. */ ! static struct binding_level *global_binding_level; /* Nonzero means unconditionally make a BLOCK for the next level pushed. */ --- 447,459 ---- /* A chain of binding_level structures awaiting reuse. */ ! static GTY((deletable (""))) struct cp_binding_level *free_binding_level; /* The outermost binding level, for names of file scope. This is created when the compiler is started and exists through the entire run. */ ! static GTY(()) struct cp_binding_level *global_binding_level; /* Nonzero means unconditionally make a BLOCK for the next level pushed. */ *************** static int keep_next_level_flag; *** 480,488 **** UNION_TYPE; the TREE_VALUE is a VAR_DECL with that type. At the time the VAR_DECL was declared, the type was incomplete. */ ! static tree incomplete_vars; ! #if defined(DEBUG_CP_BINDING_LEVELS) static int binding_depth = 0; static int is_class_level = 0; --- 463,471 ---- UNION_TYPE; the TREE_VALUE is a VAR_DECL with that type. At the time the VAR_DECL was declared, the type was incomplete. */ ! static GTY(()) tree incomplete_vars; ! #if defined(DEBUG_BINDING_LEVELS) static int binding_depth = 0; static int is_class_level = 0; *************** indent () *** 494,525 **** for (i = 0; i < binding_depth*2; i++) putc (' ', stderr); } ! #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ ! static tree pushdecl_with_scope PARAMS ((tree, struct binding_level *)); static void push_binding_level (newlevel, tag_transparent, keep) ! struct binding_level *newlevel; int tag_transparent, keep; { /* Add this level to the front of the chain (stack) of levels that are active. */ ! memset ((char*) newlevel, 0, sizeof (struct binding_level)); newlevel->level_chain = current_binding_level; current_binding_level = newlevel; newlevel->tag_transparent = tag_transparent; newlevel->more_cleanups_ok = 1; newlevel->keep = keep; ! #if defined(DEBUG_CP_BINDING_LEVELS) newlevel->binding_depth = binding_depth; indent (); fprintf (stderr, "push %s level 0x%08x line %d\n", (is_class_level) ? "class" : "block", newlevel, lineno); is_class_level = 0; binding_depth++; ! #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ } /* Find the innermost enclosing class scope, and reset --- 477,508 ---- for (i = 0; i < binding_depth*2; i++) putc (' ', stderr); } ! #endif /* defined(DEBUG_BINDING_LEVELS) */ ! static tree pushdecl_with_scope PARAMS ((tree, struct cp_binding_level *)); static void push_binding_level (newlevel, tag_transparent, keep) ! struct cp_binding_level *newlevel; int tag_transparent, keep; { /* Add this level to the front of the chain (stack) of levels that are active. */ ! memset ((char*) newlevel, 0, sizeof (struct cp_binding_level)); newlevel->level_chain = current_binding_level; current_binding_level = newlevel; newlevel->tag_transparent = tag_transparent; newlevel->more_cleanups_ok = 1; newlevel->keep = keep; ! #if defined(DEBUG_BINDING_LEVELS) newlevel->binding_depth = binding_depth; indent (); fprintf (stderr, "push %s level 0x%08x line %d\n", (is_class_level) ? "class" : "block", newlevel, lineno); is_class_level = 0; binding_depth++; ! #endif /* defined(DEBUG_BINDING_LEVELS) */ } /* Find the innermost enclosing class scope, and reset *************** push_binding_level (newlevel, tag_transp *** 528,534 **** static void find_class_binding_level () { ! struct binding_level *level = current_binding_level; while (level && level->parm_flag != 2) level = level->level_chain; --- 511,517 ---- static void find_class_binding_level () { ! struct cp_binding_level *level = current_binding_level; while (level && level->parm_flag != 2) level = level->level_chain; *************** pop_binding_level () *** 548,554 **** abort (); } /* Pop the current level, and free the structure for reuse. */ ! #if defined(DEBUG_CP_BINDING_LEVELS) binding_depth--; indent (); fprintf (stderr, "pop %s level 0x%08x line %d\n", --- 531,537 ---- abort (); } /* Pop the current level, and free the structure for reuse. */ ! #if defined(DEBUG_BINDING_LEVELS) binding_depth--; indent (); fprintf (stderr, "pop %s level 0x%08x line %d\n", *************** pop_binding_level () *** 560,574 **** fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n"); } is_class_level = 0; ! #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ { ! register struct binding_level *level = current_binding_level; current_binding_level = current_binding_level->level_chain; level->level_chain = free_binding_level; ! #if 0 /* defined(DEBUG_CP_BINDING_LEVELS) */ if (level->binding_depth != binding_depth) abort (); ! #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ free_binding_level = level; find_class_binding_level (); } --- 543,557 ---- fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n"); } is_class_level = 0; ! #endif /* defined(DEBUG_BINDING_LEVELS) */ { ! register struct cp_binding_level *level = current_binding_level; current_binding_level = current_binding_level->level_chain; level->level_chain = free_binding_level; ! #if 0 /* defined(DEBUG_BINDING_LEVELS) */ if (level->binding_depth != binding_depth) abort (); ! #endif /* defined(DEBUG_BINDING_LEVELS) */ free_binding_level = level; find_class_binding_level (); } *************** suspend_binding_level () *** 587,593 **** abort (); } /* Suspend the current level. */ ! #if defined(DEBUG_CP_BINDING_LEVELS) binding_depth--; indent (); fprintf (stderr, "suspend %s level 0x%08x line %d\n", --- 570,576 ---- abort (); } /* Suspend the current level. */ ! #if defined(DEBUG_BINDING_LEVELS) binding_depth--; indent (); fprintf (stderr, "suspend %s level 0x%08x line %d\n", *************** suspend_binding_level () *** 599,637 **** fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n"); } is_class_level = 0; ! #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ current_binding_level = current_binding_level->level_chain; find_class_binding_level (); } static void resume_binding_level (b) ! struct binding_level *b; { /* Resuming binding levels is meant only for namespaces, ! and those cannot nest into classes. */ my_friendly_assert(!class_binding_level, 386); /* Also, resuming a non-directly nested namespace is a no-no. */ my_friendly_assert(b->level_chain == current_binding_level, 386); current_binding_level = b; ! #if defined(DEBUG_CP_BINDING_LEVELS) b->binding_depth = binding_depth; indent (); fprintf (stderr, "resume %s level 0x%08x line %d\n", (is_class_level) ? "class" : "block", b, lineno); is_class_level = 0; binding_depth++; ! #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ } ! /* Create a new `struct binding_level'. */ static ! struct binding_level * make_binding_level () { /* NOSTRICT */ ! return (struct binding_level *) xmalloc (sizeof (struct binding_level)); } /* Nonzero if we are currently in the global binding level. */ --- 582,620 ---- fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n"); } is_class_level = 0; ! #endif /* defined(DEBUG_BINDING_LEVELS) */ current_binding_level = current_binding_level->level_chain; find_class_binding_level (); } static void resume_binding_level (b) ! struct cp_binding_level *b; { /* Resuming binding levels is meant only for namespaces, ! and those cannot nest into classes. */ my_friendly_assert(!class_binding_level, 386); /* Also, resuming a non-directly nested namespace is a no-no. */ my_friendly_assert(b->level_chain == current_binding_level, 386); current_binding_level = b; ! #if defined(DEBUG_BINDING_LEVELS) b->binding_depth = binding_depth; indent (); fprintf (stderr, "resume %s level 0x%08x line %d\n", (is_class_level) ? "class" : "block", b, lineno); is_class_level = 0; binding_depth++; ! #endif /* defined(DEBUG_BINDING_LEVELS) */ } ! /* Create a new `struct cp_binding_level'. */ static ! struct cp_binding_level * make_binding_level () { /* NOSTRICT */ ! return (struct cp_binding_level *) ggc_alloc (sizeof (struct cp_binding_level)); } /* Nonzero if we are currently in the global binding level. */ *************** global_bindings_p () *** 644,653 **** /* Return the innermost binding level that is not for a class scope. */ ! static struct binding_level * innermost_nonclass_level () { ! struct binding_level *b; b = current_binding_level; while (b->parm_flag == 2) --- 627,636 ---- /* Return the innermost binding level that is not for a class scope. */ ! static struct cp_binding_level * innermost_nonclass_level () { ! struct cp_binding_level *b; b = current_binding_level; while (b->parm_flag == 2) *************** innermost_nonclass_level () *** 665,671 **** int toplevel_bindings_p () { ! struct binding_level *b = innermost_nonclass_level (); return b->namespace_p || b->template_parms_p; } --- 648,654 ---- int toplevel_bindings_p () { ! struct cp_binding_level *b = innermost_nonclass_level (); return b->namespace_p || b->template_parms_p; } *************** toplevel_bindings_p () *** 677,688 **** int namespace_bindings_p () { ! struct binding_level *b = innermost_nonclass_level (); return b->namespace_p; } ! /* If KEEP is non-zero, make a BLOCK node for the next binding level, unconditionally. Otherwise, use the normal logic to decide whether or not to create a BLOCK. */ --- 660,671 ---- int namespace_bindings_p () { ! struct cp_binding_level *b = innermost_nonclass_level (); return b->namespace_p; } ! /* If KEEP is nonzero, make a BLOCK node for the next binding level, unconditionally. Otherwise, use the normal logic to decide whether or not to create a BLOCK. */ *************** declare_namespace_level () *** 711,717 **** current_binding_level->namespace_p = 1; } ! /* Returns non-zero if this scope was created to store template parameters. */ int --- 694,700 ---- current_binding_level->namespace_p = 1; } ! /* Returns nonzero if this scope was created to store template parameters. */ int *************** current_tmpl_spec_kind (n_class_scopes) *** 731,737 **** int n_template_parm_scopes = 0; int seen_specialization_p = 0; int innermost_specialization_p = 0; ! struct binding_level *b; /* Scan through the template parameter scopes. */ for (b = current_binding_level; b->template_parms_p; b = b->level_chain) --- 714,720 ---- int n_template_parm_scopes = 0; int seen_specialization_p = 0; int innermost_specialization_p = 0; ! struct cp_binding_level *b; /* Scan through the template parameter scopes. */ for (b = current_binding_level; b->template_parms_p; b = b->level_chain) *************** current_tmpl_spec_kind (n_class_scopes) *** 742,748 **** template template <> ... ! which is always illegal since [temp.expl.spec] forbids the specialization of a class member template if the enclosing class templates are not explicitly specialized as well. */ if (b->template_spec_p) --- 725,731 ---- template template <> ... ! which is always invalid since [temp.expl.spec] forbids the specialization of a class member template if the enclosing class templates are not explicitly specialized as well. */ if (b->template_spec_p) *************** current_tmpl_spec_kind (n_class_scopes) *** 779,785 **** template void R::S::f(int); ! This is illegal; there needs to be one set of template parameters for each class. */ return tsk_insufficient_parms; else if (n_template_parm_scopes == n_class_scopes) --- 762,768 ---- template void R::S::f(int); ! This is invalid; there needs to be one set of template parameters for each class. */ return tsk_insufficient_parms; else if (n_template_parm_scopes == n_class_scopes) *************** void *** 824,840 **** pushlevel (tag_transparent) int tag_transparent; { ! struct binding_level *newlevel; if (cfun && !doing_semantic_analysis_p ()) return; /* Reuse or create a struct for this binding level. */ ! #if defined(DEBUG_CP_BINDING_LEVELS) if (0) ! #else /* !defined(DEBUG_CP_BINDING_LEVELS) */ if (free_binding_level) ! #endif /* !defined(DEBUG_CP_BINDING_LEVELS) */ { newlevel = free_binding_level; free_binding_level = free_binding_level->level_chain; --- 807,823 ---- pushlevel (tag_transparent) int tag_transparent; { ! struct cp_binding_level *newlevel; if (cfun && !doing_semantic_analysis_p ()) return; /* Reuse or create a struct for this binding level. */ ! #if defined(DEBUG_BINDING_LEVELS) if (0) ! #else /* !defined(DEBUG_BINDING_LEVELS) */ if (free_binding_level) ! #endif /* !defined(DEBUG_BINDING_LEVELS) */ { newlevel = free_binding_level; free_binding_level = free_binding_level->level_chain; *************** note_level_for_catch () *** 919,932 **** } /* For a binding between a name and an entity at a block scope, ! this is the `struct binding_level' for the block. */ ! #define BINDING_LEVEL(NODE) \ ! (((struct tree_binding*)(NODE))->scope.level) ! /* A free list of CPLUS_BINDING nodes, connected by their ! TREE_CHAINs. */ ! static tree free_bindings; /* Make DECL the innermost binding for ID. The LEVEL is the binding level at which this declaration is being bound. */ --- 902,913 ---- } /* For a binding between a name and an entity at a block scope, ! this is the `struct cp_binding_level' for the block. */ ! #define BINDING_LEVEL(NODE) ((NODE)->scope.level) ! /* A free list of "cxx_binding"s, connected by their PREVIOUS. */ ! static GTY((deletable (""))) cxx_binding *free_bindings; /* Make DECL the innermost binding for ID. The LEVEL is the binding level at which this declaration is being bound. */ *************** static void *** 935,951 **** push_binding (id, decl, level) tree id; tree decl; ! struct binding_level* level; { ! tree binding; if (free_bindings) { binding = free_bindings; ! free_bindings = TREE_CHAIN (binding); } else ! binding = make_node (CPLUS_BINDING); /* Now, fill in the binding information. */ BINDING_VALUE (binding) = decl; --- 916,932 ---- push_binding (id, decl, level) tree id; tree decl; ! struct cp_binding_level* level; { ! cxx_binding *binding; if (free_bindings) { binding = free_bindings; ! free_bindings = binding->previous; } else ! binding = cxx_binding_make (); /* Now, fill in the binding information. */ BINDING_VALUE (binding) = decl; *************** push_binding (id, decl, level) *** 956,962 **** BINDING_HAS_LEVEL_P (binding) = 1; /* And put it on the front of the list of bindings for ID. */ ! TREE_CHAIN (binding) = IDENTIFIER_BINDING (id); IDENTIFIER_BINDING (id) = binding; } --- 937,943 ---- BINDING_HAS_LEVEL_P (binding) = 1; /* And put it on the front of the list of bindings for ID. */ ! binding->previous = IDENTIFIER_BINDING (id); IDENTIFIER_BINDING (id) = binding; } *************** push_binding (id, decl, level) *** 965,979 **** stat' hack whereby a non-typedef class-name or enum-name can be bound at the same level as some other kind of entity. It's the responsibility of the caller to check that inserting this name is ! legal here. Returns nonzero if the new binding was successful. */ static int add_binding (id, decl) tree id; tree decl; { ! tree binding = IDENTIFIER_BINDING (id); int ok = 1; if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)) /* The new name is the type name. */ BINDING_TYPE (binding) = decl; --- 946,961 ---- stat' hack whereby a non-typedef class-name or enum-name can be bound at the same level as some other kind of entity. It's the responsibility of the caller to check that inserting this name is ! valid here. Returns nonzero if the new binding was successful. */ static int add_binding (id, decl) tree id; tree decl; { ! cxx_binding *binding = IDENTIFIER_BINDING (id); int ok = 1; + timevar_push (TV_NAME_LOOKUP); if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)) /* The new name is the type name. */ BINDING_TYPE (binding) = decl; *************** add_binding (id, decl) *** 1030,1036 **** ok = 0; } ! return ok; } /* Add DECL to the list of things declared in B. */ --- 1012,1018 ---- ok = 0; } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok); } /* Add DECL to the list of things declared in B. */ *************** add_binding (id, decl) *** 1038,1049 **** static void add_decl_to_level (decl, b) tree decl; ! struct binding_level *b; { ! /* We build up the list in reverse order, and reverse it later if ! necessary. */ ! TREE_CHAIN (decl) = b->names; ! b->names = decl; } /* Bind DECL to ID in the current_binding_level, assumed to be a local --- 1020,1053 ---- static void add_decl_to_level (decl, b) tree decl; ! struct cp_binding_level *b; { ! if (TREE_CODE (decl) == NAMESPACE_DECL ! && !DECL_NAMESPACE_ALIAS (decl)) ! { ! TREE_CHAIN (decl) = b->namespaces; ! b->namespaces = decl; ! } ! else if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl)) ! { ! TREE_CHAIN (decl) = b->vtables; ! b->vtables = decl; ! } ! else ! { ! /* We build up the list in reverse order, and reverse it later if ! necessary. */ ! TREE_CHAIN (decl) = b->names; ! b->names = decl; ! b->names_size++; ! ! /* If appropriate, add decl to separate list of statics */ ! if (b->namespace_p) ! if ((TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)) ! || (TREE_CODE (decl) == FUNCTION_DECL ! && (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl)))) ! VARRAY_PUSH_TREE (b->static_decls, decl); ! } } /* Bind DECL to ID in the current_binding_level, assumed to be a local *************** push_local_binding (id, decl, flags) *** 1057,1063 **** tree decl; int flags; { ! struct binding_level *b; /* Skip over any local classes. This makes sense if we call push_local_binding with a friend decl of a local class. */ --- 1061,1067 ---- tree decl; int flags; { ! struct cp_binding_level *b; /* Skip over any local classes. This makes sense if we call push_local_binding with a friend decl of a local class. */ *************** push_class_binding (id, decl) *** 1098,1108 **** tree decl; { int result = 1; ! tree binding = IDENTIFIER_BINDING (id); tree context; /* Note that we declared this value so that we can issue an error if ! this an illegal redeclaration of a name already used for some other purpose. */ note_name_declared_in_class (id, decl); --- 1102,1113 ---- tree decl; { int result = 1; ! cxx_binding *binding = IDENTIFIER_BINDING (id); tree context; + timevar_push (TV_NAME_LOOKUP); /* Note that we declared this value so that we can issue an error if ! this is an invalid redeclaration of a name already used for some other purpose. */ note_name_declared_in_class (id, decl); *************** push_class_binding (id, decl) *** 1152,1158 **** in this class. */ INHERITED_VALUE_BINDING_P (binding) = 1; ! return result; } /* Remove the binding for DECL which should be the innermost binding --- 1157,1163 ---- in this class. */ INHERITED_VALUE_BINDING_P (binding) = 1; ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result); } /* Remove the binding for DECL which should be the innermost binding *************** pop_binding (id, decl) *** 1163,1169 **** tree id; tree decl; { ! tree binding; if (id == NULL_TREE) /* It's easiest to write the loops that call this function without --- 1168,1174 ---- tree id; tree decl; { ! cxx_binding *binding; if (id == NULL_TREE) /* It's easiest to write the loops that call this function without *************** pop_binding (id, decl) *** 1175,1181 **** binding = IDENTIFIER_BINDING (id); /* The name should be bound. */ ! my_friendly_assert (binding != NULL_TREE, 0); /* The DECL will be either the ordinary binding or the type binding for this identifier. Remove that binding. */ --- 1180,1186 ---- binding = IDENTIFIER_BINDING (id); /* The name should be bound. */ ! my_friendly_assert (binding != NULL, 0); /* The DECL will be either the ordinary binding or the type binding for this identifier. Remove that binding. */ *************** pop_binding (id, decl) *** 1190,1199 **** { /* We're completely done with the innermost binding for this identifier. Unhook it from the list of bindings. */ ! IDENTIFIER_BINDING (id) = TREE_CHAIN (binding); /* Add it to the free list. */ ! TREE_CHAIN (binding) = free_bindings; free_bindings = binding; /* Clear the BINDING_LEVEL so the garbage collector doesn't walk --- 1195,1204 ---- { /* We're completely done with the innermost binding for this identifier. Unhook it from the list of bindings. */ ! IDENTIFIER_BINDING (id) = binding->previous; /* Add it to the free list. */ ! binding->previous = free_bindings; free_bindings = binding; /* Clear the BINDING_LEVEL so the garbage collector doesn't walk *************** poplevel (keep, reverse, functionbody) *** 1282,1289 **** tree decl; int leaving_for_scope; if (cfun && !doing_semantic_analysis_p ()) ! return NULL_TREE; my_friendly_assert (current_binding_level->parm_flag != 2, 19990916); --- 1287,1296 ---- tree decl; int leaving_for_scope; + timevar_push (TV_NAME_LOOKUP); + if (cfun && !doing_semantic_analysis_p ()) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); my_friendly_assert (current_binding_level->parm_flag != 2, 19990916); *************** poplevel (keep, reverse, functionbody) *** 1308,1314 **** under constraints of next binding contour. */ if (cfun && !functionbody) { ! struct binding_level *level_chain; level_chain = current_binding_level->level_chain; if (level_chain) { --- 1315,1321 ---- under constraints of next binding contour. */ if (cfun && !functionbody) { ! struct cp_binding_level *level_chain; level_chain = current_binding_level->level_chain; if (level_chain) { *************** poplevel (keep, reverse, functionbody) *** 1410,1417 **** if (leaving_for_scope && TREE_CODE (link) == VAR_DECL && DECL_NAME (link)) { ! tree outer_binding ! = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (link))); tree ns_binding; if (!outer_binding) --- 1417,1424 ---- if (leaving_for_scope && TREE_CODE (link) == VAR_DECL && DECL_NAME (link)) { ! cxx_binding *outer_binding ! = IDENTIFIER_BINDING (DECL_NAME (link))->previous; tree ns_binding; if (!outer_binding) *************** poplevel (keep, reverse, functionbody) *** 1466,1472 **** current_binding_level->level_chain-> dead_vars_from_for); ! /* Although we don't pop the CPLUS_BINDING, we do clear its BINDING_LEVEL since the level is going away now. */ BINDING_LEVEL (IDENTIFIER_BINDING (DECL_NAME (link))) = 0; --- 1473,1479 ---- current_binding_level->level_chain-> dead_vars_from_for); ! /* Although we don't pop the cxx_binding, we do clear its BINDING_LEVEL since the level is going away now. */ BINDING_LEVEL (IDENTIFIER_BINDING (DECL_NAME (link))) = 0; *************** poplevel (keep, reverse, functionbody) *** 1574,1580 **** block = poplevel (keep, reverse, functionbody); } ! return block; } /* Delete the node BLOCK from the current binding level. --- 1581,1587 ---- block = poplevel (keep, reverse, functionbody); } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, block); } /* Delete the node BLOCK from the current binding level. *************** set_block (block) *** 1631,1644 **** void pushlevel_class () { ! register struct binding_level *newlevel; /* Reuse or create a struct for this binding level. */ ! #if defined(DEBUG_CP_BINDING_LEVELS) if (0) ! #else /* !defined(DEBUG_CP_BINDING_LEVELS) */ if (free_binding_level) ! #endif /* !defined(DEBUG_CP_BINDING_LEVELS) */ { newlevel = free_binding_level; free_binding_level = free_binding_level->level_chain; --- 1638,1651 ---- void pushlevel_class () { ! register struct cp_binding_level *newlevel; /* Reuse or create a struct for this binding level. */ ! #if defined(DEBUG_BINDING_LEVELS) if (0) ! #else /* !defined(DEBUG_BINDING_LEVELS) */ if (free_binding_level) ! #endif /* !defined(DEBUG_BINDING_LEVELS) */ { newlevel = free_binding_level; free_binding_level = free_binding_level->level_chain; *************** pushlevel_class () *** 1646,1654 **** else newlevel = make_binding_level (); ! #if defined(DEBUG_CP_BINDING_LEVELS) is_class_level = 1; ! #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ push_binding_level (newlevel, 0, 0); --- 1653,1661 ---- else newlevel = make_binding_level (); ! #if defined(DEBUG_BINDING_LEVELS) is_class_level = 1; ! #endif /* defined(DEBUG_BINDING_LEVELS) */ push_binding_level (newlevel, 0, 0); *************** pushlevel_class () *** 1662,1670 **** void poplevel_class () { ! register struct binding_level *level = class_binding_level; tree shadowed; my_friendly_assert (level != 0, 354); /* If we're leaving a toplevel class, don't bother to do the setting --- 1669,1679 ---- void poplevel_class () { ! register struct cp_binding_level *level = class_binding_level; tree shadowed; + timevar_push (TV_NAME_LOOKUP); + my_friendly_assert (level != 0, 354); /* If we're leaving a toplevel class, don't bother to do the setting *************** poplevel_class () *** 1674,1680 **** next time we're entering a class scope, it is the same class. */ if (current_class_depth != 1) { ! struct binding_level* b; /* Clear out our IDENTIFIER_CLASS_VALUEs. */ for (shadowed = level->class_shadowed; --- 1683,1689 ---- next time we're entering a class scope, it is the same class. */ if (current_class_depth != 1) { ! struct cp_binding_level* b; /* Clear out our IDENTIFIER_CLASS_VALUEs. */ for (shadowed = level->class_shadowed; *************** poplevel_class () *** 1693,1707 **** shadowed; shadowed = TREE_CHAIN (shadowed)) { ! tree t; ! t = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed)); ! while (t && BINDING_LEVEL (t) != b) ! t = TREE_CHAIN (t); ! if (t) IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) ! = BINDING_VALUE (t); } } else --- 1702,1716 ---- shadowed; shadowed = TREE_CHAIN (shadowed)) { ! cxx_binding *binding; ! binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed)); ! while (binding && BINDING_LEVEL (binding) != b) ! binding = binding->previous; ! if (binding) IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) ! = BINDING_VALUE (binding); } } else *************** poplevel_class () *** 1724,1734 **** /* Now, pop out of the binding level which we created up in the `pushlevel_class' routine. */ ! #if defined(DEBUG_CP_BINDING_LEVELS) is_class_level = 1; ! #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ pop_binding_level (); } /* We are entering the scope of a class. Clear IDENTIFIER_CLASS_VALUE --- 1733,1745 ---- /* Now, pop out of the binding level which we created up in the `pushlevel_class' routine. */ ! #if defined(DEBUG_BINDING_LEVELS) is_class_level = 1; ! #endif /* defined(DEBUG_BINDING_LEVELS) */ pop_binding_level (); + + timevar_pop (TV_NAME_LOOKUP); } /* We are entering the scope of a class. Clear IDENTIFIER_CLASS_VALUE *************** clear_identifier_class_values () *** 1748,1754 **** IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE; } ! /* Returns non-zero if T is a virtual function table. */ int vtable_decl_p (t, data) --- 1759,1765 ---- IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE; } ! /* Returns nonzero if T is a virtual function table. */ int vtable_decl_p (t, data) *************** vtable_decl_p (t, data) *** 1758,1764 **** return (TREE_CODE (t) == VAR_DECL && DECL_VIRTUAL_P (t)); } ! /* Returns non-zero if T is a TYPE_DECL for a type with virtual functions. */ int --- 1769,1775 ---- return (TREE_CODE (t) == VAR_DECL && DECL_VIRTUAL_P (t)); } ! /* Returns nonzero if T is a TYPE_DECL for a type with virtual functions. */ int *************** cp_namespace_decls (ns) *** 1780,1785 **** --- 1791,1840 ---- return NAMESPACE_LEVEL (ns)->names; } + struct walk_globals_data { + walk_globals_pred p; + walk_globals_fn f; + void *data; + }; + + /* Walk the vtable declarations in NAMESPACE. Whenever one is found + for which P returns nonzero, call F with its address. If any call + to F returns a nonzero value, return a nonzero value. */ + + static int + walk_vtables_r (namespace, data) + tree namespace; + void *data; + { + struct walk_globals_data* wgd = (struct walk_globals_data *) data; + walk_globals_fn f = wgd->f; + void *d = wgd->data; + tree decl = NAMESPACE_LEVEL (namespace)->vtables; + int result = 0; + + for (; decl ; decl = TREE_CHAIN (decl)) + result |= (*f) (&decl, d); + + return result; + } + + /* Walk the vtable declarations. Whenever one is found for which P + returns nonzero, call F with its address. If any call to F + returns a nonzero value, return a nonzero value. */ + int + walk_vtables (p, f, data) + walk_globals_pred p; + walk_globals_fn f; + void *data; + { + struct walk_globals_data wgd; + wgd.p = p; + wgd.f = f; + wgd.data = data; + + return walk_namespaces (walk_vtables_r, &wgd); + } + /* Walk all the namespaces contained NAMESPACE, including NAMESPACE itself, calling F for each. The DATA is passed to F as well. */ *************** walk_namespaces_r (namespace, f, data) *** 1789,1810 **** walk_namespaces_fn f; void *data; { - tree current; int result = 0; result |= (*f) (namespace, data); ! for (current = cp_namespace_decls (namespace); ! current; ! current = TREE_CHAIN (current)) ! { ! if (TREE_CODE (current) != NAMESPACE_DECL ! || DECL_NAMESPACE_ALIAS (current)) ! continue; ! ! /* We found a namespace. */ ! result |= walk_namespaces_r (current, f, data); ! } return result; } --- 1844,1856 ---- walk_namespaces_fn f; void *data; { int result = 0; + tree current = NAMESPACE_LEVEL (namespace)->namespaces; result |= (*f) (namespace, data); ! for (; current; current = TREE_CHAIN (current)) ! result |= walk_namespaces_r (current, f, data); return result; } *************** walk_namespaces (f, data) *** 1820,1834 **** return walk_namespaces_r (global_namespace, f, data); } - struct walk_globals_data { - walk_globals_pred p; - walk_globals_fn f; - void *data; - }; - /* Walk the global declarations in NAMESPACE. Whenever one is found ! for which P returns non-zero, call F with its address. If any call ! to F returns a non-zero value, return a non-zero value. */ static int walk_globals_r (namespace, data) --- 1866,1874 ---- return walk_namespaces_r (global_namespace, f, data); } /* Walk the global declarations in NAMESPACE. Whenever one is found ! for which P returns nonzero, call F with its address. If any call ! to F returns a nonzero value, return a nonzero value. */ static int walk_globals_r (namespace, data) *************** walk_globals_r (namespace, data) *** 1861,1868 **** } /* Walk the global declarations. Whenever one is found for which P ! returns non-zero, call F with its address. If any call to F ! returns a non-zero value, return a non-zero value. */ int walk_globals (p, f, data) --- 1901,1908 ---- } /* Walk the global declarations. Whenever one is found for which P ! returns nonzero, call F with its address. If any call to F ! returns a nonzero value, return a nonzero value. */ int walk_globals (p, f, data) *************** wrapup_globals_for_namespace (namespace, *** 1887,1984 **** tree namespace; void *data; { ! tree globals = cp_namespace_decls (namespace); ! int len = list_length (globals); ! tree *vec = (tree *) alloca (sizeof (tree) * len); ! int i; ! int result; ! tree decl; int last_time = (data != 0); - if (last_time && namespace == global_namespace) - /* Let compile_file handle the global namespace. */ - return 0; - - /* Process the decls in reverse order--earliest first. - Put them into VEC from back to front, then take out from front. */ - for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl)) - vec[len - i - 1] = decl; - if (last_time) { check_global_declarations (vec, len); return 0; } - /* Temporarily mark vtables as external. That prevents - wrapup_global_declarations from writing them out; we must process - them ourselves in finish_vtable_vardecl. */ - for (i = 0; i < len; ++i) - if (vtable_decl_p (vec[i], /*data=*/0) && !DECL_EXTERNAL (vec[i])) - { - DECL_NOT_REALLY_EXTERN (vec[i]) = 1; - DECL_EXTERNAL (vec[i]) = 1; - } - /* Write out any globals that need to be output. */ ! result = wrapup_global_declarations (vec, len); ! ! /* Undo the hack to DECL_EXTERNAL above. */ ! for (i = 0; i < len; ++i) ! if (vtable_decl_p (vec[i], /*data=*/0) ! && DECL_NOT_REALLY_EXTERN (vec[i])) ! { ! DECL_NOT_REALLY_EXTERN (vec[i]) = 0; ! DECL_EXTERNAL (vec[i]) = 0; ! } ! ! return result; ! } ! ! ! /* Mark ARG (which is really a struct binding_level **) for GC. */ ! ! static void ! mark_binding_level (arg) ! void *arg; ! { ! struct binding_level *lvl = *(struct binding_level **)arg; ! ! for (; lvl; lvl = lvl->level_chain) ! { ! ggc_mark_tree (lvl->names); ! ggc_mark_tree (lvl->tags); ! ggc_mark_tree (lvl->usings); ! ggc_mark_tree (lvl->using_directives); ! ggc_mark_tree (lvl->class_shadowed); ! ggc_mark_tree (lvl->type_shadowed); ! ggc_mark_tree (lvl->shadowed_labels); ! ggc_mark_tree (lvl->blocks); ! ggc_mark_tree (lvl->this_class); ! ggc_mark_tree (lvl->dead_vars_from_for); ! } } - static void - mark_named_label_lists (labs, uses) - void *labs; - void *uses; - { - struct named_label_list *l = *(struct named_label_list **)labs; - struct named_label_use_list *u = *(struct named_label_use_list **)uses; - - for (; l; l = l->next) - { - ggc_mark (l); - mark_binding_level (&l->binding_level); - ggc_mark_tree (l->old_value); - ggc_mark_tree (l->label_decl); - ggc_mark_tree (l->bad_decls); - } - - for (; u; u = u->next) - ggc_mark (u); - } /* For debugging. */ static int no_print_functions = 0; --- 1927,1948 ---- tree namespace; void *data; { ! struct cp_binding_level *level = NAMESPACE_LEVEL (namespace); ! varray_type statics = level->static_decls; ! tree *vec = &VARRAY_TREE (statics, 0); ! int len = VARRAY_ACTIVE_SIZE (statics); int last_time = (data != 0); if (last_time) { check_global_declarations (vec, len); return 0; } /* Write out any globals that need to be output. */ ! return wrapup_global_declarations (vec, len); } /* For debugging. */ static int no_print_functions = 0; *************** static int no_print_builtins = 0; *** 1986,1992 **** void print_binding_level (lvl) ! struct binding_level *lvl; { tree t; int i = 0, len; --- 1950,1956 ---- void print_binding_level (lvl) ! struct cp_binding_level *lvl; { tree t; int i = 0, len; *************** print_binding_level (lvl) *** 2087,2095 **** void print_other_binding_stack (stack) ! struct binding_level *stack; { ! struct binding_level *level; for (level = stack; level != global_binding_level; level = level->level_chain) { fprintf (stderr, "binding level "); --- 2051,2059 ---- void print_other_binding_stack (stack) ! struct cp_binding_level *stack; { ! struct cp_binding_level *level; for (level = stack; level != global_binding_level; level = level->level_chain) { fprintf (stderr, "binding level "); *************** print_other_binding_stack (stack) *** 2102,2108 **** void print_binding_stack () { ! struct binding_level *b; fprintf (stderr, "current_binding_level="); fprintf (stderr, HOST_PTR_PRINTF, current_binding_level); fprintf (stderr, "\nclass_binding_level="); --- 2066,2072 ---- void print_binding_stack () { ! struct cp_binding_level *b; fprintf (stderr, "current_binding_level="); fprintf (stderr, HOST_PTR_PRINTF, current_binding_level); fprintf (stderr, "\nclass_binding_level="); *************** print_binding_stack () *** 2127,2227 **** print_binding_level (global_binding_level); } ! /* Namespace binding access routines: The namespace_bindings field of ! the identifier is polymorphic, with three possible values: ! NULL_TREE, a list of CPLUS_BINDINGS, or any other tree_node ! indicating the BINDING_VALUE of global_namespace. */ /* Check whether the a binding for the name to scope is known. ! Assumes that the bindings of the name are already a list ! of bindings. Returns the binding found, or NULL_TREE. */ ! static tree ! find_binding (name, scope) ! tree name; ! tree scope; { ! tree iter, prev = NULL_TREE; ! scope = ORIGINAL_NAMESPACE (scope); ! for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name); iter; ! iter = TREE_CHAIN (iter)) { - my_friendly_assert (TREE_CODE (iter) == CPLUS_BINDING, 374); if (BINDING_SCOPE (iter) == scope) { /* Move binding found to the front of the list, so ! subsequent lookups will find it faster. */ if (prev) { ! TREE_CHAIN (prev) = TREE_CHAIN (iter); ! TREE_CHAIN (iter) = IDENTIFIER_NAMESPACE_BINDINGS (name); IDENTIFIER_NAMESPACE_BINDINGS (name) = iter; } ! return iter; } prev = iter; } ! return NULL_TREE; } ! /* Always returns a binding for name in scope. If the ! namespace_bindings is not a list, convert it to one first. ! If no binding is found, make a new one. */ ! tree ! binding_for_name (name, scope) ! tree name; ! tree scope; { ! tree b = IDENTIFIER_NAMESPACE_BINDINGS (name); ! tree result; scope = ORIGINAL_NAMESPACE (scope); ! ! if (b && TREE_CODE (b) != CPLUS_BINDING) ! { ! /* Get rid of optimization for global scope. */ ! IDENTIFIER_NAMESPACE_BINDINGS (name) = NULL_TREE; ! BINDING_VALUE (binding_for_name (name, global_namespace)) = b; ! b = IDENTIFIER_NAMESPACE_BINDINGS (name); ! } ! if (b && (result = find_binding (name, scope))) return result; ! /* Not found, make a new one. */ ! result = make_node (CPLUS_BINDING); ! TREE_CHAIN (result) = b; ! IDENTIFIER_NAMESPACE_BINDINGS (name) = result; ! BINDING_SCOPE (result) = scope; BINDING_TYPE (result) = NULL_TREE; BINDING_VALUE (result) = NULL_TREE; return result; } ! /* Return the binding value for name in scope, considering that ! namespace_binding may or may not be a list of CPLUS_BINDINGS. */ tree ! namespace_binding (name, scope) ! tree name; ! tree scope; { ! tree b = IDENTIFIER_NAMESPACE_BINDINGS (name); ! if (b == NULL_TREE) ! return NULL_TREE; ! if (scope == NULL_TREE) ! scope = global_namespace; ! if (TREE_CODE (b) != CPLUS_BINDING) ! return (scope == global_namespace) ? b : NULL_TREE; ! name = find_binding (name,scope); ! if (name == NULL_TREE) ! return name; ! return BINDING_VALUE (name); } ! /* Set the binding value for name in scope. If modifying the binding ! of global_namespace is attempted, try to optimize it. */ void set_namespace_binding (name, scope, val) --- 2091,2182 ---- print_binding_level (global_binding_level); } ! /* Namespace binding access routines. */ /* Check whether the a binding for the name to scope is known. ! Returns the binding found, or NULL. */ ! static inline cxx_binding * ! find_binding (tree name, tree scope, cxx_binding *front) { ! cxx_binding *iter; ! cxx_binding *prev = NULL; ! timevar_push (TV_NAME_LOOKUP); ! for (iter = front; iter; iter = iter->previous) { if (BINDING_SCOPE (iter) == scope) { /* Move binding found to the front of the list, so ! subsequent lookups will find it faster. */ if (prev) { ! prev->previous = iter->previous; ! iter->previous = front; IDENTIFIER_NAMESPACE_BINDINGS (name) = iter; } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, iter); } prev = iter; } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL); } ! /* Return the binding for NAME in SCOPE, if any. Otherwise, return NULL. */ ! cxx_binding * ! cxx_scope_find_binding_for_name (tree scope, tree name) ! { ! cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name); ! if (b) ! { ! scope = ORIGINAL_NAMESPACE (scope); ! /* Fold-in case where NAME is used only once. */ ! if (scope == BINDING_SCOPE (b) && b->previous == NULL) ! return b; ! return find_binding (name, scope, b); ! } ! return b; ! } ! ! /* Always returns a binding for name in scope. ! If no binding is found, make a new one. */ ! ! cxx_binding * ! binding_for_name (tree name, tree scope) { ! cxx_binding *result; scope = ORIGINAL_NAMESPACE (scope); ! result = cxx_scope_find_binding_for_name (scope, name); ! if (result) return result; ! /* Not found, make a new one. */ ! result = cxx_binding_make (); ! result->previous = IDENTIFIER_NAMESPACE_BINDINGS (name); BINDING_TYPE (result) = NULL_TREE; BINDING_VALUE (result) = NULL_TREE; + BINDING_SCOPE (result) = scope; + result->is_local = false; + result->value_is_inherited = false; + result->has_level = false; + IDENTIFIER_NAMESPACE_BINDINGS (name) = result; return result; } ! /* Return the binding value for name in scope. */ tree ! namespace_binding (tree name, tree scope) { ! cxx_binding *b = ! cxx_scope_find_binding_for_name (scope ? scope : global_namespace, name); ! ! return b ? b->value : NULL_TREE; } ! /* Set the binding value for name in scope. */ void set_namespace_binding (name, scope, val) *************** set_namespace_binding (name, scope, val) *** 2229,2250 **** tree scope; tree val; { ! tree b; if (scope == NULL_TREE) scope = global_namespace; - if (scope == global_namespace) - { - b = IDENTIFIER_NAMESPACE_BINDINGS (name); - if (b == NULL_TREE || TREE_CODE (b) != CPLUS_BINDING) - { - IDENTIFIER_NAMESPACE_BINDINGS (name) = val; - return; - } - } b = binding_for_name (name, scope); BINDING_VALUE (b) = val; } /* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we --- 2184,2198 ---- tree scope; tree val; { ! cxx_binding *b; + timevar_push (TV_NAME_LOOKUP); if (scope == NULL_TREE) scope = global_namespace; b = binding_for_name (name, scope); BINDING_VALUE (b) = val; + timevar_pop (TV_NAME_LOOKUP); } /* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we *************** push_namespace (name) *** 2258,2266 **** int need_new = 1; int implicit_use = 0; int global = 0; if (!global_namespace) { ! /* This must be ::. */ my_friendly_assert (name == get_identifier ("::"), 377); global = 1; } --- 2206,2217 ---- int need_new = 1; int implicit_use = 0; int global = 0; + + timevar_push (TV_NAME_LOOKUP); + if (!global_namespace) { ! /* This must be ::. */ my_friendly_assert (name == get_identifier ("::"), 377); global = 1; } *************** push_namespace (name) *** 2279,2285 **** } else { ! /* Check whether this is an extended namespace definition. */ d = IDENTIFIER_NAMESPACE_VALUE (name); if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL) { --- 2230,2236 ---- } else { ! /* Check whether this is an extended namespace definition. */ d = IDENTIFIER_NAMESPACE_VALUE (name); if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL) { *************** push_namespace (name) *** 2295,2301 **** if (need_new) { ! /* Make a new namespace, binding the name to it. */ d = build_lang_decl (NAMESPACE_DECL, name, void_type_node); /* The global namespace is not pushed, and the global binding level is set elsewhere. */ --- 2246,2252 ---- if (need_new) { ! /* Make a new namespace, binding the name to it. */ d = build_lang_decl (NAMESPACE_DECL, name, void_type_node); /* The global namespace is not pushed, and the global binding level is set elsewhere. */ *************** push_namespace (name) *** 2306,2311 **** --- 2257,2265 ---- pushlevel (0); declare_namespace_level (); NAMESPACE_LEVEL (d) = current_binding_level; + VARRAY_TREE_INIT (current_binding_level->static_decls, + name != std_identifier ? 10 : 200, + "Static declarations"); } } else *************** push_namespace (name) *** 2313,2320 **** if (implicit_use) do_using_directive (d); ! /* Enter the name space. */ current_namespace = d; } /* Pop from the scope of the current namespace. */ --- 2267,2276 ---- if (implicit_use) do_using_directive (d); ! /* Enter the name space. */ current_namespace = d; + + timevar_pop (TV_NAME_LOOKUP); } /* Pop from the scope of the current namespace. */ *************** void *** 2351,2356 **** --- 2307,2313 ---- pop_nested_namespace (ns) tree ns; { + timevar_push (TV_NAME_LOOKUP); while (ns != global_namespace) { pop_namespace (); *************** pop_nested_namespace (ns) *** 2358,2366 **** --- 2315,2340 ---- } pop_from_top_level (); + timevar_pop (TV_NAME_LOOKUP); } + /* Allocate storage for saving a C++ binding. */ + #define cxx_saved_binding_make() \ + (ggc_alloc (sizeof (cxx_saved_binding))) + + struct cxx_saved_binding GTY(()) + { + /* Link that chains saved C++ bindings for a given name into a stack. */ + cxx_saved_binding *previous; + /* The name of the current binding. */ + tree identifier; + /* The binding we're saving. */ + cxx_binding *binding; + tree class_value; + tree real_type_value; + }; + /* Subroutines for reverting temporarily to top-level for instantiation of templates and such. We actually need to clear out the class- and local-value slots of all identifiers, so that only the global values *************** pop_nested_namespace (ns) *** 2368,2415 **** scope isn't enough, because more binding levels may be pushed. */ struct saved_scope *scope_chain; ! /* Mark ARG (which is really a struct saved_scope **) for GC. */ ! ! static void ! mark_saved_scope (arg) ! void *arg; ! { ! struct saved_scope *t = *(struct saved_scope **)arg; ! while (t) ! { ! mark_binding_level (&t->class_bindings); ! ggc_mark_tree (t->old_bindings); ! ggc_mark_tree (t->old_namespace); ! ggc_mark_tree (t->decl_ns_list); ! ggc_mark_tree (t->class_name); ! ggc_mark_tree (t->class_type); ! ggc_mark_tree (t->access_specifier); ! ggc_mark_tree (t->function_decl); ! if (t->lang_base) ! ggc_mark_tree_varray (t->lang_base); ! ggc_mark_tree (t->lang_name); ! ggc_mark_tree (t->template_parms); ! ggc_mark_tree (t->x_previous_class_type); ! ggc_mark_tree (t->x_previous_class_values); ! ggc_mark_tree (t->x_saved_tree); ! ggc_mark_tree (t->lookups); ! ! mark_stmt_tree (&t->x_stmt_tree); ! mark_binding_level (&t->bindings); ! t = t->prev; ! } ! } ! ! static tree ! store_bindings (names, old_bindings) ! tree names, old_bindings; { tree t; ! tree search_bindings = old_bindings; for (t = names; t; t = TREE_CHAIN (t)) { ! tree binding, t1, id; if (TREE_CODE (t) == TREE_LIST) id = TREE_PURPOSE (t); --- 2342,2359 ---- scope isn't enough, because more binding levels may be pushed. */ struct saved_scope *scope_chain; ! static cxx_saved_binding * ! store_bindings (tree names, cxx_saved_binding *old_bindings) { tree t; ! cxx_saved_binding *search_bindings = old_bindings; + timevar_push (TV_NAME_LOOKUP); for (t = names; t; t = TREE_CHAIN (t)) { ! tree id; ! cxx_saved_binding *saved; ! cxx_saved_binding *t1; if (TREE_CODE (t) == TREE_LIST) id = TREE_PURPOSE (t); *************** store_bindings (names, old_bindings) *** 2423,2446 **** || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id))) continue; ! for (t1 = search_bindings; t1; t1 = TREE_CHAIN (t1)) ! if (TREE_VEC_ELT (t1, 0) == id) goto skip_it; my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135); ! binding = make_tree_vec (4); ! TREE_VEC_ELT (binding, 0) = id; ! TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id); ! TREE_VEC_ELT (binding, 2) = IDENTIFIER_BINDING (id); ! TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id); ! IDENTIFIER_BINDING (id) = NULL_TREE; IDENTIFIER_CLASS_VALUE (id) = NULL_TREE; ! TREE_CHAIN (binding) = old_bindings; ! old_bindings = binding; skip_it: ; } ! return old_bindings; } void --- 2367,2390 ---- || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id))) continue; ! for (t1 = search_bindings; t1; t1 = t1->previous) ! if (t1->identifier == id) goto skip_it; my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135); ! saved = cxx_saved_binding_make (); ! saved->previous = old_bindings; ! saved->identifier = id; ! saved->binding = IDENTIFIER_BINDING (id); ! saved->class_value = IDENTIFIER_CLASS_VALUE (id);; ! saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id); ! IDENTIFIER_BINDING (id) = NULL; IDENTIFIER_CLASS_VALUE (id) = NULL_TREE; ! old_bindings = saved; skip_it: ; } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings); } void *************** maybe_push_to_top_level (pseudo) *** 2448,2458 **** int pseudo; { struct saved_scope *s; ! struct binding_level *b; ! tree old_bindings; int need_pop; ! s = (struct saved_scope *) xcalloc (1, sizeof (struct saved_scope)); b = scope_chain ? current_binding_level : 0; --- 2392,2404 ---- int pseudo; { struct saved_scope *s; ! struct cp_binding_level *b; ! cxx_saved_binding *old_bindings; int need_pop; ! timevar_push (TV_NAME_LOOKUP); ! ! s = (struct saved_scope *) ggc_alloc_cleared (sizeof (struct saved_scope)); b = scope_chain ? current_binding_level : 0; *************** maybe_push_to_top_level (pseudo) *** 2465,2471 **** else need_pop = 0; ! old_bindings = NULL_TREE; if (scope_chain && previous_class_type) old_bindings = store_bindings (previous_class_values, old_bindings); --- 2411,2417 ---- else need_pop = 0; ! old_bindings = NULL; if (scope_chain && previous_class_type) old_bindings = store_bindings (previous_class_values, old_bindings); *************** maybe_push_to_top_level (pseudo) *** 2504,2509 **** --- 2450,2456 ---- VARRAY_TREE_INIT (current_lang_base, 10, "current_lang_base"); current_lang_name = lang_name_cplusplus; current_namespace = global_namespace; + timevar_pop (TV_NAME_LOOKUP); } void *************** void *** 2516,2537 **** pop_from_top_level () { struct saved_scope *s = scope_chain; ! tree t; /* Clear out class-level bindings cache. */ if (previous_class_type) invalidate_class_lookup_cache (); ! VARRAY_FREE (current_lang_base); scope_chain = s->prev; ! for (t = s->old_bindings; t; t = TREE_CHAIN (t)) { ! tree id = TREE_VEC_ELT (t, 0); ! SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1)); ! IDENTIFIER_BINDING (id) = TREE_VEC_ELT (t, 2); ! IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3); } /* If we were in the middle of compiling a function, restore our --- 2463,2486 ---- pop_from_top_level () { struct saved_scope *s = scope_chain; ! cxx_saved_binding *saved; ! ! timevar_push (TV_NAME_LOOKUP); /* Clear out class-level bindings cache. */ if (previous_class_type) invalidate_class_lookup_cache (); ! current_lang_base = 0; scope_chain = s->prev; ! for (saved = s->old_bindings; saved; saved = saved->previous) { ! tree id = saved->identifier; ! IDENTIFIER_BINDING (id) = saved->binding; ! IDENTIFIER_CLASS_VALUE (id) = saved->class_value; ! SET_IDENTIFIER_TYPE_VALUE (id, saved->real_type_value); } /* If we were in the middle of compiling a function, restore our *************** pop_from_top_level () *** 2541,2547 **** current_function_decl = s->function_decl; last_function_parms = s->last_parms; ! free (s); } /* Push a definition of struct, union or enum tag "name". --- 2490,2496 ---- current_function_decl = s->function_decl; last_function_parms = s->last_parms; ! timevar_pop (TV_NAME_LOOKUP); } /* Push a definition of struct, union or enum tag "name". *************** static void *** 2561,2581 **** set_identifier_type_value_with_scope (id, type, b) tree id; tree type; ! struct binding_level *b; { if (!b->namespace_p) { /* Shadow the marker, not the real thing, so that the marker ! gets restored later. */ tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id); b->type_shadowed = tree_cons (id, old_type_value, b->type_shadowed); } else { ! tree binding = binding_for_name (id, current_namespace); BINDING_TYPE (binding) = type; ! /* Store marker instead of real type. */ type = global_type_node; } SET_IDENTIFIER_TYPE_VALUE (id, type); --- 2510,2530 ---- set_identifier_type_value_with_scope (id, type, b) tree id; tree type; ! struct cp_binding_level *b; { if (!b->namespace_p) { /* Shadow the marker, not the real thing, so that the marker ! gets restored later. */ tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id); b->type_shadowed = tree_cons (id, old_type_value, b->type_shadowed); } else { ! cxx_binding *binding = binding_for_name (id, current_namespace); BINDING_TYPE (binding) = type; ! /* Store marker instead of real type. */ type = global_type_node; } SET_IDENTIFIER_TYPE_VALUE (id, type); *************** set_identifier_type_value (id, type) *** 2591,2614 **** set_identifier_type_value_with_scope (id, type, current_binding_level); } ! /* Return the type associated with id. */ tree identifier_type_value (id) tree id; { ! /* There is no type with that name, anywhere. */ if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE) ! return NULL_TREE; ! /* This is not the type marker, but the real thing. */ if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node) ! return REAL_IDENTIFIER_TYPE_VALUE (id); /* Have to search for it. It must be on the global level, now. ! Ask lookup_name not to return non-types. */ id = lookup_name_real (id, 2, 1, 0); if (id) ! return TREE_TYPE (id); ! return NULL_TREE; } /* Pop off extraneous binding levels left over due to syntax errors. --- 2540,2564 ---- set_identifier_type_value_with_scope (id, type, current_binding_level); } ! /* Return the type associated with id. */ tree identifier_type_value (id) tree id; { ! timevar_push (TV_NAME_LOOKUP); ! /* There is no type with that name, anywhere. */ if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); ! /* This is not the type marker, but the real thing. */ if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, REAL_IDENTIFIER_TYPE_VALUE (id)); /* Have to search for it. It must be on the global level, now. ! Ask lookup_name not to return non-types. */ id = lookup_name_real (id, 2, 1, 0); if (id) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_TYPE (id)); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); } /* Pop off extraneous binding levels left over due to syntax errors. *************** identifier_type_value (id) *** 2618,2624 **** void pop_everything () { ! #ifdef DEBUG_CP_BINDING_LEVELS fprintf (stderr, "XXX entering pop_everything ()\n"); #endif while (!toplevel_bindings_p ()) --- 2568,2574 ---- void pop_everything () { ! #ifdef DEBUG_BINDING_LEVELS fprintf (stderr, "XXX entering pop_everything ()\n"); #endif while (!toplevel_bindings_p ()) *************** pop_everything () *** 2628,2641 **** else poplevel (0, 0, 0); } ! #ifdef DEBUG_CP_BINDING_LEVELS fprintf (stderr, "XXX leaving pop_everything ()\n"); #endif } /* The type TYPE is being declared. If it is a class template, or a specialization of a class template, do any processing required and ! perform error-checking. If IS_FRIEND is non-zero, this TYPE is being declared a friend. B is the binding level at which this TYPE should be bound. --- 2578,2591 ---- else poplevel (0, 0, 0); } ! #ifdef DEBUG_BINDING_LEVELS fprintf (stderr, "XXX leaving pop_everything ()\n"); #endif } /* The type TYPE is being declared. If it is a class template, or a specialization of a class template, do any processing required and ! perform error-checking. If IS_FRIEND is nonzero, this TYPE is being declared a friend. B is the binding level at which this TYPE should be bound. *************** static tree *** 2646,2652 **** maybe_process_template_type_declaration (type, globalize, b) tree type; int globalize; ! struct binding_level* b; { tree decl = TYPE_NAME (type); --- 2596,2602 ---- maybe_process_template_type_declaration (type, globalize, b) tree type; int globalize; ! struct cp_binding_level* b; { tree decl = TYPE_NAME (type); *************** maybe_process_template_type_declaration *** 2691,2697 **** b->level_chain->tags = tree_cons (name, type, b->level_chain->tags); if (!COMPLETE_TYPE_P (current_class_type)) ! CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags; } } } --- 2641,2651 ---- b->level_chain->tags = tree_cons (name, type, b->level_chain->tags); if (!COMPLETE_TYPE_P (current_class_type)) ! { ! maybe_add_class_template_decl_list (current_class_type, ! type, /*friend_p=*/0); ! CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags; ! } } } } *************** push_local_name (decl) *** 2731,2736 **** --- 2685,2692 ---- size_t i, nelts; tree t, name; + timevar_push (TV_NAME_LOOKUP); + if (!local_names) VARRAY_TREE_INIT (local_names, 8, "local_names"); *************** push_local_name (decl) *** 2744,2760 **** { if (!DECL_LANG_SPECIFIC (decl)) retrofit_lang_decl (decl); if (DECL_LANG_SPECIFIC (t)) DECL_DISCRIMINATOR (decl) = DECL_DISCRIMINATOR (t) + 1; else DECL_DISCRIMINATOR (decl) = 1; VARRAY_TREE (local_names, i) = decl; ! return; } } VARRAY_PUSH_TREE (local_names, decl); } /* Push a tag name NAME for struct/class/union/enum type TYPE. --- 2700,2718 ---- { if (!DECL_LANG_SPECIFIC (decl)) retrofit_lang_decl (decl); + DECL_LANG_SPECIFIC (decl)->decl_flags.u2sel = 1; if (DECL_LANG_SPECIFIC (t)) DECL_DISCRIMINATOR (decl) = DECL_DISCRIMINATOR (t) + 1; else DECL_DISCRIMINATOR (decl) = 1; VARRAY_TREE (local_names, i) = decl; ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0); } } VARRAY_PUSH_TREE (local_names, decl); + timevar_pop (TV_NAME_LOOKUP); } /* Push a tag name NAME for struct/class/union/enum type TYPE. *************** pushtag (name, type, globalize) *** 2767,2773 **** tree name, type; int globalize; { ! register struct binding_level *b; b = current_binding_level; while (b->tag_transparent --- 2725,2733 ---- tree name, type; int globalize; { ! register struct cp_binding_level *b; ! ! timevar_push (TV_NAME_LOOKUP); b = current_binding_level; while (b->tag_transparent *************** pushtag (name, type, globalize) *** 2776,2782 **** /* We may be defining a new type in the initializer of a static member variable. We allow this when not pedantic, and it is particularly useful for ! type punning via an anonymous union. */ || COMPLETE_TYPE_P (b->this_class)))) b = b->level_chain; --- 2736,2742 ---- /* We may be defining a new type in the initializer of a static member variable. We allow this when not pedantic, and it is particularly useful for ! type punning via an anonymous union. */ || COMPLETE_TYPE_P (b->this_class)))) b = b->level_chain; *************** pushtag (name, type, globalize) *** 2854,2860 **** if (b->parm_flag == 2) { if (!COMPLETE_TYPE_P (current_class_type)) ! CLASSTYPE_TAGS (current_class_type) = b->tags; } } --- 2814,2824 ---- if (b->parm_flag == 2) { if (!COMPLETE_TYPE_P (current_class_type)) ! { ! maybe_add_class_template_decl_list (current_class_type, ! type, /*friend_p=*/0); ! CLASSTYPE_TAGS (current_class_type) = b->tags; ! } } } *************** pushtag (name, type, globalize) *** 2874,2879 **** --- 2838,2845 ---- tree d = build_decl (TYPE_DECL, NULL_TREE, type); TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b); } + + timevar_pop (TV_NAME_LOOKUP); } /* Counter used to create anonymous type names. */ *************** make_anon_name () *** 2898,2904 **** void clear_anon_tags () { ! register struct binding_level *b; register tree tags; static int last_cnt = 0; --- 2864,2870 ---- void clear_anon_tags () { ! register struct cp_binding_level *b; register tree tags; static int last_cnt = 0; *************** duplicate_decls (newdecl, olddecl) *** 3135,3141 **** } } ! /* Check for redeclaration and other discrepancies. */ if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_ARTIFICIAL (olddecl)) { --- 3101,3107 ---- } } ! /* Check for redeclaration and other discrepancies. */ if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_ARTIFICIAL (olddecl)) { *************** duplicate_decls (newdecl, olddecl) *** 3200,3205 **** --- 3166,3175 ---- /* Replace the old RTL to avoid problems with inlining. */ SET_DECL_RTL (olddecl, DECL_RTL (newdecl)); } + /* Even if the types match, prefer the new declarations type + for anitipated built-ins, for exception lists, etc... */ + else if (DECL_ANTICIPATED (olddecl)) + TREE_TYPE (olddecl) = TREE_TYPE (newdecl); if (DECL_THIS_STATIC (newdecl) && !DECL_THIS_STATIC (olddecl)) { *************** duplicate_decls (newdecl, olddecl) *** 3275,3281 **** && compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))), TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl)))) && comp_template_parms (DECL_TEMPLATE_PARMS (newdecl), ! DECL_TEMPLATE_PARMS (olddecl))) { error ("new declaration `%#D'", newdecl); cp_error_at ("ambiguates old declaration `%#D'", olddecl); --- 3245,3255 ---- && compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))), TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl)))) && comp_template_parms (DECL_TEMPLATE_PARMS (newdecl), ! DECL_TEMPLATE_PARMS (olddecl)) ! /* Template functions can be disambiguated by ! return type. */ ! && same_type_p (TREE_TYPE (TREE_TYPE (newdecl)), ! TREE_TYPE (TREE_TYPE (olddecl)))) { error ("new declaration `%#D'", newdecl); cp_error_at ("ambiguates old declaration `%#D'", olddecl); *************** duplicate_decls (newdecl, olddecl) *** 3323,3329 **** specialization, and the other is an instantiation of the same template, that we do not exit at this point. That situation can occur if we instantiate a template class, and then ! specialize one of its methods. This situation is legal, but the declarations must be merged in the usual way. */ return 0; else if (TREE_CODE (newdecl) == FUNCTION_DECL --- 3297,3303 ---- specialization, and the other is an instantiation of the same template, that we do not exit at this point. That situation can occur if we instantiate a template class, and then ! specialize one of its methods. This situation is valid, but the declarations must be merged in the usual way. */ return 0; else if (TREE_CODE (newdecl) == FUNCTION_DECL *************** duplicate_decls (newdecl, olddecl) *** 3337,3343 **** else if (TREE_CODE (newdecl) == NAMESPACE_DECL && DECL_NAMESPACE_ALIAS (newdecl) && DECL_NAMESPACE_ALIAS (newdecl) == DECL_NAMESPACE_ALIAS (olddecl)) ! /* Redeclaration of namespace alias, ignore it. */ return 1; else { --- 3311,3317 ---- else if (TREE_CODE (newdecl) == NAMESPACE_DECL && DECL_NAMESPACE_ALIAS (newdecl) && DECL_NAMESPACE_ALIAS (newdecl) == DECL_NAMESPACE_ALIAS (olddecl)) ! /* Redeclaration of namespace alias, ignore it. */ return 1; else { *************** duplicate_decls (newdecl, olddecl) *** 3447,3458 **** definition. */ if (DECL_VINDEX (olddecl)) DECL_VINDEX (newdecl) = DECL_VINDEX (olddecl); - if (DECL_VIRTUAL_CONTEXT (olddecl)) - DECL_VIRTUAL_CONTEXT (newdecl) = DECL_VIRTUAL_CONTEXT (olddecl); if (DECL_CONTEXT (olddecl)) DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl); - if (DECL_PENDING_INLINE_INFO (newdecl) == 0) - DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl); DECL_STATIC_CONSTRUCTOR (newdecl) |= DECL_STATIC_CONSTRUCTOR (olddecl); DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl); DECL_PURE_VIRTUAL_P (newdecl) |= DECL_PURE_VIRTUAL_P (olddecl); --- 3421,3428 ---- *************** duplicate_decls (newdecl, olddecl) *** 3469,3477 **** definition. */ if (warn_redundant_decls && ! DECL_ARTIFICIAL (olddecl) && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE) ! /* Don't warn about extern decl followed by definition. */ && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)) ! /* Don't warn about friends, let add_friend take care of it. */ && ! (DECL_FRIEND_P (newdecl) || DECL_FRIEND_P (olddecl))) { warning ("redundant redeclaration of `%D' in same scope", newdecl); --- 3439,3447 ---- definition. */ if (warn_redundant_decls && ! DECL_ARTIFICIAL (olddecl) && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE) ! /* Don't warn about extern decl followed by definition. */ && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)) ! /* Don't warn about friends, let add_friend take care of it. */ && ! (DECL_FRIEND_P (newdecl) || DECL_FRIEND_P (olddecl))) { warning ("redundant redeclaration of `%D' in same scope", newdecl); *************** duplicate_decls (newdecl, olddecl) *** 3487,3498 **** if (newtype != error_mark_node && oldtype != error_mark_node && TYPE_LANG_SPECIFIC (newtype) && TYPE_LANG_SPECIFIC (oldtype)) ! { ! CLASSTYPE_VSIZE (newtype) = CLASSTYPE_VSIZE (oldtype); ! CLASSTYPE_FRIEND_CLASSES (newtype) ! = CLASSTYPE_FRIEND_CLASSES (oldtype); ! } ! DECL_ORIGINAL_TYPE (newdecl) = DECL_ORIGINAL_TYPE (olddecl); } --- 3457,3465 ---- if (newtype != error_mark_node && oldtype != error_mark_node && TYPE_LANG_SPECIFIC (newtype) && TYPE_LANG_SPECIFIC (oldtype)) ! CLASSTYPE_FRIEND_CLASSES (newtype) ! = CLASSTYPE_FRIEND_CLASSES (oldtype); ! \ DECL_ORIGINAL_TYPE (newdecl) = DECL_ORIGINAL_TYPE (olddecl); } *************** duplicate_decls (newdecl, olddecl) *** 3513,3524 **** if (DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)) == NULL_TREE && DECL_INITIAL (DECL_TEMPLATE_RESULT (newdecl)) != NULL_TREE) { ! DECL_SOURCE_LINE (olddecl) ! = DECL_SOURCE_LINE (DECL_TEMPLATE_RESULT (olddecl)) ! = DECL_SOURCE_LINE (newdecl); ! DECL_SOURCE_FILE (olddecl) ! = DECL_SOURCE_FILE (DECL_TEMPLATE_RESULT (olddecl)) ! = DECL_SOURCE_FILE (newdecl); } return 1; --- 3480,3488 ---- if (DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)) == NULL_TREE && DECL_INITIAL (DECL_TEMPLATE_RESULT (newdecl)) != NULL_TREE) { ! DECL_SOURCE_LOCATION (olddecl) ! = DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (olddecl)) ! = DECL_SOURCE_LOCATION (newdecl); } return 1; *************** duplicate_decls (newdecl, olddecl) *** 3539,3545 **** newtype = oldtype; if (TREE_CODE (newdecl) == VAR_DECL) ! DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl); /* Do this after calling `merge_types' so that default parameters don't confuse us. */ else if (TREE_CODE (newdecl) == FUNCTION_DECL --- 3503,3513 ---- newtype = oldtype; if (TREE_CODE (newdecl) == VAR_DECL) ! { ! DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl); ! DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl); ! } ! /* Do this after calling `merge_types' so that default parameters don't confuse us. */ else if (TREE_CODE (newdecl) == FUNCTION_DECL *************** duplicate_decls (newdecl, olddecl) *** 3589,3596 **** && DECL_INITIAL (olddecl) != NULL_TREE) { DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); ! DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl); ! DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl); if (CAN_HAVE_FULL_LANG_DECL_P (newdecl) && DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl)) --- 3557,3563 ---- && DECL_INITIAL (olddecl) != NULL_TREE) { DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); ! DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl); if (CAN_HAVE_FULL_LANG_DECL_P (newdecl) && DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl)) *************** duplicate_decls (newdecl, olddecl) *** 3658,3664 **** /* Don't really know how much of the language-specific values we should copy from old to new. */ DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl); ! DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl); DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl); DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl); DECL_INITIALIZED_IN_CLASS_P (newdecl) --- 3625,3632 ---- /* Don't really know how much of the language-specific values we should copy from old to new. */ DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl); ! DECL_LANG_SPECIFIC (newdecl)->decl_flags.u2 = ! DECL_LANG_SPECIFIC (olddecl)->decl_flags.u2; DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl); DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl); DECL_INITIALIZED_IN_CLASS_P (newdecl) *************** duplicate_decls (newdecl, olddecl) *** 3668,3676 **** /* Only functions have DECL_BEFRIENDING_CLASSES. */ if (TREE_CODE (newdecl) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (newdecl)) ! DECL_BEFRIENDING_CLASSES (newdecl) ! = chainon (DECL_BEFRIENDING_CLASSES (newdecl), ! DECL_BEFRIENDING_CLASSES (olddecl)); } if (TREE_CODE (newdecl) == FUNCTION_DECL) --- 3636,3650 ---- /* Only functions have DECL_BEFRIENDING_CLASSES. */ if (TREE_CODE (newdecl) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (newdecl)) ! { ! DECL_BEFRIENDING_CLASSES (newdecl) ! = chainon (DECL_BEFRIENDING_CLASSES (newdecl), ! DECL_BEFRIENDING_CLASSES (olddecl)); ! /* DECL_THUNKS is only valid for virtual functions, ! otherwise it is a DECL_FRIEND_CONTEXT. */ ! if (DECL_VIRTUAL_P (newdecl)) ! DECL_THUNKS (newdecl) = DECL_THUNKS (olddecl); ! } } if (TREE_CODE (newdecl) == FUNCTION_DECL) *************** duplicate_decls (newdecl, olddecl) *** 3697,3713 **** olddecl); SET_DECL_TEMPLATE_SPECIALIZATION (olddecl); } ! DECL_DECLARED_INLINE_P (newdecl) |= DECL_DECLARED_INLINE_P (olddecl); ! /* If either decl says `inline', this fn is inline, unless its ! definition was passed already. */ ! if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == NULL_TREE) ! DECL_INLINE (olddecl) = 1; ! DECL_INLINE (newdecl) = DECL_INLINE (olddecl); ! DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl) ! = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl)); /* Preserve abstractness on cloned [cd]tors. */ DECL_ABSTRACT (newdecl) = DECL_ABSTRACT (olddecl); --- 3671,3696 ---- olddecl); SET_DECL_TEMPLATE_SPECIALIZATION (olddecl); + + /* [temp.expl.spec/14] We don't inline explicit specialization + just because the primary template says so. */ } ! else ! { ! if (DECL_PENDING_INLINE_INFO (newdecl) == 0) ! DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl); ! DECL_DECLARED_INLINE_P (newdecl) |= DECL_DECLARED_INLINE_P (olddecl); ! /* If either decl says `inline', this fn is inline, unless ! its definition was passed already. */ ! if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == NULL_TREE) ! DECL_INLINE (olddecl) = 1; ! DECL_INLINE (newdecl) = DECL_INLINE (olddecl); ! ! DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl) ! = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl)); ! } /* Preserve abstractness on cloned [cd]tors. */ DECL_ABSTRACT (newdecl) = DECL_ABSTRACT (olddecl); *************** duplicate_decls (newdecl, olddecl) *** 3807,3813 **** memcpy ((char *) olddecl + sizeof (struct tree_common), (char *) newdecl + sizeof (struct tree_common), sizeof (struct tree_decl) - sizeof (struct tree_common) ! + tree_code_length [(int)TREE_CODE (newdecl)] * sizeof (char *)); } DECL_UID (olddecl) = olddecl_uid; --- 3790,3796 ---- memcpy ((char *) olddecl + sizeof (struct tree_common), (char *) newdecl + sizeof (struct tree_common), sizeof (struct tree_decl) - sizeof (struct tree_common) ! + TREE_CODE_LENGTH (TREE_CODE (newdecl)) * sizeof (char *)); } DECL_UID (olddecl) = olddecl_uid; *************** pushdecl (x) *** 3837,3842 **** --- 3820,3827 ---- register tree name; int need_new_binding; + timevar_push (TV_NAME_LOOKUP); + /* We shouldn't be calling pushdecl when we're generating RTL for a function that we already did semantic analysis on previously. */ my_friendly_assert (!cfun || doing_semantic_analysis_p (), *************** pushdecl (x) *** 3960,3971 **** /* Check for duplicate params. */ if (duplicate_decls (x, t)) ! return t; } else if ((DECL_EXTERN_C_FUNCTION_P (x) || DECL_FUNCTION_TEMPLATE_P (x)) && is_overloaded_fn (t)) ! /* Don't do anything just yet. */; else if (t == wchar_decl_node) { if (pedantic && ! DECL_IN_SYSTEM_HEADER (x)) --- 3945,3956 ---- /* Check for duplicate params. */ if (duplicate_decls (x, t)) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } else if ((DECL_EXTERN_C_FUNCTION_P (x) || DECL_FUNCTION_TEMPLATE_P (x)) && is_overloaded_fn (t)) ! /* Don't do anything just yet. */; else if (t == wchar_decl_node) { if (pedantic && ! DECL_IN_SYSTEM_HEADER (x)) *************** pushdecl (x) *** 3973,3984 **** TREE_TYPE (x)); /* Throw away the redeclaration. */ ! return t; } else if (TREE_CODE (t) != TREE_CODE (x)) { if (duplicate_decls (x, t)) ! return t; } else if (duplicate_decls (x, t)) { --- 3958,3969 ---- TREE_TYPE (x)); /* Throw away the redeclaration. */ ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } else if (TREE_CODE (t) != TREE_CODE (x)) { if (duplicate_decls (x, t)) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } else if (duplicate_decls (x, t)) { *************** pushdecl (x) *** 3987,3993 **** else if (TREE_CODE (t) == FUNCTION_DECL) check_default_args (t); ! return t; } else if (DECL_MAIN_P (x)) { --- 3972,3978 ---- else if (TREE_CODE (t) == FUNCTION_DECL) check_default_args (t); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } else if (DECL_MAIN_P (x)) { *************** pushdecl (x) *** 4001,4007 **** error ("as `%D'", x); /* We don't try to push this declaration since that causes a crash. */ ! return x; } } --- 3986,3992 ---- error ("as `%D'", x); /* We don't try to push this declaration since that causes a crash. */ ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); } } *************** pushdecl (x) *** 4019,4025 **** { t = push_overloaded_decl (x, PUSH_LOCAL); if (t != x) ! return t; if (!namespace_bindings_p ()) /* We do not need to create a binding for this name; push_overloaded_decl will have already done so if --- 4004,4010 ---- { t = push_overloaded_decl (x, PUSH_LOCAL); if (t != x) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); if (!namespace_bindings_p ()) /* We do not need to create a binding for this name; push_overloaded_decl will have already done so if *************** pushdecl (x) *** 4031,4042 **** t = push_overloaded_decl (x, PUSH_GLOBAL); if (t == x) add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t))); ! return t; } /* If declaring a type as a typedef, copy the type (unless we're at line 0), and install this TYPE_DECL as the new type's typedef ! name. See the extensive comment in ../c-decl.c (pushdecl). */ if (TREE_CODE (x) == TYPE_DECL) { tree type = TREE_TYPE (x); --- 4016,4027 ---- t = push_overloaded_decl (x, PUSH_GLOBAL); if (t == x) add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t))); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } /* If declaring a type as a typedef, copy the type (unless we're at line 0), and install this TYPE_DECL as the new type's typedef ! name. See the extensive comment in ../c-decl.c (pushdecl). */ if (TREE_CODE (x) == TYPE_DECL) { tree type = TREE_TYPE (x); *************** pushdecl (x) *** 4206,4212 **** if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x) /* Inline decls shadow nothing. */ && !DECL_FROM_INLINE (x) ! && TREE_CODE (oldlocal) == PARM_DECL) { bool err = false; --- 4191,4199 ---- if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x) /* Inline decls shadow nothing. */ && !DECL_FROM_INLINE (x) ! && TREE_CODE (oldlocal) == PARM_DECL ! /* Don't check the `this' parameter. */ ! && !DECL_ARTIFICIAL (oldlocal)) { bool err = false; *************** pushdecl (x) *** 4216,4222 **** { /* Go to where the parms should be and see if we find them there. */ ! struct binding_level *b = current_binding_level->level_chain; /* ARM $8.3 */ if (b->parm_flag == 1) --- 4203,4209 ---- { /* Go to where the parms should be and see if we find them there. */ ! struct cp_binding_level *b = current_binding_level->level_chain; /* ARM $8.3 */ if (b->parm_flag == 1) *************** pushdecl (x) *** 4266,4272 **** ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x)) : current_binding_level); ! return x; } /* Same as pushdecl, but define X in binding-level LEVEL. We rely on the --- 4253,4259 ---- ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x)) : current_binding_level); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); } /* Same as pushdecl, but define X in binding-level LEVEL. We rely on the *************** pushdecl (x) *** 4275,4285 **** static tree pushdecl_with_scope (x, level) tree x; ! struct binding_level *level; { ! register struct binding_level *b; tree function_decl = current_function_decl; current_function_decl = NULL_TREE; if (level->parm_flag == 2) { --- 4262,4274 ---- static tree pushdecl_with_scope (x, level) tree x; ! struct cp_binding_level *level; { ! register struct cp_binding_level *b; tree function_decl = current_function_decl; + timevar_push (TV_NAME_LOOKUP); + current_function_decl = NULL_TREE; if (level->parm_flag == 2) { *************** pushdecl_with_scope (x, level) *** 4296,4302 **** current_binding_level = b; } current_function_decl = function_decl; ! return x; } /* Like pushdecl, only it places X in the current namespace, --- 4285,4291 ---- current_binding_level = b; } current_function_decl = function_decl; ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); } /* Like pushdecl, only it places X in the current namespace, *************** tree *** 4306,4314 **** pushdecl_namespace_level (x) tree x; { ! register struct binding_level *b = current_binding_level; register tree t; t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace)); /* Now, the type_shadowed stack may screw us. Munge it so it does --- 4295,4304 ---- pushdecl_namespace_level (x) tree x; { ! register struct cp_binding_level *b = current_binding_level; register tree t; + timevar_push (TV_NAME_LOOKUP); t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace)); /* Now, the type_shadowed stack may screw us. Munge it so it does *************** pushdecl_namespace_level (x) *** 4342,4348 **** *ptr = newval; } } ! return t; } /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, --- 4332,4338 ---- *ptr = newval; } } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, *************** tree *** 4352,4361 **** pushdecl_top_level (x) tree x; { push_to_top_level (); x = pushdecl_namespace_level (x); pop_from_top_level (); ! return x; } /* Make the declaration of X appear in CLASS scope. */ --- 4342,4352 ---- pushdecl_top_level (x) tree x; { + timevar_push (TV_NAME_LOOKUP); push_to_top_level (); x = pushdecl_namespace_level (x); pop_from_top_level (); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); } /* Make the declaration of X appear in CLASS scope. */ *************** void *** 4364,4376 **** pushdecl_class_level (x) tree x; { ! /* Don't use DECL_ASSEMBLER_NAME here! Everything that looks in class ! scope looks for the pre-mangled name. */ ! register tree name; if (TREE_CODE (x) == OVERLOAD) ! x = OVL_CURRENT (x); ! name = DECL_NAME (x); if (name) { --- 4355,4368 ---- pushdecl_class_level (x) tree x; { ! tree name; + timevar_push (TV_NAME_LOOKUP); + /* Get the name of X. */ if (TREE_CODE (x) == OVERLOAD) ! name = DECL_NAME (get_first_fn (x)); ! else ! name = DECL_NAME (x); if (name) { *************** pushdecl_class_level (x) *** 4380,4392 **** } else if (ANON_AGGR_TYPE_P (TREE_TYPE (x))) { tree f; ! for (f = TYPE_FIELDS (TREE_TYPE (x)); ! f; ! f = TREE_CHAIN (f)) pushdecl_class_level (f); } } /* Enter DECL into the symbol table, if that's appropriate. Returns --- 4372,4386 ---- } else if (ANON_AGGR_TYPE_P (TREE_TYPE (x))) { + /* If X is an anonymous aggregate, all of its members are + treated as if they were members of the class containing the + aggregate, for naming purposes. */ tree f; ! for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f)) pushdecl_class_level (f); } + timevar_pop (TV_NAME_LOOKUP); } /* Enter DECL into the symbol table, if that's appropriate. Returns *************** maybe_push_decl (decl) *** 4405,4411 **** || (TREE_CODE (decl) != PARM_DECL && DECL_CONTEXT (decl) != NULL_TREE /* Definitions of namespace members outside their namespace are ! possible. */ && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL) || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ()) || TREE_CODE (type) == UNKNOWN_TYPE --- 4399,4405 ---- || (TREE_CODE (decl) != PARM_DECL && DECL_CONTEXT (decl) != NULL_TREE /* Definitions of namespace members outside their namespace are ! possible. */ && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL) || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ()) || TREE_CODE (type) == UNKNOWN_TYPE *************** push_class_level_binding (name, x) *** 4427,4437 **** tree name; tree x; { ! tree binding; /* The class_binding_level will be NULL if x is a template parameter name in a member template. */ if (!class_binding_level) ! return; /* Make sure that this new member does not have the same name as a template parameter. */ --- 4421,4433 ---- tree name; tree x; { ! cxx_binding *binding; ! ! timevar_push (TV_NAME_LOOKUP); /* The class_binding_level will be NULL if x is a template parameter name in a member template. */ if (!class_binding_level) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0); /* Make sure that this new member does not have the same name as a template parameter. */ *************** push_class_level_binding (name, x) *** 4481,4487 **** INHERITED_VALUE_BINDING_P (binding) = 0; TREE_TYPE (shadow) = x; IDENTIFIER_CLASS_VALUE (name) = x; ! return; } } --- 4477,4483 ---- INHERITED_VALUE_BINDING_P (binding) = 0; TREE_TYPE (shadow) = x; IDENTIFIER_CLASS_VALUE (name) = x; ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0); } } *************** push_class_level_binding (name, x) *** 4496,4501 **** --- 4492,4498 ---- what to pop later. */ TREE_TYPE (class_binding_level->class_shadowed) = x; } + timevar_pop (TV_NAME_LOOKUP); } /* Insert another USING_DECL into the current binding level, returning *************** push_using_decl (scope, name) *** 4510,4527 **** { tree decl; my_friendly_assert (TREE_CODE (scope) == NAMESPACE_DECL, 383); my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 384); for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl)) if (DECL_INITIAL (decl) == scope && DECL_NAME (decl) == name) break; if (decl) ! return namespace_bindings_p () ? decl : NULL_TREE; decl = build_lang_decl (USING_DECL, name, void_type_node); DECL_INITIAL (decl) = scope; TREE_CHAIN (decl) = current_binding_level->usings; current_binding_level->usings = decl; ! return decl; } /* Add namespace to using_directives. Return NULL_TREE if nothing was --- 4507,4527 ---- { tree decl; + timevar_push (TV_NAME_LOOKUP); + my_friendly_assert (TREE_CODE (scope) == NAMESPACE_DECL, 383); my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 384); for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl)) if (DECL_INITIAL (decl) == scope && DECL_NAME (decl) == name) break; if (decl) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ! namespace_bindings_p () ? decl : NULL_TREE); decl = build_lang_decl (USING_DECL, name, void_type_node); DECL_INITIAL (decl) = scope; TREE_CHAIN (decl) = current_binding_level->usings; current_binding_level->usings = decl; ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); } /* Add namespace to using_directives. Return NULL_TREE if nothing was *************** push_using_directive (used) *** 4535,4554 **** tree ud = current_binding_level->using_directives; tree iter, ancestor; ! /* Check if we already have this. */ if (purpose_member (used, ud) != NULL_TREE) ! return NULL_TREE; ancestor = namespace_ancestor (current_decl_namespace (), used); ud = current_binding_level->using_directives; ud = tree_cons (used, ancestor, ud); current_binding_level->using_directives = ud; ! /* Recursively add all namespaces used. */ for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter)) push_using_directive (TREE_PURPOSE (iter)); ! return ud; } /* DECL is a FUNCTION_DECL for a non-member function, which may have --- 4535,4556 ---- tree ud = current_binding_level->using_directives; tree iter, ancestor; ! timevar_push (TV_NAME_LOOKUP); ! ! /* Check if we already have this. */ if (purpose_member (used, ud) != NULL_TREE) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); ancestor = namespace_ancestor (current_decl_namespace (), used); ud = current_binding_level->using_directives; ud = tree_cons (used, ancestor, ud); current_binding_level->using_directives = ud; ! /* Recursively add all namespaces used. */ for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter)) push_using_directive (TREE_PURPOSE (iter)); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ud); } /* DECL is a FUNCTION_DECL for a non-member function, which may have *************** push_overloaded_decl (decl, flags) *** 4580,4585 **** --- 4582,4589 ---- tree new_binding; int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL)); + timevar_push (TV_NAME_LOOKUP); + if (doing_global) old = namespace_binding (name, DECL_CONTEXT (decl)); else *************** push_overloaded_decl (decl, flags) *** 4612,4618 **** decl, fn); if (duplicate_decls (decl, fn)) ! return fn; } } else if (old == error_mark_node) --- 4616,4622 ---- decl, fn); if (duplicate_decls (decl, fn)) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fn); } } else if (old == error_mark_node) *************** push_overloaded_decl (decl, flags) *** 4622,4628 **** { cp_error_at ("previous non-function declaration `%#D'", old); error ("conflicts with function declaration `%#D'", decl); ! return decl; } } --- 4626,4632 ---- { cp_error_at ("previous non-function declaration `%#D'", old); error ("conflicts with function declaration `%#D'", decl); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); } } *************** push_overloaded_decl (decl, flags) *** 4668,4677 **** *d = tree_cons (NULL_TREE, new_binding, TREE_CHAIN (*d)); ! /* And update the CPLUS_BINDING node. */ BINDING_VALUE (IDENTIFIER_BINDING (name)) = new_binding; ! return decl; } /* We should always find a previous binding in this case. */ --- 4672,4681 ---- *d = tree_cons (NULL_TREE, new_binding, TREE_CHAIN (*d)); ! /* And update the cxx_binding node. */ BINDING_VALUE (IDENTIFIER_BINDING (name)) = new_binding; ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); } /* We should always find a previous binding in this case. */ *************** push_overloaded_decl (decl, flags) *** 4682,4688 **** push_local_binding (name, new_binding, flags); } ! return decl; } /* Generate an implicit declaration for identifier FUNCTIONID --- 4686,4692 ---- push_local_binding (name, new_binding, flags); } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); } /* Generate an implicit declaration for identifier FUNCTIONID *************** redeclaration_error_message (newdecl, ol *** 4748,4754 **** return 0; /* If both functions come from different namespaces, this is not ! a redeclaration - this is a conflict with a used function. */ if (DECL_NAMESPACE_SCOPE_P (olddecl) && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl)) return "`%D' conflicts with used function"; --- 4752,4758 ---- return 0; /* If both functions come from different namespaces, this is not ! a redeclaration - this is a conflict with a used function. */ if (DECL_NAMESPACE_SCOPE_P (olddecl) && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl)) return "`%D' conflicts with used function"; *************** lookup_label (id) *** 4866,4883 **** tree decl; struct named_label_list *ent; /* You can't use labels at global scope. */ if (current_function_decl == NULL_TREE) { error ("label `%s' referenced outside of any function", IDENTIFIER_POINTER (id)); ! return NULL_TREE; } /* See if we've already got this label. */ decl = IDENTIFIER_LABEL_VALUE (id); if (decl != NULL_TREE && DECL_CONTEXT (decl) == current_function_decl) ! return decl; /* Record this label on the list of labels used in this function. We do this before calling make_label_decl so that we get the --- 4870,4889 ---- tree decl; struct named_label_list *ent; + timevar_push (TV_NAME_LOOKUP); + /* You can't use labels at global scope. */ if (current_function_decl == NULL_TREE) { error ("label `%s' referenced outside of any function", IDENTIFIER_POINTER (id)); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); } /* See if we've already got this label. */ decl = IDENTIFIER_LABEL_VALUE (id); if (decl != NULL_TREE && DECL_CONTEXT (decl) == current_function_decl) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); /* Record this label on the list of labels used in this function. We do this before calling make_label_decl so that we get the *************** lookup_label (id) *** 4894,4900 **** /* Now fill in the information we didn't have before. */ ent->label_decl = decl; ! return decl; } /* Declare a local label named ID. */ --- 4900,4906 ---- /* Now fill in the information we didn't have before. */ ent->label_decl = decl; ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); } /* Declare a local label named ID. */ *************** decl_jump_unsafe (decl) *** 4950,4963 **** static void check_previous_goto_1 (decl, level, names, file, line) tree decl; ! struct binding_level *level; tree names; const char *file; int line; { int identified = 0; int saw_eh = 0; ! struct binding_level *b = current_binding_level; for (; b; b = b->level_chain) { tree new_decls = b->names; --- 4956,4969 ---- static void check_previous_goto_1 (decl, level, names, file, line) tree decl; ! struct cp_binding_level *level; tree names; const char *file; int line; { int identified = 0; int saw_eh = 0; ! struct cp_binding_level *b = current_binding_level; for (; b; b = b->level_chain) { tree new_decls = b->names; *************** check_previous_goto (use) *** 5024,5030 **** static void check_switch_goto (level) ! struct binding_level *level; { check_previous_goto_1 (NULL_TREE, level, level->names, NULL, 0); } --- 5030,5036 ---- static void check_switch_goto (level) ! struct cp_binding_level *level; { check_previous_goto_1 (NULL_TREE, level, level->names, NULL, 0); } *************** define_label (filename, line, name) *** 5126,5132 **** { tree decl = lookup_label (name); struct named_label_list *ent; ! register struct binding_level *p; for (ent = named_labels; ent; ent = ent->next) if (ent->label_decl == decl) --- 5132,5140 ---- { tree decl = lookup_label (name); struct named_label_list *ent; ! register struct cp_binding_level *p; ! ! timevar_push (TV_NAME_LOOKUP); for (ent = named_labels; ent; ent = ent->next) if (ent->label_decl == decl) *************** define_label (filename, line, name) *** 5143,5149 **** if (DECL_INITIAL (decl) != NULL_TREE) { error ("duplicate label `%D'", decl); ! return 0; } else { --- 5151,5157 ---- if (DECL_INITIAL (decl) != NULL_TREE) { error ("duplicate label `%D'", decl); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); } else { *************** define_label (filename, line, name) *** 5158,5170 **** ent->binding_level = current_binding_level; } check_previous_gotos (decl); ! return decl; } } struct cp_switch { ! struct binding_level *level; struct cp_switch *next; /* The SWITCH_STMT being built. */ tree switch_stmt; --- 5166,5179 ---- ent->binding_level = current_binding_level; } check_previous_gotos (decl); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); } + timevar_pop (TV_NAME_LOOKUP); } struct cp_switch { ! struct cp_binding_level *level; struct cp_switch *next; /* The SWITCH_STMT being built. */ tree switch_stmt; *************** finish_case_label (low_value, high_value *** 5220,5226 **** tree high_value; { tree cond, r; ! register struct binding_level *p; if (! switch_stack) { --- 5229,5235 ---- tree high_value; { tree cond, r; ! register struct cp_binding_level *p; if (! switch_stack) { *************** static tree *** 5358,5371 **** lookup_tag (form, name, binding_level, thislevel_only) enum tree_code form; tree name; ! struct binding_level *binding_level; int thislevel_only; { ! register struct binding_level *level; ! /* Non-zero if, we should look past a template parameter level, even if THISLEVEL_ONLY. */ int allow_template_parms_p = 1; for (level = binding_level; level; level = level->level_chain) { register tree tail; --- 5367,5382 ---- lookup_tag (form, name, binding_level, thislevel_only) enum tree_code form; tree name; ! struct cp_binding_level *binding_level; int thislevel_only; { ! register struct cp_binding_level *level; ! /* Nonzero if, we should look past a template parameter level, even if THISLEVEL_ONLY. */ int allow_template_parms_p = 1; + timevar_push (TV_NAME_LOOKUP); + for (level = binding_level; level; level = level->level_chain) { register tree tail; *************** lookup_tag (form, name, binding_level, t *** 5375,5398 **** /* There's no need for error checking here, because anon names are unique throughout the compilation. */ if (TYPE_IDENTIFIER (TREE_VALUE (tail)) == name) ! return TREE_VALUE (tail); } else if (level->namespace_p) ! /* Do namespace lookup. */ for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail)) { ! tree old = binding_for_name (name, tail); /* If we just skipped past a template parameter level, even though THISLEVEL_ONLY, and we find a template class declaration, then we use the _TYPE node for the template. See the example below. */ if (thislevel_only && !allow_template_parms_p ! && old && BINDING_VALUE (old) ! && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (old))) ! old = TREE_TYPE (BINDING_VALUE (old)); ! else ! old = BINDING_TYPE (old); if (old) { --- 5386,5413 ---- /* There's no need for error checking here, because anon names are unique throughout the compilation. */ if (TYPE_IDENTIFIER (TREE_VALUE (tail)) == name) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_VALUE (tail)); } else if (level->namespace_p) ! /* Do namespace lookup. */ for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail)) { ! cxx_binding *binding = ! cxx_scope_find_binding_for_name (tail, name); ! tree old; /* If we just skipped past a template parameter level, even though THISLEVEL_ONLY, and we find a template class declaration, then we use the _TYPE node for the template. See the example below. */ if (thislevel_only && !allow_template_parms_p ! && binding && BINDING_VALUE (binding) ! && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (binding))) ! old = TREE_TYPE (BINDING_VALUE (binding)); ! else if (binding) ! old = BINDING_TYPE (binding); ! else ! old = NULL; if (old) { *************** lookup_tag (form, name, binding_level, t *** 5401,5418 **** if the typedef doesn't refer to a taggable type. */ old = follow_tag_typedef (old); if (!old) ! return NULL_TREE; if (TREE_CODE (old) != form && (form == ENUMERAL_TYPE || TREE_CODE (old) == ENUMERAL_TYPE)) { error ("`%#D' redeclared as %C", old, form); ! return NULL_TREE; } ! return old; } if (thislevel_only || tail == global_namespace) ! return NULL_TREE; } else for (tail = level->tags; tail; tail = TREE_CHAIN (tail)) --- 5416,5433 ---- if the typedef doesn't refer to a taggable type. */ old = follow_tag_typedef (old); if (!old) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); if (TREE_CODE (old) != form && (form == ENUMERAL_TYPE || TREE_CODE (old) == ENUMERAL_TYPE)) { error ("`%#D' redeclared as %C", old, form); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old); } if (thislevel_only || tail == global_namespace) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); } else for (tail = level->tags; tail; tail = TREE_CHAIN (tail)) *************** lookup_tag (form, name, binding_level, t *** 5426,5434 **** { /* Definition isn't the kind we were looking for. */ error ("`%#D' redeclared as %C", TREE_VALUE (tail), form); ! return NULL_TREE; } ! return TREE_VALUE (tail); } } if (thislevel_only && ! level->tag_transparent) --- 5441,5449 ---- { /* Definition isn't the kind we were looking for. */ error ("`%#D' redeclared as %C", TREE_VALUE (tail), form); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_VALUE (tail)); } } if (thislevel_only && ! level->tag_transparent) *************** lookup_tag (form, name, binding_level, t *** 5445,5459 **** are in the pseudo-global level created for the template parameters, rather than the (surrounding) namespace level. Thus, we keep going one more level, ! even though THISLEVEL_ONLY is non-zero. */ allow_template_parms_p = 0; continue; } else ! return NULL_TREE; } } ! return NULL_TREE; } #if 0 --- 5460,5474 ---- are in the pseudo-global level created for the template parameters, rather than the (surrounding) namespace level. Thus, we keep going one more level, ! even though THISLEVEL_ONLY is nonzero. */ allow_template_parms_p = 0; continue; } else ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); } } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); } #if 0 *************** set_current_level_tags_transparency (tag *** 5469,5475 **** Otherwise return 0. However, the value can never be 0 in the cases in which this is used. ! C++: If NAME is non-zero, this is the new name to install. This is done when replacing anonymous tags with real tag names. */ static tree --- 5484,5490 ---- Otherwise return 0. However, the value can never be 0 in the cases in which this is used. ! C++: If NAME is nonzero, this is the new name to install. This is done when replacing anonymous tags with real tag names. */ static tree *************** lookup_tag_reverse (type, name) *** 5477,5483 **** tree type; tree name; { ! register struct binding_level *level; for (level = current_binding_level; level; level = level->level_chain) { --- 5492,5500 ---- tree type; tree name; { ! register struct cp_binding_level *level; ! ! timevar_push (TV_NAME_LOOKUP); for (level = current_binding_level; level; level = level->level_chain) { *************** lookup_tag_reverse (type, name) *** 5488,5498 **** { if (name) TREE_PURPOSE (tail) = name; ! return TREE_PURPOSE (tail); } } } ! return NULL_TREE; } /* Look up NAME in the NAMESPACE. */ --- 5505,5515 ---- { if (name) TREE_PURPOSE (tail) = name; ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_PURPOSE (tail)); } } } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); } /* Look up NAME in the NAMESPACE. */ *************** lookup_namespace_name (namespace, name) *** 5503,5520 **** { tree val; tree template_id = NULL_TREE; my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370); if (TREE_CODE (name) == NAMESPACE_DECL) ! /* This happens for A::B when B is a namespace. */ ! return name; else if (TREE_CODE (name) == TEMPLATE_DECL) { /* This happens for A::B where B is a template, and there are no template arguments. */ error ("invalid use of `%D'", name); ! return error_mark_node; } namespace = ORIGINAL_NAMESPACE (namespace); --- 5520,5540 ---- { tree val; tree template_id = NULL_TREE; + cxx_binding binding; + + timevar_push (TV_NAME_LOOKUP); my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370); if (TREE_CODE (name) == NAMESPACE_DECL) ! /* This happens for A::B when B is a namespace. */ ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, name); else if (TREE_CODE (name) == TEMPLATE_DECL) { /* This happens for A::B where B is a template, and there are no template arguments. */ error ("invalid use of `%D'", name); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); } namespace = ORIGINAL_NAMESPACE (namespace); *************** lookup_namespace_name (namespace, name) *** 5531,5543 **** my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373); ! val = make_node (CPLUS_BINDING); ! if (!qualified_lookup_using_namespace (name, namespace, val, 0)) ! return error_mark_node; ! if (BINDING_VALUE (val)) { ! val = BINDING_VALUE (val); if (template_id) { --- 5551,5563 ---- my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373); ! cxx_binding_clear (&binding); ! if (!qualified_lookup_using_namespace (name, namespace, &binding, 0)) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); ! if (binding.value) { ! val = binding.value; if (template_id) { *************** lookup_namespace_name (namespace, name) *** 5556,5562 **** { error ("`%D::%D' is not a template", namespace, name); ! return error_mark_node; } } --- 5576,5582 ---- { error ("`%D::%D' is not a template", namespace, name); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); } } *************** lookup_namespace_name (namespace, name) *** 5568,5602 **** if (!val || !DECL_P(val) || !DECL_LANG_SPECIFIC(val) || !DECL_ANTICIPATED (val)) ! return val; } error ("`%D' undeclared in namespace `%D'", name, namespace); ! return error_mark_node; } /* Hash a TYPENAME_TYPE. K is really of type `tree'. */ ! static unsigned long typename_hash (k) ! hash_table_key k; { ! unsigned long hash; ! tree t; ! t = (tree) k; ! hash = (((unsigned long) TYPE_CONTEXT (t)) ! ^ ((unsigned long) DECL_NAME (TYPE_NAME (t)))); return hash; } /* Compare two TYPENAME_TYPEs. K1 and K2 are really of type `tree'. */ ! static bool typename_compare (k1, k2) ! hash_table_key k1; ! hash_table_key k2; { tree t1; tree t2; --- 5588,5621 ---- if (!val || !DECL_P(val) || !DECL_LANG_SPECIFIC(val) || !DECL_ANTICIPATED (val)) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); } error ("`%D' undeclared in namespace `%D'", name, namespace); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); } /* Hash a TYPENAME_TYPE. K is really of type `tree'. */ ! static hashval_t typename_hash (k) ! const void * k; { ! hashval_t hash; ! tree t = (tree) k; ! hash = (htab_hash_pointer (TYPE_CONTEXT (t)) ! ^ htab_hash_pointer (DECL_NAME (TYPE_NAME (t)))); return hash; } /* Compare two TYPENAME_TYPEs. K1 and K2 are really of type `tree'. */ ! static int typename_compare (k1, k2) ! const void * k1; ! const void * k2; { tree t1; tree t2; *************** typename_compare (k1, k2) *** 5609,5615 **** d2 = TYPE_NAME (t2); return (DECL_NAME (d1) == DECL_NAME (d2) ! && same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2)) && ((TREE_TYPE (t1) != NULL_TREE) == (TREE_TYPE (t2) != NULL_TREE)) && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) --- 5628,5634 ---- d2 = TYPE_NAME (t2); return (DECL_NAME (d1) == DECL_NAME (d2) ! && TYPE_CONTEXT (t1) == TYPE_CONTEXT (t2) && ((TREE_TYPE (t1) != NULL_TREE) == (TREE_TYPE (t2) != NULL_TREE)) && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) *************** typename_compare (k1, k2) *** 5624,5629 **** --- 5643,5650 ---- Returns the new TYPENAME_TYPE. */ + static GTY ((param_is (union tree_node))) htab_t typename_htab; + tree build_typename_type (context, name, fullname, base_type) tree context; *************** build_typename_type (context, name, full *** 5633,5648 **** { tree t; tree d; ! struct hash_entry *e; ! ! static struct hash_table ht; ! if (!ht.table) { ! static struct hash_table *h = &ht; ! ! hash_table_init (&ht, &hash_newfunc, &typename_hash, &typename_compare); ! ggc_add_tree_hash_table_root (&h, 1); } /* Build the TYPENAME_TYPE. */ --- 5654,5665 ---- { tree t; tree d; ! PTR *e; ! if (typename_htab == NULL) { ! typename_htab = htab_create_ggc (61, &typename_hash, ! &typename_compare, NULL); } /* Build the TYPENAME_TYPE. */ *************** build_typename_type (context, name, full *** 5659,5670 **** DECL_ARTIFICIAL (d) = 1; /* See if we already have this type. */ ! e = hash_lookup (&ht, t, /*create=*/false, /*copy=*/0); ! if (e) ! t = (tree) e->key; else ! /* Insert the type into the table. */ ! hash_lookup (&ht, t, /*create=*/true, /*copy=*/0); return t; } --- 5676,5686 ---- DECL_ARTIFICIAL (d) = 1; /* See if we already have this type. */ ! e = htab_find_slot (typename_htab, t, INSERT); ! if (*e) ! t = (tree) *e; else ! *e = t; return t; } *************** make_typename_type (context, name, compl *** 5740,5745 **** --- 5756,5769 ---- return error_mark_node; } + if (complain & tf_error) + { + if (complain & tf_parsing) + type_access_control (context, tmpl); + else + enforce_access (context, tmpl); + } + return lookup_template_class (tmpl, TREE_OPERAND (fullname, 1), NULL_TREE, context, *************** make_typename_type (context, name, compl *** 5766,5771 **** --- 5790,5804 ---- error ("no type named `%#T' in `%#T'", name, context); return error_mark_node; } + + if (complain & tf_error) + { + if (complain & tf_parsing) + type_access_control (context, t); + else + enforce_access (context, t); + } + if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl)) t = TREE_TYPE (t); if (IMPLICIT_TYPENAME_P (t)) *************** make_typename_type (context, name, compl *** 5793,5799 **** return error_mark_node; } - return build_typename_type (context, name, fullname, NULL_TREE); } --- 5826,5831 ---- *************** make_typename_type (context, name, compl *** 5806,5812 **** tree make_unbound_class_template (context, name, complain) tree context, name; ! int complain; { tree t; tree d; --- 5838,5844 ---- tree make_unbound_class_template (context, name, complain) tree context, name; ! tsubst_flags_t complain; { tree t; tree d; *************** make_unbound_class_template (context, na *** 5828,5840 **** if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl)) { ! if (complain) error ("no class template named `%#T' in `%#T'", name, context); return error_mark_node; } ! if (!enforce_access (context, tmpl)) ! return error_mark_node; return tmpl; } --- 5860,5877 ---- if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl)) { ! if (complain & tf_error) error ("no class template named `%#T' in `%#T'", name, context); return error_mark_node; } ! if (complain & tf_error) ! { ! if (complain & tf_parsing) ! type_access_control (context, tmpl); ! else ! enforce_access (context, tmpl); ! } return tmpl; } *************** make_unbound_class_template (context, na *** 5854,5875 **** return t; } ! /* Select the right _DECL from multiple choices. */ static tree ! select_decl (binding, flags) ! tree binding; ! int flags; { tree val; val = BINDING_VALUE (binding); if (LOOKUP_NAMESPACES_ONLY (flags)) { ! /* We are not interested in types. */ if (val && TREE_CODE (val) == NAMESPACE_DECL) ! return val; ! return NULL_TREE; } /* If we could have a type and --- 5891,5913 ---- return t; } ! /* Select the right _DECL from multiple choices. */ static tree ! select_decl (cxx_binding *binding, int flags) { tree val; + + timevar_push (TV_NAME_LOOKUP); + val = BINDING_VALUE (binding); if (LOOKUP_NAMESPACES_ONLY (flags)) { ! /* We are not interested in types. */ if (val && TREE_CODE (val) == NAMESPACE_DECL) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); } /* If we could have a type and *************** select_decl (binding, flags) *** 5878,5890 **** && (!val || ((flags & LOOKUP_PREFER_TYPES) && TREE_CODE (val) != TYPE_DECL))) val = TYPE_STUB_DECL (BINDING_TYPE (binding)); ! /* Don't return non-types if we really prefer types. */ else if (val && LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL && (TREE_CODE (val) != TEMPLATE_DECL || !DECL_CLASS_TEMPLATE_P (val))) val = NULL_TREE; ! return val; } /* Unscoped lookup of a global: iterate over current namespaces, --- 5916,5928 ---- && (!val || ((flags & LOOKUP_PREFER_TYPES) && TREE_CODE (val) != TYPE_DECL))) val = TYPE_STUB_DECL (BINDING_TYPE (binding)); ! /* Don't return non-types if we really prefer types. */ else if (val && LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL && (TREE_CODE (val) != TEMPLATE_DECL || !DECL_CLASS_TEMPLATE_P (val))) val = NULL_TREE; ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); } /* Unscoped lookup of a global: iterate over current namespaces, *************** unqualified_namespace_lookup (name, flag *** 5897,5961 **** int flags; tree *spacesp; { - tree b = make_node (CPLUS_BINDING); tree initial = current_decl_namespace (); tree scope = initial; tree siter; ! struct binding_level *level; tree val = NULL_TREE; if (spacesp) *spacesp = NULL_TREE; for (; !val; scope = CP_DECL_CONTEXT (scope)) { if (spacesp) *spacesp = tree_cons (scope, NULL_TREE, *spacesp); ! val = binding_for_name (name, scope); /* Ignore anticipated built-in functions. */ ! if (val && BINDING_VALUE (val) ! && DECL_P (BINDING_VALUE (val)) ! && DECL_LANG_SPECIFIC (BINDING_VALUE (val)) ! && DECL_ANTICIPATED (BINDING_VALUE (val))) ! { ! BINDING_VALUE (b) = NULL_TREE; ! BINDING_TYPE (b) = NULL_TREE; ! } ! else { ! /* Initialize binding for this context. */ ! BINDING_VALUE (b) = BINDING_VALUE (val); ! BINDING_TYPE (b) = BINDING_TYPE (val); } ! /* Add all _DECLs seen through local using-directives. */ for (level = current_binding_level; !level->namespace_p; level = level->level_chain) ! if (!lookup_using_namespace (name, b, level->using_directives, scope, flags, spacesp)) ! /* Give up because of error. */ ! return error_mark_node; ! /* Add all _DECLs seen through global using-directives. */ ! /* XXX local and global using lists should work equally. */ siter = initial; while (1) { ! if (!lookup_using_namespace (name, b, DECL_NAMESPACE_USING (siter), scope, flags, spacesp)) ! /* Give up because of error. */ ! return error_mark_node; if (siter == scope) break; siter = CP_DECL_CONTEXT (siter); } ! val = select_decl (b, flags); if (scope == global_namespace) break; } ! return val; } /* Combine prefer_type and namespaces_only into flags. */ --- 5935,5999 ---- int flags; tree *spacesp; { tree initial = current_decl_namespace (); tree scope = initial; tree siter; ! struct cp_binding_level *level; tree val = NULL_TREE; + cxx_binding binding; + timevar_push (TV_NAME_LOOKUP); + cxx_binding_clear (&binding); if (spacesp) *spacesp = NULL_TREE; for (; !val; scope = CP_DECL_CONTEXT (scope)) { + cxx_binding *b; if (spacesp) *spacesp = tree_cons (scope, NULL_TREE, *spacesp); ! b = cxx_scope_find_binding_for_name (scope, name); /* Ignore anticipated built-in functions. */ ! if (b && BINDING_VALUE (b) && DECL_P (BINDING_VALUE (b)) ! && DECL_LANG_SPECIFIC (BINDING_VALUE (b)) ! && DECL_ANTICIPATED (BINDING_VALUE (b))) ! /* Keep binding cleared. */; ! else if (b) { ! /* Initialize binding for this context. */ ! binding.value = BINDING_VALUE (b); ! binding.type = BINDING_TYPE (b); } ! /* Add all _DECLs seen through local using-directives. */ for (level = current_binding_level; !level->namespace_p; level = level->level_chain) ! if (!lookup_using_namespace (name, &binding, level->using_directives, scope, flags, spacesp)) ! /* Give up because of error. */ ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); ! /* Add all _DECLs seen through global using-directives. */ ! /* XXX local and global using lists should work equally. */ siter = initial; while (1) { ! if (!lookup_using_namespace (name, &binding, ! DECL_NAMESPACE_USING (siter), scope, flags, spacesp)) ! /* Give up because of error. */ ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); if (siter == scope) break; siter = CP_DECL_CONTEXT (siter); } ! val = select_decl (&binding, flags); if (scope == global_namespace) break; } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); } /* Combine prefer_type and namespaces_only into flags. */ *************** warn_about_implicit_typename_lookup (typ *** 6022,6027 **** --- 6060,6124 ---- } } + /* Check to see whether or not DECL is a variable that would have been + in scope under the ARM, but is not in scope under the ANSI/ISO + standard. If so, issue an error message. If name lookup would + work in both cases, but return a different result, this function + returns the result of ANSI/ISO lookup. Otherwise, it returns + DECL. */ + + tree + check_for_out_of_scope_variable (tree decl) + { + tree shadowed; + + /* We only care about out of scope variables. */ + if (!(TREE_CODE (decl) == VAR_DECL && DECL_DEAD_FOR_LOCAL (decl))) + return decl; + + shadowed = DECL_SHADOWED_FOR_VAR (decl); + while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL + && DECL_DEAD_FOR_LOCAL (shadowed)) + shadowed = DECL_SHADOWED_FOR_VAR (shadowed); + if (!shadowed) + shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (decl)); + if (shadowed) + { + if (!DECL_ERROR_REPORTED (decl)) + { + warning ("name lookup of `%D' changed", + DECL_NAME (decl)); + cp_warning_at (" matches this `%D' under ISO standard rules", + shadowed); + cp_warning_at (" matches this `%D' under old rules", decl); + DECL_ERROR_REPORTED (decl) = 1; + } + return shadowed; + } + + /* If we have already complained about this declaration, there's no + need to do it again. */ + if (DECL_ERROR_REPORTED (decl)) + return decl; + + DECL_ERROR_REPORTED (decl) = 1; + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))) + { + error ("name lookup of `%D' changed for new ISO `for' scoping", + DECL_NAME (decl)); + cp_error_at (" cannot use obsolete binding at `%D' because it has a destructor", decl); + return error_mark_node; + } + else + { + pedwarn ("name lookup of `%D' changed for new ISO `for' scoping", + DECL_NAME (decl)); + cp_pedwarn_at (" using obsolete binding at `%D'", decl); + } + + return decl; + } + /* Look up NAME in the current binding level and its superiors in the namespace of variables, functions and typedefs. Return a ..._DECL node of some kind representing its definition if there is only one *************** warn_about_implicit_typename_lookup (typ *** 6033,6039 **** If PREFER_TYPE is -2, we're being called from yylex(). (UGLY) Otherwise we prefer non-TYPE_DECLs. ! If NONCLASS is non-zero, we don't look for the NAME in class scope, using IDENTIFIER_CLASS_VALUE. */ static tree --- 6130,6136 ---- If PREFER_TYPE is -2, we're being called from yylex(). (UGLY) Otherwise we prefer non-TYPE_DECLs. ! If NONCLASS is nonzero, we don't look for the NAME in class scope, using IDENTIFIER_CLASS_VALUE. */ static tree *************** lookup_name_real (name, prefer_type, non *** 6047,6054 **** tree from_obj = NULL_TREE; int flags; int val_is_implicit_typename = 0; ! /* Hack: copy flag set by parser, if set. */ if (only_namespace_names) namespaces_only = 1; --- 6144,6154 ---- tree from_obj = NULL_TREE; int flags; int val_is_implicit_typename = 0; + cxx_binding *iter; ! timevar_push (TV_NAME_LOOKUP); ! ! /* Hack: copy flag set by parser, if set. */ if (only_namespace_names) namespaces_only = 1; *************** lookup_name_real (name, prefer_type, non *** 6061,6067 **** prefer_type = looking_for_typename; flags = lookup_flags (prefer_type, namespaces_only); ! /* If the next thing is '<', class templates are types. */ if (looking_for_template) flags |= LOOKUP_TEMPLATES_EXPECTED; --- 6161,6167 ---- prefer_type = looking_for_typename; flags = lookup_flags (prefer_type, namespaces_only); ! /* If the next thing is '<', class templates are types. */ if (looking_for_template) flags |= LOOKUP_TEMPLATES_EXPECTED; *************** lookup_name_real (name, prefer_type, non *** 6073,6080 **** if (type) { if (type == error_mark_node) ! return error_mark_node; ! if (TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type)) type = TREE_TYPE (type); if (TYPE_P (type)) --- 6173,6180 ---- if (type) { if (type == error_mark_node) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); ! if (IMPLICIT_TYPENAME_P (type)) type = TREE_TYPE (type); if (TYPE_P (type)) *************** lookup_name_real (name, prefer_type, non *** 6084,6094 **** type = global_namespace; if (TREE_CODE (type) == NAMESPACE_DECL) { ! val = make_node (CPLUS_BINDING); flags |= LOOKUP_COMPLAIN; ! if (!qualified_lookup_using_namespace (name, type, val, flags)) ! return NULL_TREE; ! val = select_decl (val, flags); } else if (! IS_AGGR_TYPE (type) || TREE_CODE (type) == TEMPLATE_TYPE_PARM --- 6184,6195 ---- type = global_namespace; if (TREE_CODE (type) == NAMESPACE_DECL) { ! cxx_binding b; ! cxx_binding_clear (&b); flags |= LOOKUP_COMPLAIN; ! if (!qualified_lookup_using_namespace (name, type, &b, flags)) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); ! val = select_decl (&b, flags); } else if (! IS_AGGR_TYPE (type) || TREE_CODE (type) == TEMPLATE_TYPE_PARM *************** lookup_name_real (name, prefer_type, non *** 6101,6107 **** else { val = lookup_member (type, name, 0, prefer_type); ! type_access_control (type, val); /* Restore the containing TYPENAME_TYPE if we looked through it before. */ --- 6202,6209 ---- else { val = lookup_member (type, name, 0, prefer_type); ! if (!uses_template_parms (type)) ! type_access_control (type, val); /* Restore the containing TYPENAME_TYPE if we looked through it before. */ *************** lookup_name_real (name, prefer_type, non *** 6131,6137 **** else { flags = lookup_flags (prefer_type, namespaces_only); ! /* If we're not parsing, we need to complain. */ flags |= LOOKUP_COMPLAIN; } --- 6233,6239 ---- else { flags = lookup_flags (prefer_type, namespaces_only); ! /* If we're not parsing, we need to complain. */ flags |= LOOKUP_COMPLAIN; } *************** lookup_name_real (name, prefer_type, non *** 6140,6166 **** if (current_class_type == NULL_TREE) nonclass = 1; ! for (t = IDENTIFIER_BINDING (name); t; t = TREE_CHAIN (t)) { tree binding; ! if (!LOCAL_BINDING_P (t) && nonclass) /* We're not looking for class-scoped bindings, so keep going. */ continue; /* If this is the kind of thing we're looking for, we're done. */ ! if (qualify_lookup (BINDING_VALUE (t), flags)) ! binding = BINDING_VALUE (t); else if ((flags & LOOKUP_PREFER_TYPES) ! && qualify_lookup (BINDING_TYPE (t), flags)) ! binding = BINDING_TYPE (t); else binding = NULL_TREE; /* Handle access control on types from enclosing or base classes. */ if (binding && ! yylex ! && BINDING_LEVEL (t) && BINDING_LEVEL (t)->parm_flag == 2) ! type_access_control (BINDING_LEVEL (t)->this_class, binding); if (binding && (!val || !IMPLICIT_TYPENAME_TYPE_DECL_P (binding))) --- 6242,6268 ---- if (current_class_type == NULL_TREE) nonclass = 1; ! for (iter = IDENTIFIER_BINDING (name); iter; iter = iter->previous) { tree binding; ! if (!LOCAL_BINDING_P (iter) && nonclass) /* We're not looking for class-scoped bindings, so keep going. */ continue; /* If this is the kind of thing we're looking for, we're done. */ ! if (qualify_lookup (BINDING_VALUE (iter), flags)) ! binding = BINDING_VALUE (iter); else if ((flags & LOOKUP_PREFER_TYPES) ! && qualify_lookup (BINDING_TYPE (iter), flags)) ! binding = BINDING_TYPE (iter); else binding = NULL_TREE; /* Handle access control on types from enclosing or base classes. */ if (binding && ! yylex ! && BINDING_LEVEL (iter) && BINDING_LEVEL (iter)->parm_flag == 2) ! type_access_control (BINDING_LEVEL (iter)->this_class, binding); if (binding && (!val || !IMPLICIT_TYPENAME_TYPE_DECL_P (binding))) *************** does not match lookup in the current sco *** 6219,6225 **** else if (from_obj) val = from_obj; ! return val; } tree --- 6321,6327 ---- else if (from_obj) val = from_obj; ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); } tree *************** tree *** 6260,6268 **** lookup_name_current_level (name) tree name; { ! struct binding_level *b; tree t = NULL_TREE; b = current_binding_level; while (b->parm_flag == 2) b = b->level_chain; --- 6362,6372 ---- lookup_name_current_level (name) tree name; { ! struct cp_binding_level *b; tree t = NULL_TREE; + timevar_push (TV_NAME_LOOKUP); + b = current_binding_level; while (b->parm_flag == 2) b = b->level_chain; *************** lookup_name_current_level (name) *** 6281,6287 **** while (1) { if (BINDING_LEVEL (IDENTIFIER_BINDING (name)) == b) ! return IDENTIFIER_VALUE (name); if (b->keep == 2) b = b->level_chain; --- 6385,6391 ---- while (1) { if (BINDING_LEVEL (IDENTIFIER_BINDING (name)) == b) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, IDENTIFIER_VALUE (name)); if (b->keep == 2) b = b->level_chain; *************** lookup_name_current_level (name) *** 6290,6296 **** } } ! return t; } /* Like lookup_name_current_level, but for types. */ --- 6394,6400 ---- } } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } /* Like lookup_name_current_level, but for types. */ *************** lookup_type_current_level (name) *** 6300,6316 **** tree name; { register tree t = NULL_TREE; my_friendly_assert (! current_binding_level->namespace_p, 980716); if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node) { ! struct binding_level *b = current_binding_level; while (1) { if (purpose_member (name, b->type_shadowed)) ! return REAL_IDENTIFIER_TYPE_VALUE (name); if (b->keep == 2) b = b->level_chain; else --- 6404,6423 ---- tree name; { register tree t = NULL_TREE; + + timevar_push (TV_NAME_LOOKUP); my_friendly_assert (! current_binding_level->namespace_p, 980716); if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node) { ! struct cp_binding_level *b = current_binding_level; while (1) { if (purpose_member (name, b->type_shadowed)) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ! REAL_IDENTIFIER_TYPE_VALUE (name)); if (b->keep == 2) b = b->level_chain; else *************** lookup_type_current_level (name) *** 6318,6324 **** } } ! return t; } void --- 6425,6431 ---- } } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } void *************** record_builtin_type (rid_index, name, ty *** 6359,6365 **** tdecl = pushdecl (build_decl (TYPE_DECL, tname, type)); set_identifier_type_value (tname, NULL_TREE); if ((int) rid_index < (int) RID_MAX) ! /* Built-in types live in the global namespace. */ SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl); } if (rname != NULL_TREE) --- 6466,6472 ---- tdecl = pushdecl (build_decl (TYPE_DECL, tname, type)); set_identifier_type_value (tname, NULL_TREE); if ((int) rid_index < (int) RID_MAX) ! /* Built-in types live in the global namespace. */ SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl); } if (rname != NULL_TREE) *************** record_builtin_java_type (name, size) *** 6391,6402 **** if (size > 0) type = make_signed_type (size); else if (size > -32) ! { /* "__java_char" or ""__java_boolean". */ type = make_unsigned_type (-size); /*if (size == -1) TREE_SET_CODE (type, BOOLEAN_TYPE);*/ } else ! { /* "__java_float" or ""__java_double". */ type = make_node (REAL_TYPE); TYPE_PRECISION (type) = - size; layout_type (type); --- 6498,6509 ---- if (size > 0) type = make_signed_type (size); else if (size > -32) ! { /* "__java_char" or ""__java_boolean". */ type = make_unsigned_type (-size); /*if (size == -1) TREE_SET_CODE (type, BOOLEAN_TYPE);*/ } else ! { /* "__java_float" or ""__java_double". */ type = make_node (REAL_TYPE); TYPE_PRECISION (type) = - size; layout_type (type); *************** record_builtin_java_type (name, size) *** 6406,6419 **** /* Suppress generate debug symbol entries for these types, since for normal C++ they are just clutter. ! However, push_lang_context undoes this if extern "Java" is seen. */ DECL_IGNORED_P (decl) = 1; TYPE_FOR_JAVA (type) = 1; return type; } ! /* Push a type into the namespace so that the back-ends ignore it. */ static void record_unknown_type (type, name) --- 6513,6526 ---- /* Suppress generate debug symbol entries for these types, since for normal C++ they are just clutter. ! However, push_lang_context undoes this if extern "Java" is seen. */ DECL_IGNORED_P (decl) = 1; TYPE_FOR_JAVA (type) = 1; return type; } ! /* Push a type into the namespace so that the back-ends ignore it. */ static void record_unknown_type (type, name) *************** typedef struct predefined_identifier *** 6439,6445 **** const char *const name; /* The place where the IDENTIFIER_NODE should be stored. */ tree *const node; ! /* Non-zero if this is the name of a constructor or destructor. */ const int ctor_or_dtor_p; } predefined_identifier; --- 6546,6552 ---- const char *const name; /* The place where the IDENTIFIER_NODE should be stored. */ tree *const node; ! /* Nonzero if this is the name of a constructor or destructor. */ const int ctor_or_dtor_p; } predefined_identifier; *************** cxx_init_decl_processing () *** 6496,6514 **** initialize_predefined_identifiers (); /* Fill in back-end hooks. */ - init_lang_status = &push_cp_function_context; - free_lang_status = &pop_cp_function_context; - mark_lang_status = &mark_cp_function_context; lang_missing_noreturn_ok_p = &cp_missing_noreturn_ok_p; - cp_parse_init (); - init_decl2 (); - init_pt (); - /* Create the global variables. */ push_to_top_level (); ! /* Enter the global namespace. */ my_friendly_assert (global_namespace == NULL_TREE, 375); push_namespace (get_identifier ("::")); global_namespace = current_namespace; --- 6603,6614 ---- initialize_predefined_identifiers (); /* Fill in back-end hooks. */ lang_missing_noreturn_ok_p = &cp_missing_noreturn_ok_p; /* Create the global variables. */ push_to_top_level (); ! /* Enter the global namespace. */ my_friendly_assert (global_namespace == NULL_TREE, 375); push_namespace (get_identifier ("::")); global_namespace = current_namespace; *************** cxx_init_decl_processing () *** 6553,6565 **** NAMESPACE_LEVEL (global_namespace) = global_binding_level; declare_namespace_level (); /* Create the `std' namespace. */ push_namespace (std_identifier); std_node = current_namespace; pop_namespace (); - lang_attribute_table = cp_attribute_table; - c_common_nodes_and_builtins (); java_byte_type_node = record_builtin_java_type ("__java_byte", 8); --- 6653,6667 ---- NAMESPACE_LEVEL (global_namespace) = global_binding_level; declare_namespace_level (); + VARRAY_TREE_INIT (global_binding_level->static_decls, + 200, + "Static declarations"); + /* Create the `std' namespace. */ push_namespace (std_identifier); std_node = current_namespace; pop_namespace (); c_common_nodes_and_builtins (); java_byte_type_node = record_builtin_java_type ("__java_byte", 8); *************** cxx_init_decl_processing () *** 6587,6595 **** boolean_true_node = build_int_2 (1, 0); TREE_TYPE (boolean_true_node) = boolean_type_node; - signed_size_zero_node = build_int_2 (0, 0); - TREE_TYPE (signed_size_zero_node) = make_signed_type (TYPE_PRECISION (sizetype)); - empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE); #if 0 --- 6689,6694 ---- *************** cxx_init_decl_processing () *** 6600,6607 **** vtable_index_type = ptrdiff_type_node; vtt_parm_type = build_pointer_type (const_ptr_type_node); - lang_type_promotes_to = convert_type_from_ellipsis; - void_ftype = build_function_type (void_type_node, void_list_node); void_ftype_ptr = build_function_type (void_type_node, tree_cons (NULL_TREE, --- 6699,6704 ---- *************** cxx_init_decl_processing () *** 6659,6666 **** tree ptr_ftype_sizetype; push_namespace (std_identifier); ! bad_alloc_type_node = xref_tag ! (class_type_node, get_identifier ("bad_alloc"), 1); pop_namespace (); ptr_ftype_sizetype = build_function_type (ptr_type_node, --- 6756,6764 ---- tree ptr_ftype_sizetype; push_namespace (std_identifier); ! bad_alloc_type_node ! = xref_tag (class_type, get_identifier ("bad_alloc"), ! /*attributes=*/NULL_TREE, 1); pop_namespace (); ptr_ftype_sizetype = build_function_type (ptr_type_node, *************** cxx_init_decl_processing () *** 6682,6688 **** /* Perform other language dependent initializations. */ init_class_processing (); - init_init_processing (); init_search_processing (); init_rtti_processing (); --- 6780,6785 ---- *************** cxx_init_decl_processing () *** 6702,6742 **** say -fwritable-strings? */ if (flag_writable_strings) flag_const_strings = 0; - - /* Add GC roots for all of our global variables. */ - ggc_add_tree_root (c_global_trees, sizeof c_global_trees / sizeof(tree)); - ggc_add_tree_root (cp_global_trees, sizeof cp_global_trees / sizeof(tree)); - ggc_add_tree_root (&integer_three_node, 1); - ggc_add_tree_root (&integer_two_node, 1); - ggc_add_tree_root (&signed_size_zero_node, 1); - ggc_add_tree_root (&size_one_node, 1); - ggc_add_tree_root (&size_zero_node, 1); - ggc_add_root (&global_binding_level, 1, sizeof global_binding_level, - mark_binding_level); - ggc_add_root (&scope_chain, 1, sizeof scope_chain, &mark_saved_scope); - ggc_add_tree_root (&static_ctors, 1); - ggc_add_tree_root (&static_dtors, 1); - ggc_add_tree_root (&lastiddecl, 1); - - ggc_add_tree_root (&last_function_parms, 1); - ggc_add_tree_root (&error_mark_list, 1); - - ggc_add_tree_root (&global_namespace, 1); - ggc_add_tree_root (&global_type_node, 1); - ggc_add_tree_root (&anonymous_namespace_name, 1); - - ggc_add_tree_root (&got_object, 1); - ggc_add_tree_root (&got_scope, 1); - - ggc_add_tree_root (¤t_lang_name, 1); - ggc_add_tree_root (&static_aggregates, 1); - ggc_add_tree_root (&free_bindings, 1); - ggc_add_tree_root (&incomplete_vars, 1); } /* Generate an initializer for a function naming variable from NAME. NAME may be NULL, in which case we generate a special ! ERROR_MARK node which should be replaced later. */ tree cp_fname_init (name) --- 6799,6809 ---- say -fwritable-strings? */ if (flag_writable_strings) flag_const_strings = 0; } /* Generate an initializer for a function naming variable from NAME. NAME may be NULL, in which case we generate a special ! ERROR_MARK node which should be replaced later. */ tree cp_fname_init (name) *************** cp_fname_init (name) *** 6761,6767 **** TREE_TYPE (init) = type; else /* We don't know the value until instantiation time. Make ! something which will be digested now, but replaced later. */ init = build (ERROR_MARK, type); return init; --- 6828,6834 ---- TREE_TYPE (init) = type; else /* We don't know the value until instantiation time. Make ! something which will be digested now, but replaced later. */ init = build (ERROR_MARK, type); return init; *************** cp_make_fname_decl (id, type_dep) *** 6783,6789 **** tree init = cp_fname_init (name); tree decl = build_decl (VAR_DECL, id, TREE_TYPE (init)); ! /* As we don't push the decl here, we must set the context. */ DECL_CONTEXT (decl) = current_function_decl; DECL_PRETTY_FUNCTION_P (decl) = type_dep; --- 6850,6856 ---- tree init = cp_fname_init (name); tree decl = build_decl (VAR_DECL, id, TREE_TYPE (init)); ! /* As we don't push the decl here, we must set the context. */ DECL_CONTEXT (decl) = current_function_decl; DECL_PRETTY_FUNCTION_P (decl) = type_dep; *************** cp_make_fname_decl (id, type_dep) *** 6807,6832 **** See tree.h for possible values. If LIBNAME is nonzero, use that for DECL_ASSEMBLER_NAME, ! the name to be called if we can't opencode the function. */ static tree ! builtin_function_1 (name, type, context, code, class, libname) const char *name; tree type; tree context; int code; enum built_in_class class; const char *libname; { tree decl = build_library_fn_1 (get_identifier (name), ERROR_MARK, type); DECL_BUILT_IN_CLASS (decl) = class; DECL_FUNCTION_CODE (decl) = code; DECL_CONTEXT (decl) = context; - /* The return builtins leave the current function. */ - if (code == BUILT_IN_RETURN || code == BUILT_IN_EH_RETURN) - TREE_THIS_VOLATILE (decl) = 1; - pushdecl (decl); /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME, --- 6874,6898 ---- See tree.h for possible values. If LIBNAME is nonzero, use that for DECL_ASSEMBLER_NAME, ! the name to be called if we can't opencode the function. ! If ATTRS is nonzero, use that for the function's attribute ! list. */ static tree ! builtin_function_1 (name, type, context, code, class, libname, attrs) const char *name; tree type; tree context; int code; enum built_in_class class; const char *libname; + tree attrs; { tree decl = build_library_fn_1 (get_identifier (name), ERROR_MARK, type); DECL_BUILT_IN_CLASS (decl) = class; DECL_FUNCTION_CODE (decl) = code; DECL_CONTEXT (decl) = context; pushdecl (decl); /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME, *************** builtin_function_1 (name, type, context, *** 6842,6848 **** DECL_ANTICIPATED (decl) = 1; /* Possibly apply some default attributes to this built-in function. */ ! decl_attributes (&decl, NULL_TREE, 0); return decl; } --- 6908,6917 ---- DECL_ANTICIPATED (decl) = 1; /* Possibly apply some default attributes to this built-in function. */ ! if (attrs) ! decl_attributes (&decl, attrs, ATTR_FLAG_BUILT_IN); ! else ! decl_attributes (&decl, NULL_TREE, 0); return decl; } *************** builtin_function_1 (name, type, context, *** 6858,6883 **** See tree.h for possible values. If LIBNAME is nonzero, use that for DECL_ASSEMBLER_NAME, ! the name to be called if we can't opencode the function. */ tree ! builtin_function (name, type, code, class, libname) const char *name; tree type; int code; enum built_in_class class; const char *libname; { /* All builtins that don't begin with an '_' should additionally go in the 'std' namespace. */ if (name[0] != '_') { push_namespace (std_identifier); ! builtin_function_1 (name, type, std_node, code, class, libname); pop_namespace (); } ! return builtin_function_1 (name, type, NULL_TREE, code, class, libname); } /* Generate a FUNCTION_DECL with the typical flags for a runtime library --- 6927,6957 ---- See tree.h for possible values. If LIBNAME is nonzero, use that for DECL_ASSEMBLER_NAME, ! the name to be called if we can't opencode the function. ! ! If ATTRS is nonzero, use that for the function's attribute ! list. */ tree ! builtin_function (name, type, code, class, libname, attrs) const char *name; tree type; int code; enum built_in_class class; const char *libname; + tree attrs; { /* All builtins that don't begin with an '_' should additionally go in the 'std' namespace. */ if (name[0] != '_') { push_namespace (std_identifier); ! builtin_function_1 (name, type, std_node, code, class, libname, attrs); pop_namespace (); } ! return builtin_function_1 (name, type, NULL_TREE, code, ! class, libname, attrs); } /* Generate a FUNCTION_DECL with the typical flags for a runtime library *************** push_throw_library_fn (name, type) *** 7004,7010 **** attributes. */ void ! insert_default_attributes (decl) tree decl; { if (!DECL_EXTERN_C_FUNCTION_P (decl)) --- 7078,7084 ---- attributes. */ void ! cxx_insert_default_attributes (decl) tree decl; { if (!DECL_EXTERN_C_FUNCTION_P (decl)) *************** check_tag_decl (declspecs) *** 7142,7148 **** || value == ridpointers[(int) RID_VIRTUAL] || value == ridpointers[(int) RID_CONST] || value == ridpointers[(int) RID_VOLATILE] ! || value == ridpointers[(int) RID_EXPLICIT]) ob_modifier = value; } --- 7216,7223 ---- || value == ridpointers[(int) RID_VIRTUAL] || value == ridpointers[(int) RID_CONST] || value == ridpointers[(int) RID_VOLATILE] ! || value == ridpointers[(int) RID_EXPLICIT] ! || value == ridpointers[(int) RID_THREAD]) ob_modifier = value; } *************** start_decl (declarator, declspecs, initi *** 7282,7289 **** tree decl; register tree type, tem; tree context; - extern int have_extern_spec; - extern int used_extern_spec; #if 0 /* See code below that used this. */ --- 7357,7362 ---- *************** start_decl (declarator, declspecs, initi *** 7291,7301 **** #endif /* This should only be done once on the top most decl. */ ! if (have_extern_spec && !used_extern_spec) { declspecs = tree_cons (NULL_TREE, get_identifier ("extern"), declspecs); ! used_extern_spec = 1; } /* An object declared as __attribute__((deprecated)) suppresses --- 7364,7374 ---- #endif /* This should only be done once on the top most decl. */ ! if (have_extern_spec) { declspecs = tree_cons (NULL_TREE, get_identifier ("extern"), declspecs); ! have_extern_spec = false; } /* An object declared as __attribute__((deprecated)) suppresses *************** start_decl (declarator, declspecs, initi *** 7324,7334 **** && context != current_namespace && TREE_CODE (decl) == VAR_DECL) { /* When parsing the initializer, lookup should use the object's ! namespace. */ push_decl_namespace (context); } ! /* We are only interested in class contexts, later. */ if (context && TREE_CODE (context) == NAMESPACE_DECL) context = NULL_TREE; --- 7397,7407 ---- && context != current_namespace && TREE_CODE (decl) == VAR_DECL) { /* When parsing the initializer, lookup should use the object's ! namespace. */ push_decl_namespace (context); } ! /* We are only interested in class contexts, later. */ if (context && TREE_CODE (context) == NAMESPACE_DECL) context = NULL_TREE; *************** start_decl (declarator, declspecs, initi *** 7451,7457 **** wrong semantics. If we say -fno-conserve-space, we want this to produce errors about redefs; to do this we force variables into the data segment. */ ! DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem); #endif if (! processing_template_decl) --- 7524,7532 ---- wrong semantics. If we say -fno-conserve-space, we want this to produce errors about redefs; to do this we force variables into the data segment. */ ! DECL_COMMON (tem) = ((TREE_CODE (tem) != VAR_DECL ! || !DECL_THREAD_LOCAL (tem)) ! && (flag_conserve_space || ! TREE_PUBLIC (tem))); #endif if (! processing_template_decl) *************** grok_reference_init (decl, type, init) *** 7579,7588 **** DECL_INITIAL for local references (instead assigning to them explicitly); we need to allow the temporary to be initialized first. */ ! tmp = convert_to_reference ! (type, init, CONV_IMPLICIT, ! LOOKUP_ONLYCONVERTING|LOOKUP_SPECULATIVELY|LOOKUP_NORMAL|DIRECT_BIND, ! decl); if (tmp == error_mark_node) return NULL_TREE; --- 7654,7660 ---- DECL_INITIAL for local references (instead assigning to them explicitly); we need to allow the temporary to be initialized first. */ ! tmp = initialize_reference (type, init, decl); if (tmp == error_mark_node) return NULL_TREE; *************** grok_reference_init (decl, type, init) *** 7600,7638 **** return NULL_TREE; } - /* Fill in DECL_INITIAL with some magical value to prevent expand_decl from - mucking with forces it does not comprehend (i.e. initialization with a - constructor). If we are at global scope and won't go into COMMON, fill - it in with a dummy CONSTRUCTOR to force the variable into .data; - otherwise we can use error_mark_node. */ - - static tree - obscure_complex_init (decl, init) - tree decl, init; - { - if (! flag_no_inline && TREE_STATIC (decl)) - { - if (extract_init (decl, init)) - return NULL_TREE; - } - - #if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS) - if (toplevel_bindings_p () && ! DECL_COMMON (decl)) - DECL_INITIAL (decl) = build (CONSTRUCTOR, TREE_TYPE (decl), NULL_TREE, - NULL_TREE); - else - #endif - { - if (zero_init_p (TREE_TYPE (decl))) - DECL_INITIAL (decl) = error_mark_node; - /* Otherwise, force_store_init_value will have already stored a - zero-init initializer in DECL_INITIAL, that should be - retained. */ - } - - return init; - } - /* When parsing `int a[] = {1, 2};' we don't know the size of the array until we finish parsing the initializer. If that's the situation we're in, update DECL accordingly. */ --- 7672,7677 ---- *************** layout_var_decl (decl) *** 7693,7703 **** /* If we haven't already layed out this declaration, do so now. Note that we must not call complete type for an external object because it's type might involve templates that we are not ! supposed to isntantiate yet. (And it's perfectly legal to say `extern X x' for some incomplete type `X'.) */ if (!DECL_EXTERNAL (decl)) complete_type (type); ! if (!DECL_SIZE (decl) && COMPLETE_TYPE_P (type)) layout_decl (decl, 0); if (!DECL_EXTERNAL (decl) && DECL_SIZE (decl) == NULL_TREE) --- 7732,7747 ---- /* If we haven't already layed out this declaration, do so now. Note that we must not call complete type for an external object because it's type might involve templates that we are not ! supposed to isntantiate yet. (And it's perfectly valid to say `extern X x' for some incomplete type `X'.) */ if (!DECL_EXTERNAL (decl)) complete_type (type); ! if (!DECL_SIZE (decl) ! && TREE_TYPE (decl) != error_mark_node ! && (COMPLETE_TYPE_P (type) ! || (TREE_CODE (type) == ARRAY_TYPE ! && !TYPE_DOMAIN (type) ! && COMPLETE_TYPE_P (TREE_TYPE (type))))) layout_decl (decl, 0); if (!DECL_EXTERNAL (decl) && DECL_SIZE (decl) == NULL_TREE) *************** maybe_commonize_var (decl) *** 7750,7789 **** if (TREE_STATIC (decl) /* Don't mess with __FUNCTION__. */ && ! DECL_ARTIFICIAL (decl) ! && current_function_decl ! && DECL_CONTEXT (decl) == current_function_decl ! && (DECL_DECLARED_INLINE_P (current_function_decl) ! || DECL_TEMPLATE_INSTANTIATION (current_function_decl)) ! && TREE_PUBLIC (current_function_decl)) { ! /* If flag_weak, we don't need to mess with this, as we can just ! make the function weak, and let it refer to its unique local ! copy. This works because we don't allow the function to be ! inlined. */ ! if (! flag_weak) { ! if (DECL_INTERFACE_KNOWN (current_function_decl)) ! { ! TREE_PUBLIC (decl) = 1; ! DECL_EXTERNAL (decl) = DECL_EXTERNAL (current_function_decl); ! } ! else if (DECL_INITIAL (decl) == NULL_TREE ! || DECL_INITIAL (decl) == error_mark_node) { TREE_PUBLIC (decl) = 1; DECL_COMMON (decl) = 1; } ! /* else we lose. We can only do this if we can use common, ! which we can't if it has been initialized. */ ! ! if (!TREE_PUBLIC (decl)) { cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl); cp_warning_at (" you can work around this by removing the initializer", decl); } } - else - comdat_linkage (decl); } else if (DECL_LANG_SPECIFIC (decl) && DECL_COMDAT (decl)) /* Set it up again; we might have set DECL_INITIAL since the last --- 7794,7836 ---- if (TREE_STATIC (decl) /* Don't mess with __FUNCTION__. */ && ! DECL_ARTIFICIAL (decl) ! && DECL_FUNCTION_SCOPE_P (decl) ! /* Unfortunately, import_export_decl has not always been called ! before the function is processed, so we cannot simply check ! DECL_COMDAT. */ ! && (DECL_COMDAT (DECL_CONTEXT (decl)) ! || ((DECL_DECLARED_INLINE_P (DECL_CONTEXT (decl)) ! || DECL_TEMPLATE_INSTANTIATION (DECL_CONTEXT (decl))) ! && TREE_PUBLIC (DECL_CONTEXT (decl))))) { ! if (flag_weak) { ! /* With weak symbols, we simply make the variable COMDAT; ! that will cause copies in multiple translations units to ! be merged. */ ! comdat_linkage (decl); ! } ! else ! { ! if (DECL_INITIAL (decl) == NULL_TREE ! || DECL_INITIAL (decl) == error_mark_node) { + /* Without weak symbols, we can use COMMON to merge + uninitialized variables. */ TREE_PUBLIC (decl) = 1; DECL_COMMON (decl) = 1; } ! else { + /* While for initialized variables, we must use internal + linkage -- which means that multiple copies will not + be merged. */ + TREE_PUBLIC (decl) = 0; + DECL_COMMON (decl) = 0; cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl); cp_warning_at (" you can work around this by removing the initializer", decl); } } } else if (DECL_LANG_SPECIFIC (decl) && DECL_COMDAT (decl)) /* Set it up again; we might have set DECL_INITIAL since the last *************** check_for_uninitialized_const_var (decl) *** 7810,7862 **** error ("uninitialized const `%D'", decl); } ! /* Verify INIT (the initializer for DECL), and record the ! initialization in DECL_INITIAL, if appropriate. Returns a new ! value for INIT. */ static tree ! check_initializer (decl, init) ! tree decl; ! tree init; { ! tree type; ! if (TREE_CODE (decl) == FIELD_DECL) ! return init; ! type = TREE_TYPE (decl); ! /* If `start_decl' didn't like having an initialization, ignore it now. */ ! if (init != NULL_TREE && DECL_INITIAL (decl) == NULL_TREE) ! init = NULL_TREE; ! /* Check the initializer. */ ! if (init) { ! /* Things that are going to be initialized need to have complete ! type. */ ! TREE_TYPE (decl) = type = complete_type (TREE_TYPE (decl)); ! if (type == error_mark_node) ! /* We will have already complained. */ ! init = NULL_TREE; ! else if (COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type))) ! { ! error ("variable-sized object `%D' may not be initialized", decl); ! init = NULL_TREE; ! } ! else if (TREE_CODE (type) == ARRAY_TYPE ! && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (type)))) { ! error ("elements of array `%#D' have incomplete type", decl); ! init = NULL_TREE; } ! else if (TREE_CODE (type) != ARRAY_TYPE && !COMPLETE_TYPE_P (type)) { ! error ("`%D' has incomplete type", decl); ! TREE_TYPE (decl) = error_mark_node; ! init = NULL_TREE; } } if (TREE_CODE (decl) == CONST_DECL) --- 7857,8133 ---- error ("uninitialized const `%D'", decl); } ! /* FIELD is a FIELD_DECL or NULL. In the former case, the value ! returned is the next FIELD_DECL (possibly FIELD itself) that can be ! initialized. If there are no more such fields, the return value ! will be NULL. */ static tree ! next_initializable_field (tree field) { ! while (field ! && (TREE_CODE (field) != FIELD_DECL ! || (DECL_C_BIT_FIELD (field) && !DECL_NAME (field)) ! || DECL_ARTIFICIAL (field))) ! field = TREE_CHAIN (field); ! return field; ! } ! /* Undo the brace-elision allowed by [dcl.init.aggr] in a ! brace-enclosed aggregate initializer. ! *INITP is one of a list of initializers describing a brace-enclosed ! initializer for an entity of the indicated aggregate TYPE. It may ! not presently match the shape of the TYPE; for example: ! ! struct S { int a; int b; }; ! struct S a[] = { 1, 2, 3, 4 }; ! Here *INITP will point to TREE_LIST of four elements, rather than a ! list of two elements, each itself a list of two elements. This ! routine transforms INIT from the former form into the latter. The ! revised initializer is returned. */ ! ! static tree ! reshape_init (tree type, tree *initp) ! { ! tree inits; ! tree old_init; ! tree old_init_value; ! tree new_init; ! bool brace_enclosed_p; ! ! old_init = *initp; ! old_init_value = (TREE_CODE (*initp) == TREE_LIST ! ? TREE_VALUE (*initp) : old_init); ! ! /* For some parse errors, OLD_INIT_VALUE may be NULL. */ ! if (!old_init_value) { ! my_friendly_assert (TREE_CODE (old_init) == TREE_LIST, 20021202); ! TREE_VALUE (old_init) = error_mark_node; ! return old_init; ! } ! /* If the initializer is brace-enclosed, pull initializers from the ! enclosed elements. Advance past the brace-enclosed initializer ! now. */ ! if (TREE_CODE (old_init_value) == CONSTRUCTOR ! && TREE_HAS_CONSTRUCTOR (old_init_value)) ! { ! *initp = TREE_CHAIN (old_init); ! TREE_CHAIN (old_init) = NULL_TREE; ! inits = CONSTRUCTOR_ELTS (old_init_value); ! initp = &inits; ! brace_enclosed_p = true; ! } ! else ! { ! inits = NULL_TREE; ! brace_enclosed_p = false; ! } ! ! /* A non-aggregate type is always initialized with a single ! initializer. */ ! if (!CP_AGGREGATE_TYPE_P (type)) ! { ! *initp = TREE_CHAIN (old_init); ! TREE_CHAIN (old_init) = NULL_TREE; ! /* It is invalid to initialize a non-aggregate type with a ! brace-enclosed initializer. */ ! if (brace_enclosed_p) ! { ! error ("brace-enclosed initializer used to initialize `%T'", ! type); ! if (TREE_CODE (old_init) == TREE_LIST) ! TREE_VALUE (old_init) = error_mark_node; ! else ! old_init = error_mark_node; ! } ! ! return old_init; ! } ! ! /* [dcl.init.aggr] ! ! All implicit type conversions (clause _conv_) are considered when ! initializing the aggregate member with an initializer from an ! initializer-list. If the initializer can initialize a member, ! the member is initialized. Otherwise, if the member is itself a ! non-empty subaggregate, brace elision is assumed and the ! initializer is considered for the initialization of the first ! member of the subaggregate. */ ! if (CLASS_TYPE_P (type) ! && !brace_enclosed_p ! && can_convert_arg (type, TREE_TYPE (old_init_value), old_init_value)) ! { ! *initp = TREE_CHAIN (old_init); ! TREE_CHAIN (old_init) = NULL_TREE; ! return old_init; ! } ! ! if (TREE_CODE (old_init_value) == STRING_CST ! && TREE_CODE (type) == ARRAY_TYPE ! && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type)))) ! { ! /* [dcl.init.string] ! ! A char array (whether plain char, signed char, or unsigned char) ! can be initialized by a string-literal (optionally enclosed in ! braces); a wchar_t array can be initialized by a wide ! string-literal (optionally enclosed in braces). */ ! new_init = old_init; ! /* Move past the initializer. */ ! *initp = TREE_CHAIN (old_init); ! TREE_CHAIN (old_init) = NULL_TREE; ! } ! else ! { ! /* Build a CONSTRUCTOR to hold the contents of the aggregate. */ ! new_init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE); ! TREE_HAS_CONSTRUCTOR (new_init) = 1; ! ! if (CLASS_TYPE_P (type)) { ! tree field; ! ! field = next_initializable_field (TYPE_FIELDS (type)); ! ! if (!field) ! { ! /* [dcl.init.aggr] ! ! An initializer for an aggregate member that is an ! empty class shall have the form of an empty ! initializer-list {}. */ ! if (!brace_enclosed_p) ! error ("initializer for `%T' must be brace-enclosed", ! type); ! } ! else ! { ! /* Loop through the initializable fields, gathering ! initializers. */ ! while (*initp) ! { ! tree field_init; ! ! /* Handle designated initializers, as an extension. */ ! if (TREE_PURPOSE (*initp)) ! { ! if (pedantic) ! pedwarn ("ISO C++ does not allow designated initializers"); ! field = lookup_field_1 (type, TREE_PURPOSE (*initp), ! /*want_type=*/false); ! if (!field || TREE_CODE (field) != FIELD_DECL) ! error ("`%T' has no non-static data member named `%D'", ! type, TREE_PURPOSE (*initp)); ! } ! if (!field) ! break; ! ! field_init = reshape_init (TREE_TYPE (field), initp); ! TREE_CHAIN (field_init) = CONSTRUCTOR_ELTS (new_init); ! CONSTRUCTOR_ELTS (new_init) = field_init; ! /* [dcl.init.aggr] ! ! When a union is initialized with a brace-enclosed ! initializer, the braces shall only contain an ! initializer for the first member of the union. */ ! if (TREE_CODE (type) == UNION_TYPE) ! break; ! field = next_initializable_field (TREE_CHAIN (field)); ! } ! } } ! else if (TREE_CODE (type) == ARRAY_TYPE) { ! tree index; ! tree max_index; ! ! /* If the bound of the array is known, take no more initializers ! than are allowed. */ ! max_index = (TYPE_DOMAIN (type) ! ? array_type_nelts (type) : NULL_TREE); ! /* Loop through the array elements, gathering initializers. */ ! for (index = size_zero_node; ! *initp && (!max_index || !tree_int_cst_lt (max_index, index)); ! index = size_binop (PLUS_EXPR, index, size_one_node)) ! { ! tree element_init; ! ! element_init = reshape_init (TREE_TYPE (type), initp); ! TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init); ! CONSTRUCTOR_ELTS (new_init) = element_init; ! if (TREE_PURPOSE (element_init)) ! index = TREE_PURPOSE (element_init); ! } } + else + abort (); + + /* The initializers were placed in reverse order in the + CONSTRUCTOR. */ + CONSTRUCTOR_ELTS (new_init) = nreverse (CONSTRUCTOR_ELTS (new_init)); + + if (TREE_CODE (old_init) == TREE_LIST) + new_init = build_tree_list (TREE_PURPOSE (old_init), new_init); + } + + /* If this was a brace-enclosed initializer and all of the + initializers were not used up, there is a problem. */ + if (brace_enclosed_p && *initp) + error ("too many initializers for `%T'", type); + + return new_init; + } + + /* Verify INIT (the initializer for DECL), and record the + initialization in DECL_INITIAL, if appropriate. + + If the return value is non-NULL, it is an expression that must be + evaluated dynamically to initialize DECL. */ + + static tree + check_initializer (tree decl, tree init, int flags) + { + tree type = TREE_TYPE (decl); + + /* If `start_decl' didn't like having an initialization, ignore it now. */ + if (init != NULL_TREE && DECL_INITIAL (decl) == NULL_TREE) + init = NULL_TREE; + + /* If an initializer is present, DECL_INITIAL has been + error_mark_node, to indicate that an as-of-yet unevaluated + initialization will occur. From now on, DECL_INITIAL reflects + the static initialization -- if any -- of DECL. */ + DECL_INITIAL (decl) = NULL_TREE; + + /* Things that are going to be initialized need to have complete + type. */ + TREE_TYPE (decl) = type = complete_type (TREE_TYPE (decl)); + + if (type == error_mark_node) + /* We will have already complained. */ + init = NULL_TREE; + else if (init && COMPLETE_TYPE_P (type) + && !TREE_CONSTANT (TYPE_SIZE (type))) + { + error ("variable-sized object `%D' may not be initialized", decl); + init = NULL_TREE; + } + else if (TREE_CODE (type) == ARRAY_TYPE + && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (type)))) + { + error ("elements of array `%#D' have incomplete type", decl); + init = NULL_TREE; + } + else if (TREE_CODE (type) != ARRAY_TYPE && !COMPLETE_TYPE_P (type)) + { + error ("`%D' has incomplete type", decl); + TREE_TYPE (decl) = error_mark_node; + init = NULL_TREE; } if (TREE_CODE (decl) == CONST_DECL) *************** check_initializer (decl, init) *** 7869,7905 **** init = NULL_TREE; } else if (!DECL_EXTERNAL (decl) && TREE_CODE (type) == REFERENCE_TYPE) ! { ! init = grok_reference_init (decl, type, init); ! if (init) ! init = obscure_complex_init (decl, init); ! } ! else if (!DECL_EXTERNAL (decl) && !zero_init_p (type)) ! { ! force_store_init_value (decl, build_forced_zero_init (type)); ! ! if (init) ! goto process_init; ! } else if (init) { ! process_init: if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type)) { if (TREE_CODE (type) == ARRAY_TYPE) ! init = digest_init (type, init, (tree *) 0); else if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init)) { if (TYPE_NON_AGGREGATE_CLASS (type)) { error ("`%D' must be initialized by constructor, not by `{...}'", ! decl); init = error_mark_node; } else goto dont_use_constructor; } } else { --- 8140,8203 ---- init = NULL_TREE; } else if (!DECL_EXTERNAL (decl) && TREE_CODE (type) == REFERENCE_TYPE) ! init = grok_reference_init (decl, type, init); else if (init) { ! if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init)) ! { ! /* [dcl.init] paragraph 13, ! If T is a scalar type, then a declaration of the form ! T x = { a }; ! is equivalent to ! T x = a; ! ! reshape_init will complain about the extra braces, ! and doesn't do anything useful in the case where TYPE is ! scalar, so just don't call it. */ ! if (CP_AGGREGATE_TYPE_P (type)) ! init = reshape_init (type, &init); ! } ! ! /* If DECL has an array type without a specific bound, deduce the ! array size from the initializer. */ ! maybe_deduce_size_from_array_init (decl, init); ! type = TREE_TYPE (decl); ! if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init)) ! TREE_TYPE (init) = type; ! if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type)) { if (TREE_CODE (type) == ARRAY_TYPE) ! goto initialize_aggr; else if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init)) { if (TYPE_NON_AGGREGATE_CLASS (type)) { error ("`%D' must be initialized by constructor, not by `{...}'", ! decl); init = error_mark_node; } else goto dont_use_constructor; } + else + { + int saved_stmts_are_full_exprs_p; + + initialize_aggr: + saved_stmts_are_full_exprs_p = 0; + if (building_stmt_tree ()) + { + saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p (); + current_stmt_tree ()->stmts_are_full_exprs_p = 1; + } + init = build_aggr_init (decl, init, flags); + if (building_stmt_tree ()) + current_stmt_tree ()->stmts_are_full_exprs_p = + saved_stmts_are_full_exprs_p; + return init; + } } else { *************** check_initializer (decl, init) *** 7907,7943 **** if (TREE_CODE (init) != TREE_VEC) init = store_init_value (decl, init); } - - if (init) - /* We must hide the initializer so that expand_decl - won't try to do something it does not understand. */ - init = obscure_complex_init (decl, init); } else if (DECL_EXTERNAL (decl)) ; ! else if (TYPE_P (type) ! && (IS_AGGR_TYPE (type) || TYPE_NEEDS_CONSTRUCTING (type))) { tree core_type = strip_array_types (type); ! if (! TYPE_NEEDS_CONSTRUCTING (core_type)) ! { ! if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)) ! error ("structure `%D' with uninitialized const members", decl); ! if (CLASSTYPE_REF_FIELDS_NEED_INIT (core_type)) ! error ("structure `%D' with uninitialized reference members", ! decl); ! } check_for_uninitialized_const_var (decl); - - if (COMPLETE_TYPE_P (type) && TYPE_NEEDS_CONSTRUCTING (type)) - init = obscure_complex_init (decl, NULL_TREE); - } else check_for_uninitialized_const_var (decl); return init; } --- 8205,8233 ---- if (TREE_CODE (init) != TREE_VEC) init = store_init_value (decl, init); } } else if (DECL_EXTERNAL (decl)) ; ! else if (TYPE_P (type) && TYPE_NEEDS_CONSTRUCTING (type)) ! goto initialize_aggr; ! else if (IS_AGGR_TYPE (type)) { tree core_type = strip_array_types (type); ! if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)) ! error ("structure `%D' with uninitialized const members", decl); ! if (CLASSTYPE_REF_FIELDS_NEED_INIT (core_type)) ! error ("structure `%D' with uninitialized reference members", ! decl); check_for_uninitialized_const_var (decl); } else check_for_uninitialized_const_var (decl); + if (init && init != error_mark_node) + init = build (INIT_EXPR, type, decl, init); + return init; } *************** void *** 8035,8052 **** maybe_inject_for_scope_var (decl) tree decl; { if (!DECL_NAME (decl)) ! return; /* Declarations of __FUNCTION__ and its ilk appear magically when the variable is first used. If that happens to be inside a for-loop, we don't want to do anything special. */ if (DECL_PRETTY_FUNCTION_P (decl)) ! return; if (current_binding_level->is_for_scope) { ! struct binding_level *outer = current_binding_level->level_chain; /* Check to see if the same name is already bound at the outer --- 8325,8344 ---- maybe_inject_for_scope_var (decl) tree decl; { + timevar_push (TV_NAME_LOOKUP); + if (!DECL_NAME (decl)) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0); /* Declarations of __FUNCTION__ and its ilk appear magically when the variable is first used. If that happens to be inside a for-loop, we don't want to do anything special. */ if (DECL_PRETTY_FUNCTION_P (decl)) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0); if (current_binding_level->is_for_scope) { ! struct cp_binding_level *outer = current_binding_level->level_chain; /* Check to see if the same name is already bound at the outer *************** maybe_inject_for_scope_var (decl) *** 8058,8065 **** Otherwise, we need to preserve the temp slot for decl to last into the outer binding level. */ ! tree outer_binding ! = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (decl))); if (outer_binding && BINDING_LEVEL (outer_binding) == outer && (TREE_CODE (BINDING_VALUE (outer_binding)) --- 8350,8357 ---- Otherwise, we need to preserve the temp slot for decl to last into the outer binding level. */ ! cxx_binding *outer_binding ! = IDENTIFIER_BINDING (DECL_NAME (decl))->previous; if (outer_binding && BINDING_LEVEL (outer_binding) == outer && (TREE_CODE (BINDING_VALUE (outer_binding)) *************** maybe_inject_for_scope_var (decl) *** 8073,8111 **** else if (DECL_IN_MEMORY_P (decl)) preserve_temp_slots (DECL_RTL (decl)); } } /* Generate code to initialize DECL (a local variable). */ ! void ! initialize_local_var (decl, init, flags) tree decl; tree init; - int flags; { tree type = TREE_TYPE (decl); ! /* If the type is bogus, don't bother initializing the variable. */ ! if (type == error_mark_node) ! return; ! if (DECL_SIZE (decl) == NULL_TREE && !TREE_STATIC (decl)) { /* If we used it already as memory, it must stay in memory. */ DECL_INITIAL (decl) = NULL_TREE; TREE_ADDRESSABLE (decl) = TREE_USED (decl); } - /* Local statics are handled differently from ordinary automatic - variables. */ - if (TREE_STATIC (decl)) - { - if (TYPE_NEEDS_CONSTRUCTING (type) || init != NULL_TREE - || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) - expand_static_init (decl, init); - return; - } - if (DECL_SIZE (decl) && type != error_mark_node) { int already_used; --- 8365,8395 ---- else if (DECL_IN_MEMORY_P (decl)) preserve_temp_slots (DECL_RTL (decl)); } + + timevar_pop (TV_NAME_LOOKUP); } /* Generate code to initialize DECL (a local variable). */ ! static void ! initialize_local_var (decl, init) tree decl; tree init; { tree type = TREE_TYPE (decl); ! my_friendly_assert (TREE_CODE (decl) == VAR_DECL ! || TREE_CODE (decl) == RESULT_DECL, ! 20021010); ! my_friendly_assert (!TREE_STATIC (decl), 20021010); ! if (DECL_SIZE (decl) == NULL_TREE) { /* If we used it already as memory, it must stay in memory. */ DECL_INITIAL (decl) = NULL_TREE; TREE_ADDRESSABLE (decl) = TREE_USED (decl); } if (DECL_SIZE (decl) && type != error_mark_node) { int already_used; *************** initialize_local_var (decl, init, flags) *** 8113,8126 **** /* Compute and store the initial value. */ already_used = TREE_USED (decl) || TREE_USED (type); ! if (init || TYPE_NEEDS_CONSTRUCTING (type)) { int saved_stmts_are_full_exprs_p; my_friendly_assert (building_stmt_tree (), 20000906); saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p (); current_stmt_tree ()->stmts_are_full_exprs_p = 1; ! finish_expr_stmt (build_aggr_init (decl, init, flags)); current_stmt_tree ()->stmts_are_full_exprs_p = saved_stmts_are_full_exprs_p; } --- 8397,8411 ---- /* Compute and store the initial value. */ already_used = TREE_USED (decl) || TREE_USED (type); ! /* Perform the initialization. */ ! if (init) { int saved_stmts_are_full_exprs_p; my_friendly_assert (building_stmt_tree (), 20000906); saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p (); current_stmt_tree ()->stmts_are_full_exprs_p = 1; ! finish_expr_stmt (init); current_stmt_tree ()->stmts_are_full_exprs_p = saved_stmts_are_full_exprs_p; } *************** initialize_local_var (decl, init, flags) *** 8139,8177 **** else if (already_used) TREE_USED (decl) = 1; } - } - - /* Generate code to destroy DECL (a local variable). */ - - static void - destroy_local_var (decl) - tree decl; - { - tree type = TREE_TYPE (decl); - tree cleanup; ! /* Only variables get cleaned up. */ ! if (TREE_CODE (decl) != VAR_DECL) ! return; ! ! /* And only things with destructors need cleaning up. */ ! if (type == error_mark_node ! || TYPE_HAS_TRIVIAL_DESTRUCTOR (type)) ! return; ! ! if (TREE_CODE (decl) == VAR_DECL && ! (DECL_EXTERNAL (decl) || TREE_STATIC (decl))) ! /* We don't clean up things that aren't defined in this ! translation unit, or that need a static cleanup. The latter ! are handled by finish_file. */ ! return; ! ! /* Compute the cleanup. */ ! cleanup = maybe_build_cleanup (decl); ! /* Record the cleanup required for this declaration. */ ! if (DECL_SIZE (decl) && cleanup) ! finish_decl_cleanup (decl, cleanup); } /* Finish processing of a declaration; --- 8424,8442 ---- else if (already_used) TREE_USED (decl) = 1; } ! /* Generate a cleanup, if necessary. */ ! if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) ! { ! tree cleanup; ! /* Compute the cleanup. */ ! cleanup = cxx_maybe_build_cleanup (decl); ! ! /* Record the cleanup required for this declaration. */ ! if (DECL_SIZE (decl) && cleanup) ! finish_decl_cleanup (decl, cleanup); ! } } /* Finish processing of a declaration; *************** cp_finish_decl (decl, init, asmspec_tree *** 8228,8234 **** && DECL_CONTEXT (decl) != current_namespace && init) { ! /* Leave the namespace of the object. */ pop_decl_namespace (); } --- 8493,8499 ---- && DECL_CONTEXT (decl) != current_namespace && init) { ! /* Leave the namespace of the object. */ pop_decl_namespace (); } *************** cp_finish_decl (decl, init, asmspec_tree *** 8301,8310 **** SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec)); make_decl_rtl (decl, asmspec); } ! ! /* Deduce size of array from initialization, if not already known. */ ! init = check_initializer (decl, init); ! maybe_deduce_size_from_array_init (decl, init); /* Add this declaration to the statement-tree. This needs to happen after the call to check_initializer so that the DECL_STMT for a --- 8566,8624 ---- SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec)); make_decl_rtl (decl, asmspec); } ! else if (TREE_CODE (decl) == RESULT_DECL) ! init = check_initializer (decl, init, flags); ! else if (TREE_CODE (decl) == VAR_DECL) ! { ! /* Only PODs can have thread-local storage. Other types may require ! various kinds of non-trivial initialization. */ ! if (DECL_THREAD_LOCAL (decl) && !pod_type_p (TREE_TYPE (decl))) ! error ("`%D' cannot be thread-local because it has non-POD type `%T'", ! decl, TREE_TYPE (decl)); ! /* Convert the initializer to the type of DECL, if we have not ! already initialized DECL. */ ! if (!DECL_INITIALIZED_P (decl) ! /* If !DECL_EXTERNAL then DECL is being defined. In the ! case of a static data member initialized inside the ! class-specifier, there can be an initializer even if DECL ! is *not* defined. */ ! && (!DECL_EXTERNAL (decl) || init)) ! { ! init = check_initializer (decl, init, flags); ! /* Thread-local storage cannot be dynamically initialized. */ ! if (DECL_THREAD_LOCAL (decl) && init) ! { ! error ("`%D' is thread-local and so cannot be dynamically " ! "initialized", decl); ! init = NULL_TREE; ! } ! /* Handle: ! ! [dcl.init] ! ! The memory occupied by any object of static storage ! duration is zero-initialized at program startup before ! any other initialization takes place. ! ! We cannot create an appropriate initializer until after ! the type of DECL is finalized. If DECL_INITIAL is set, ! then the DECL is statically initialized, and any ! necessary zero-initialization has already been performed. */ ! if (TREE_STATIC (decl) && !DECL_INITIAL (decl)) ! DECL_INITIAL (decl) = build_zero_init (TREE_TYPE (decl), ! /*nelts=*/NULL_TREE, ! /*static_storage_p=*/true); ! /* Remember that the initialization for this variable has ! taken place. */ ! DECL_INITIALIZED_P (decl) = 1; ! } ! /* If the variable has an array type, lay out the type, even if ! there is no initializer. It is valid to index through the ! array, and we must get TYPE_ALIGN set correctly on the array ! type. */ ! else if (TREE_CODE (type) == ARRAY_TYPE) ! layout_type (type); ! } /* Add this declaration to the statement-tree. This needs to happen after the call to check_initializer so that the DECL_STMT for a *************** cp_finish_decl (decl, init, asmspec_tree *** 8335,8341 **** else abstract_virtuals_error (decl, strip_array_types (type)); ! if (TREE_CODE (decl) == FUNCTION_DECL) ; else if (DECL_EXTERNAL (decl) && ! (DECL_LANG_SPECIFIC (decl) --- 8649,8657 ---- else abstract_virtuals_error (decl, strip_array_types (type)); ! if (TREE_CODE (decl) == FUNCTION_DECL ! || TREE_TYPE (decl) == error_mark_node) ! /* No initialization required. */ ; else if (DECL_EXTERNAL (decl) && ! (DECL_LANG_SPECIFIC (decl) *************** cp_finish_decl (decl, init, asmspec_tree *** 8344,8378 **** if (init) DECL_INITIAL (decl) = init; } ! else if (TREE_CODE (CP_DECL_CONTEXT (decl)) == FUNCTION_DECL) { ! /* This is a local declaration. */ ! if (doing_semantic_analysis_p ()) ! maybe_inject_for_scope_var (decl); ! /* Initialize the local variable. But, if we're building a ! statement-tree, we'll do the initialization when we ! expand the tree. */ ! if (processing_template_decl) ! { ! if (init || DECL_INITIAL (decl) == error_mark_node) ! DECL_INITIAL (decl) = init; ! } ! else { ! /* If we're not building RTL, then we need to do so ! now. */ ! my_friendly_assert (building_stmt_tree (), 20000906); ! /* Initialize the variable. */ ! initialize_local_var (decl, init, flags); ! /* Clean up the variable. */ ! destroy_local_var (decl); } ! } ! else if (TREE_STATIC (decl) && type != error_mark_node) ! { ! /* Cleanups for static variables are handled by `finish_file'. */ ! if (TYPE_NEEDS_CONSTRUCTING (type) || init != NULL_TREE ! || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) expand_static_init (decl, init); } finish_end0: --- 8660,8684 ---- if (init) DECL_INITIAL (decl) = init; } ! else { ! /* A variable definition. */ ! if (DECL_FUNCTION_SCOPE_P (decl)) { ! /* This is a local declaration. */ ! if (doing_semantic_analysis_p ()) ! maybe_inject_for_scope_var (decl); ! /* Initialize the local variable. */ ! if (processing_template_decl) ! { ! if (init || DECL_INITIAL (decl) == error_mark_node) ! DECL_INITIAL (decl) = init; ! } ! else if (!TREE_STATIC (decl)) ! initialize_local_var (decl, init); } ! ! if (TREE_STATIC (decl)) expand_static_init (decl, init); } finish_end0: *************** declare_global_var (name, type) *** 8440,8446 **** } /* Returns a pointer to the `atexit' function. Note that if ! FLAG_USE_CXA_ATEXIT is non-zero, then this will actually be the new `__cxa_atexit' function specified in the IA64 C++ ABI. */ static tree --- 8746,8752 ---- } /* Returns a pointer to the `atexit' function. Note that if ! FLAG_USE_CXA_ATEXIT is nonzero, then this will actually be the new `__cxa_atexit' function specified in the IA64 C++ ABI. */ static tree *************** start_cleanup_fn () *** 8569,8577 **** { tree parmdecl; ! parmdecl = build_decl (PARM_DECL, NULL_TREE, ptr_type_node); DECL_CONTEXT (parmdecl) = fndecl; - DECL_ARG_TYPE (parmdecl) = ptr_type_node; TREE_USED (parmdecl) = 1; DECL_ARGUMENTS (fndecl) = parmdecl; } --- 8875,8882 ---- { tree parmdecl; ! parmdecl = cp_build_parm_decl (NULL_TREE, ptr_type_node); DECL_CONTEXT (parmdecl) = fndecl; TREE_USED (parmdecl) = 1; DECL_ARGUMENTS (fndecl) = parmdecl; } *************** register_dtor_fn (decl) *** 8638,8644 **** end_cleanup_fn (); /* Call atexit with the cleanup function. */ ! mark_addressable (cleanup); cleanup = build_unary_op (ADDR_EXPR, cleanup, 0); if (flag_use_cxa_atexit) { --- 8943,8949 ---- end_cleanup_fn (); /* Call atexit with the cleanup function. */ ! cxx_mark_addressable (cleanup); cleanup = build_unary_op (ADDR_EXPR, cleanup, 0); if (flag_use_cxa_atexit) { *************** register_dtor_fn (decl) *** 8653,8664 **** finish_expr_stmt (build_function_call (get_atexit_node (), args)); } ! void expand_static_init (decl, init) tree decl; tree init; { ! tree oldstatic = value_member (decl, static_aggregates); if (oldstatic) { --- 8958,8984 ---- finish_expr_stmt (build_function_call (get_atexit_node (), args)); } ! /* DECL is a VAR_DECL with static storage duration. INIT, if present, ! is its initializer. Generate code to handle the construction ! and destruction of DECL. */ ! ! static void expand_static_init (decl, init) tree decl; tree init; { ! tree oldstatic; ! ! my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 20021010); ! my_friendly_assert (TREE_STATIC (decl), 20021010); ! ! /* Some variables require no initialization. */ ! if (!init ! && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)) ! && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl))) ! return; ! ! oldstatic = value_member (decl, static_aggregates); if (oldstatic) { *************** expand_static_init (decl, init) *** 8708,8722 **** then_clause = begin_compound_stmt (/*has_no_scope=*/0); /* Do the initialization itself. */ ! if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)) ! || (init && TREE_CODE (init) == TREE_LIST)) ! assignment = build_aggr_init (decl, init, 0); ! else if (init) ! /* The initialization we're doing here is just a bitwise ! copy. */ ! assignment = build (INIT_EXPR, TREE_TYPE (decl), decl, init); ! else ! assignment = NULL_TREE; /* Once the assignment is complete, set TEMP to 1. Since the construction of the static object is complete at this point, --- 9028,9034 ---- then_clause = begin_compound_stmt (/*has_no_scope=*/0); /* Do the initialization itself. */ ! assignment = init ? init : NULL_TREE; /* Once the assignment is complete, set TEMP to 1. Since the construction of the static object is complete at this point, *************** grokfndecl (ctype, type, declarator, ori *** 8956,8962 **** type = build_exception_variant (type, raises); decl = build_lang_decl (FUNCTION_DECL, declarator, type); ! /* Propagate volatile out from type to decl. */ if (TYPE_VOLATILE (type)) TREE_THIS_VOLATILE (decl) = 1; --- 9268,9274 ---- type = build_exception_variant (type, raises); decl = build_lang_decl (FUNCTION_DECL, declarator, type); ! /* Propagate volatile out from type to decl. */ if (TYPE_VOLATILE (type)) TREE_THIS_VOLATILE (decl) = 1; *************** grokfndecl (ctype, type, declarator, ori *** 9047,9059 **** DECL_NOT_REALLY_EXTERN (decl) = 1; } /* If the declaration was declared inline, mark it as such. */ if (inlinep) DECL_DECLARED_INLINE_P (decl) = 1; /* We inline functions that are explicitly declared inline, or, when the user explicitly asks us to, all functions. */ ! if (DECL_DECLARED_INLINE_P (decl) || flag_inline_trees == 2) DECL_INLINE (decl) = 1; DECL_EXTERNAL (decl) = 1; if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE) --- 9359,9377 ---- DECL_NOT_REALLY_EXTERN (decl) = 1; } + DID_INLINE_FUNC (decl) = 0; /* If the declaration was declared inline, mark it as such. */ if (inlinep) DECL_DECLARED_INLINE_P (decl) = 1; /* We inline functions that are explicitly declared inline, or, when the user explicitly asks us to, all functions. */ ! if (DECL_DECLARED_INLINE_P (decl)) DECL_INLINE (decl) = 1; + if (flag_inline_trees == 2 && !DECL_INLINE (decl)) + { + DID_INLINE_FUNC (decl) = 1; + DECL_INLINE (decl) = 1; + } DECL_EXTERNAL (decl) = 1; if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE) *************** grokfndecl (ctype, type, declarator, ori *** 9107,9113 **** /* Due to bison parser ickiness, we will have already looked up an operator_name or PFUNCNAME within the current class (see template_id in parse.y). If the current class contains ! such a name, we'll get a COMPONENT_REF here. Undo that. */ my_friendly_assert (TREE_TYPE (TREE_OPERAND (fns, 0)) == current_class_type, 20001120); --- 9425,9431 ---- /* Due to bison parser ickiness, we will have already looked up an operator_name or PFUNCNAME within the current class (see template_id in parse.y). If the current class contains ! such a name, we'll get a COMPONENT_REF here. Undo that. */ my_friendly_assert (TREE_TYPE (TREE_OPERAND (fns, 0)) == current_class_type, 20001120); *************** grokfndecl (ctype, type, declarator, ori *** 9199,9205 **** decl = DECL_TEMPLATE_RESULT (decl); /* Attempt to merge the declarations. This can fail, in ! the case of some illegal specialization declarations. */ if (!duplicate_decls (decl, old_decl)) error ("no `%#D' member function declared in class `%T'", decl, ctype); --- 9517,9523 ---- decl = DECL_TEMPLATE_RESULT (decl); /* Attempt to merge the declarations. This can fail, in ! the case of some invalid specialization declarations. */ if (!duplicate_decls (decl, old_decl)) error ("no `%#D' member function declared in class `%T'", decl, ctype); *************** grokfndecl (ctype, type, declarator, ori *** 9219,9282 **** return decl; } static tree ! grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace) tree type; ! tree declarator; RID_BIT_TYPE *specbits_in; int initialized; int constp; ! tree in_namespace; { tree decl; RID_BIT_TYPE specbits; specbits = *specbits_in; ! if (TREE_CODE (type) == OFFSET_TYPE) { ! /* If you declare a static member so that it ! can be initialized, the code will reach here. */ ! tree basetype = TYPE_OFFSET_BASETYPE (type); ! type = TREE_TYPE (type); ! decl = build_lang_decl (VAR_DECL, declarator, type); ! DECL_CONTEXT (decl) = basetype; } - else - { - tree context; - - if (in_namespace) - context = in_namespace; - else if (namespace_bindings_p () || RIDBIT_SETP (RID_EXTERN, specbits)) - context = current_namespace; - else - context = NULL_TREE; ! /* For namespace-scope variables, declared in a template, we ! need the full lang_decl. The same is true for ! namespace-scope variables that do not have C++ language ! linkage. */ ! if (context ! && (processing_template_decl ! || current_lang_name != lang_name_cplusplus)) ! decl = build_lang_decl (VAR_DECL, declarator, type); ! else ! decl = build_decl (VAR_DECL, declarator, type); ! ! if (context) ! set_decl_namespace (decl, context, 0); ! context = DECL_CONTEXT (decl); ! if (declarator && context && current_lang_name != lang_name_c) ! /* We can't mangle lazily here because we don't have any ! way to recover whether or not a variable was `extern ! "C"' later. */ ! mangle_decl (decl); ! } ! if (in_namespace) ! set_decl_namespace (decl, in_namespace, 0); if (RIDBIT_SETP (RID_EXTERN, specbits)) { --- 9537,9604 ---- return decl; } + /* Create a VAR_DECL named NAME with the indicated TYPE. + + If SCOPE is non-NULL, it is the class type or namespace containing + the variable. If SCOPE is NULL, the variable should is created in + the innermost enclosings scope. */ + static tree ! grokvardecl (type, name, specbits_in, initialized, constp, scope) tree type; ! tree name; RID_BIT_TYPE *specbits_in; int initialized; int constp; ! tree scope; { tree decl; RID_BIT_TYPE specbits; + my_friendly_assert (!name || TREE_CODE (name) == IDENTIFIER_NODE, + 20020808); + specbits = *specbits_in; ! /* Compute the scope in which to place the variable. */ ! if (!scope) { ! /* An explicit "extern" specifier indicates a namespace-scope ! variable. */ ! if (RIDBIT_SETP (RID_EXTERN, specbits)) ! scope = current_namespace; ! else if (!at_function_scope_p ()) ! { ! scope = current_scope (); ! if (!scope) ! scope = current_namespace; ! } } ! if (scope ! && (/* If the variable is a namespace-scope variable declared in a ! template, we need DECL_LANG_SPECIFIC. */ ! (TREE_CODE (scope) == NAMESPACE_DECL && processing_template_decl) ! /* Similarly for namespace-scope variables with language linkage ! other than C++. */ ! || (TREE_CODE (scope) == NAMESPACE_DECL ! && current_lang_name != lang_name_cplusplus) ! /* Similarly for static data members. */ ! || TYPE_P (scope))) ! decl = build_lang_decl (VAR_DECL, name, type); ! else ! decl = build_decl (VAR_DECL, name, type); ! if (scope && TREE_CODE (scope) == NAMESPACE_DECL) ! set_decl_namespace (decl, scope, 0); ! else ! DECL_CONTEXT (decl) = scope; ! if (name && scope && current_lang_name != lang_name_c) ! /* We can't mangle lazily here because we don't have any ! way to recover whether or not a variable was `extern ! "C"' later. */ ! mangle_decl (decl); if (RIDBIT_SETP (RID_EXTERN, specbits)) { *************** grokvardecl (type, declarator, specbits_ *** 9307,9312 **** --- 9629,9644 ---- TREE_PUBLIC (decl) = DECL_EXTERNAL (decl); } + if (RIDBIT_SETP (RID_THREAD, specbits)) + { + if (targetm.have_tls) + DECL_THREAD_LOCAL (decl) = 1; + else + /* A mere warning is sure to result in improper semantics + at runtime. Don't bother to allow this to compile. */ + error ("thread-local storage not supported for this target"); + } + if (TREE_PUBLIC (decl)) { /* [basic.link]: A name with no linkage (notably, the name of a class *************** grokvardecl (type, declarator, specbits_ *** 9332,9339 **** TYPE, which is a POINTER_TYPE to a METHOD_TYPE. */ tree ! build_ptrmemfunc_type (type) ! tree type; { tree fields[4]; tree t; --- 9664,9670 ---- TYPE, which is a POINTER_TYPE to a METHOD_TYPE. */ tree ! build_ptrmemfunc_type (tree type) { tree fields[4]; tree t; *************** build_ptrmemfunc_type (type) *** 9392,9397 **** --- 9723,9736 ---- return t; } + /* Create and return a pointer to data member type. */ + + tree + build_ptrmem_type (tree class_type, tree member_type) + { + return build_pointer_type (build_offset_type (class_type, member_type)); + } + /* DECL is a VAR_DECL defined in-class, whose TYPE is also given. Check to see that the definition is valid. Issue appropriate error messages. Return 1 if the definition is particularly bad, or 0 *************** compute_array_index_type (name, size) *** 9460,9466 **** size, integer_one_node)); } ! /* The size might be the result of a cast. */ STRIP_TYPE_NOPS (size); /* It might be a const variable or enumeration constant. */ --- 9799,9805 ---- size, integer_one_node)); } ! /* The size might be the result of a cast. */ STRIP_TYPE_NOPS (size); /* It might be a const variable or enumeration constant. */ *************** grokdeclarator (declarator, declspecs, d *** 9865,9871 **** break; case ADDR_EXPR: /* C++ reference declaration */ ! /* Fall through. */ case ARRAY_REF: case INDIRECT_REF: ctype = NULL_TREE; --- 10204,10210 ---- break; case ADDR_EXPR: /* C++ reference declaration */ ! /* Fall through. */ case ARRAY_REF: case INDIRECT_REF: ctype = NULL_TREE; *************** grokdeclarator (declarator, declspecs, d *** 9883,9888 **** --- 10222,10233 ---- tree attributes; + if (decl_context != NORMAL) + { + error ("variable declaration is not allowed here"); + return error_mark_node; + } + *next = TREE_OPERAND (decl, 0); init = CALL_DECLARATOR_PARMS (decl); *************** grokdeclarator (declarator, declspecs, d *** 9907,9913 **** } else error ("invalid declarator"); ! return 0; } innermost_code = TREE_CODE (decl); if (decl_context == FIELD && ctype == NULL_TREE) --- 10252,10258 ---- } else error ("invalid declarator"); ! return NULL_TREE; } innermost_code = TREE_CODE (decl); if (decl_context == FIELD && ctype == NULL_TREE) *************** grokdeclarator (declarator, declspecs, d *** 9915,9924 **** if (ctype && TREE_OPERAND (decl, 0) && (TREE_CODE (TREE_OPERAND (decl, 0)) == TYPE_DECL ! && ((DECL_NAME (TREE_OPERAND (decl, 0)) ! == constructor_name_full (ctype)) ! || (DECL_NAME (TREE_OPERAND (decl, 0)) ! == constructor_name (ctype))))) TREE_OPERAND (decl, 0) = constructor_name (ctype); next = &TREE_OPERAND (decl, 0); decl = *next; --- 10260,10267 ---- if (ctype && TREE_OPERAND (decl, 0) && (TREE_CODE (TREE_OPERAND (decl, 0)) == TYPE_DECL ! && constructor_name_p (DECL_NAME (TREE_OPERAND (decl, 0)), ! ctype))) TREE_OPERAND (decl, 0) = constructor_name (ctype); next = &TREE_OPERAND (decl, 0); decl = *next; *************** grokdeclarator (declarator, declspecs, d *** 9949,9955 **** dname = DECL_NAME (get_first_fn (dname)); } } ! /* Fall through. */ case IDENTIFIER_NODE: if (TREE_CODE (decl) == IDENTIFIER_NODE) --- 10292,10298 ---- dname = DECL_NAME (get_first_fn (dname)); } } ! /* Fall through. */ case IDENTIFIER_NODE: if (TREE_CODE (decl) == IDENTIFIER_NODE) *************** grokdeclarator (declarator, declspecs, d *** 10024,10034 **** ctype = cname; } if (ctype && TREE_CODE (TREE_OPERAND (decl, 1)) == TYPE_DECL ! && ((DECL_NAME (TREE_OPERAND (decl, 1)) ! == constructor_name_full (ctype)) ! || (DECL_NAME (TREE_OPERAND (decl, 1)) ! == constructor_name (ctype)))) TREE_OPERAND (decl, 1) = constructor_name (ctype); next = &TREE_OPERAND (decl, 1); decl = *next; --- 10367,10383 ---- ctype = cname; } + /* If the parser sees something like "void a::b" where + "a::b" is a namespace, it will build a SCOPE_REF with + a NAMESPACE_DECL, rather than an IDENTIFIER_NODE, as + the second operand. Since the SCOPE_REF is being + used as a declarator, we recover from that here. */ + if (TREE_CODE (TREE_OPERAND (decl, 1)) == NAMESPACE_DECL) + TREE_OPERAND (decl, 1) = DECL_NAME (TREE_OPERAND (decl, 1)); + if (ctype && TREE_CODE (TREE_OPERAND (decl, 1)) == TYPE_DECL ! && constructor_name_p (DECL_NAME (TREE_OPERAND (decl, 1)), ! ctype)) TREE_OPERAND (decl, 1) = constructor_name (ctype); next = &TREE_OPERAND (decl, 1); decl = *next; *************** grokdeclarator (declarator, declspecs, d *** 10042,10049 **** } else if (TREE_CODE (decl) == BIT_NOT_EXPR && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE ! && (constructor_name (ctype) == TREE_OPERAND (decl, 0) ! || constructor_name_full (ctype) == TREE_OPERAND (decl, 0))) { sfk = sfk_destructor; ctor_return_type = ctype; --- 10391,10398 ---- } else if (TREE_CODE (decl) == BIT_NOT_EXPR && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE ! && constructor_name_p (TREE_OPERAND (decl, 0), ! ctype)) { sfk = sfk_destructor; ctor_return_type = ctype; *************** grokdeclarator (declarator, declspecs, d *** 10077,10094 **** next = 0; break; case TEMPLATE_DECL: /* Sometimes, we see a template-name used as part of a decl-specifier like in ! std::allocator alloc; ! Handle that gracefully. */ ! error ("invalid use of template-name '%E' in a declarator", ! decl); return error_mark_node; break; ! default: ! internal_error ("`%D' as declarator", decl); } } } --- 10426,10446 ---- next = 0; break; + case BASELINK: + next = &BASELINK_FUNCTIONS (decl); + break; + case TEMPLATE_DECL: /* Sometimes, we see a template-name used as part of a decl-specifier like in ! std::allocator alloc; ! Handle that gracefully. */ ! error ("invalid use of template-name '%E' in a declarator", decl); return error_mark_node; break; ! default: ! my_friendly_assert (0, 20020917); } } } *************** grokdeclarator (declarator, declspecs, d *** 10123,10129 **** if (decl_context == NORMAL && !toplevel_bindings_p ()) { ! struct binding_level *b = current_binding_level; current_binding_level = b->level_chain; if (current_binding_level != 0 && toplevel_bindings_p ()) decl_context = PARM; --- 10475,10481 ---- if (decl_context == NORMAL && !toplevel_bindings_p ()) { ! struct cp_binding_level *b = current_binding_level; current_binding_level = b->level_chain; if (current_binding_level != 0 && toplevel_bindings_p ()) decl_context = PARM; *************** grokdeclarator (declarator, declspecs, d *** 10219,10228 **** --- 10571,10592 ---- } else if (RIDBIT_SETP (i, specbits)) pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id)); + + /* Diagnose "__thread extern". Recall that this list + is in the reverse order seen in the text. */ + if (i == (int)RID_THREAD) + { + if (RIDBIT_SETP (RID_EXTERN, specbits)) + error ("`__thread' before `extern'"); + if (RIDBIT_SETP (RID_STATIC, specbits)) + error ("`__thread' before `static'"); + } + if (i == (int)RID_EXTERN && TREE_PURPOSE (spec) == error_mark_node) /* This extern was part of a language linkage. */ extern_langp = 1; + RIDBIT_SET (i, specbits); goto found; } *************** grokdeclarator (declarator, declspecs, d *** 10431,10437 **** else if (type == char_type_node) type = unsigned_char_type_node; else if (typedef_decl) ! type = unsigned_type (type); else type = unsigned_type_node; } --- 10795,10801 ---- else if (type == char_type_node) type = unsigned_char_type_node; else if (typedef_decl) ! type = c_common_unsigned_type (type); else type = unsigned_type_node; } *************** grokdeclarator (declarator, declspecs, d *** 10519,10524 **** --- 10883,10889 ---- { if (RIDBIT_SETP (RID_STATIC, specbits)) nclasses++; if (RIDBIT_SETP (RID_EXTERN, specbits) && !extern_langp) nclasses++; + if (RIDBIT_SETP (RID_THREAD, specbits)) nclasses++; if (decl_context == PARM && nclasses > 0) error ("storage class specifiers invalid in parameter declarations"); if (RIDBIT_SETP (RID_TYPEDEF, specbits)) *************** grokdeclarator (declarator, declspecs, d *** 10550,10555 **** --- 10915,10927 ---- /* Warn about storage classes that are invalid for certain kinds of declarations (parameters, typenames, etc.). */ + /* "static __thread" and "extern __thread" are allowed. */ + if (nclasses == 2 + && RIDBIT_SETP (RID_THREAD, specbits) + && (RIDBIT_SETP (RID_EXTERN, specbits) + || RIDBIT_SETP (RID_STATIC, specbits))) + nclasses = 1; + if (nclasses > 1) error ("multiple storage classes in declaration of `%s'", name); else if (decl_context != NORMAL && nclasses > 0) *************** grokdeclarator (declarator, declspecs, d *** 10605,10610 **** --- 10977,10983 ---- RIDBIT_RESET (RID_REGISTER, specbits); RIDBIT_RESET (RID_AUTO, specbits); RIDBIT_RESET (RID_EXTERN, specbits); + RIDBIT_RESET (RID_THREAD, specbits); } } else if (RIDBIT_SETP (RID_EXTERN, specbits) && initialized && !funcdef_flag) *************** grokdeclarator (declarator, declspecs, d *** 10627,10639 **** if (RIDBIT_SETP (RID_AUTO, specbits)) error ("top-level declaration of `%s' specifies `auto'", name); } if (nclasses > 0 && friendp) error ("storage class specifiers invalid in friend function declarations"); /* Now figure out the structure of the declarator proper. Descend through it, creating more complex types, until we reach ! the declared identifier (or NULL_TREE, in an absolute declarator). */ while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE && TREE_CODE (declarator) != TEMPLATE_ID_EXPR) --- 11000,11020 ---- if (RIDBIT_SETP (RID_AUTO, specbits)) error ("top-level declaration of `%s' specifies `auto'", name); } + else if (RIDBIT_SETP (RID_THREAD, specbits) + && !RIDBIT_SETP (RID_EXTERN, specbits) + && !RIDBIT_SETP (RID_STATIC, specbits)) + { + error ("function-scope `%s' implicitly auto and declared `__thread'", + name); + RIDBIT_RESET (RID_THREAD, specbits); + } if (nclasses > 0 && friendp) error ("storage class specifiers invalid in friend function declarations"); /* Now figure out the structure of the declarator proper. Descend through it, creating more complex types, until we reach ! the declared identifier (or NULL_TREE, in an abstract declarator). */ while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE && TREE_CODE (declarator) != TEMPLATE_ID_EXPR) *************** grokdeclarator (declarator, declspecs, d *** 10925,10945 **** if (TREE_CODE (type) == REFERENCE_TYPE) { ! error ("cannot declare %s to references", ! TREE_CODE (declarator) == ADDR_EXPR ! ? "references" : "pointers"); ! declarator = TREE_OPERAND (declarator, 0); ! continue; ! } ! ! if (TREE_CODE (type) == OFFSET_TYPE ! && (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE ! || TREE_CODE (TREE_TYPE (type)) == REFERENCE_TYPE)) ! { ! error ("cannot declare pointer to `%#T' member", ! TREE_TYPE (type)); type = TREE_TYPE (type); } /* Merge any constancy or volatility into the target type for the pointer. */ --- 11306,11320 ---- if (TREE_CODE (type) == REFERENCE_TYPE) { ! error (TREE_CODE (declarator) == ADDR_EXPR ! ? "cannot declare reference to `%#T'" ! : "cannot declare pointer to `%#T'", type); type = TREE_TYPE (type); } + else if (VOID_TYPE_P (type) + && (ctype || TREE_CODE (declarator) == ADDR_EXPR)) + error (ctype ? "cannot declare pointer to `%#T' member" + : "cannot declare reference to `%#T'", type); /* Merge any constancy or volatility into the target type for the pointer. */ *************** grokdeclarator (declarator, declspecs, d *** 10950,10962 **** if (TREE_CODE (declarator) == ADDR_EXPR) { ! if (TREE_CODE (type) == VOID_TYPE) ! error ("invalid type: `void &'"); ! else type = build_reference_type (type); } else if (TREE_CODE (type) == METHOD_TYPE) type = build_ptrmemfunc_type (build_pointer_type (type)); else type = build_pointer_type (type); --- 11325,11337 ---- if (TREE_CODE (declarator) == ADDR_EXPR) { ! if (!VOID_TYPE_P (type)) type = build_reference_type (type); } else if (TREE_CODE (type) == METHOD_TYPE) type = build_ptrmemfunc_type (build_pointer_type (type)); + else if (ctype) + type = build_ptrmem_type (ctype, type); else type = build_pointer_type (type); *************** grokdeclarator (declarator, declspecs, d *** 11029,11035 **** /* This needs to be here, in case we are called multiple times. */ ; else if (TREE_COMPLEXITY (declarator) == -1) ! /* Namespace member. */ pop_decl_namespace (); else if (friendp && (TREE_COMPLEXITY (declarator) < 2)) /* Don't fall out into global scope. Hides real bug? --eichin */ ; --- 11404,11410 ---- /* This needs to be here, in case we are called multiple times. */ ; else if (TREE_COMPLEXITY (declarator) == -1) ! /* Namespace member. */ pop_decl_namespace (); else if (friendp && (TREE_COMPLEXITY (declarator) < 2)) /* Don't fall out into global scope. Hides real bug? --eichin */ ; *************** grokdeclarator (declarator, declspecs, d *** 11143,11153 **** ctype, name, current_class_type); return void_type_node; } - type = build_offset_type (ctype, type); } else { ! incomplete_type_error (NULL_TREE, ctype); return error_mark_node; } --- 11518,11527 ---- ctype, name, current_class_type); return void_type_node; } } else { ! cxx_incomplete_type_error (NULL_TREE, ctype); return error_mark_node; } *************** grokdeclarator (declarator, declspecs, d *** 11162,11175 **** if (declarator && TREE_CODE (declarator) == CALL_EXPR) /* In this case, we will deal with it later. */ ; ! else ! { ! if (TREE_CODE (type) == FUNCTION_TYPE) ! type = build_cplus_method_type (ctype, TREE_TYPE (type), ! TYPE_ARG_TYPES (type)); ! else ! type = build_offset_type (ctype, type); ! } } } break; --- 11536,11544 ---- if (declarator && TREE_CODE (declarator) == CALL_EXPR) /* In this case, we will deal with it later. */ ; ! else if (TREE_CODE (type) == FUNCTION_TYPE) ! type = build_cplus_method_type (ctype, TREE_TYPE (type), ! TYPE_ARG_TYPES (type)); } } break; *************** grokdeclarator (declarator, declspecs, d *** 11178,11183 **** --- 11547,11556 ---- declarator = TREE_OPERAND (declarator, 0); break; + case BASELINK: + declarator = BASELINK_FUNCTIONS (declarator); + break; + case RECORD_TYPE: case UNION_TYPE: case ENUMERAL_TYPE: *************** grokdeclarator (declarator, declspecs, d *** 11215,11225 **** type = error_mark_node; } ! if (decl_context == FIELD && !processing_template_decl && variably_modified_type_p (type)) { ! error ("data member may not have variably modified type `%T'", type); type = error_mark_node; } --- 11588,11601 ---- type = error_mark_node; } ! if ((decl_context == FIELD || decl_context == PARM) && !processing_template_decl && variably_modified_type_p (type)) { ! if (decl_context == FIELD) ! error ("data member may not have variably modified type `%T'", type); ! else ! error ("parameter may not have variably modified type `%T'", type); type = error_mark_node; } *************** grokdeclarator (declarator, declspecs, d *** 11233,11239 **** if (RIDBIT_SETP (RID_MUTABLE, specbits)) { ! if (current_class_name == NULL_TREE || decl_context == PARM || friendp) { error ("non-member `%s' cannot be declared `mutable'", name); RIDBIT_RESET (RID_MUTABLE, specbits); --- 11609,11615 ---- if (RIDBIT_SETP (RID_MUTABLE, specbits)) { ! if (decl_context != FIELD || friendp) { error ("non-member `%s' cannot be declared `mutable'", name); RIDBIT_RESET (RID_MUTABLE, specbits); *************** grokdeclarator (declarator, declspecs, d *** 11386,11392 **** for (args = TYPE_ARG_TYPES (type); args; args = TREE_CHAIN (args)) { ! tree decl = build_decl (PARM_DECL, NULL_TREE, TREE_VALUE (args)); TREE_CHAIN (decl) = decls; decls = decl; --- 11762,11768 ---- for (args = TYPE_ARG_TYPES (type); args; args = TREE_CHAIN (args)) { ! tree decl = cp_build_parm_decl (NULL_TREE, TREE_VALUE (args)); TREE_CHAIN (decl) = decls; decls = decl; *************** grokdeclarator (declarator, declspecs, d *** 11419,11440 **** inlinep = 0; } ! /* Until core issue 180 is resolved, allow 'friend typename A::B'. ! But don't allow implicit typenames except with a class-key. */ ! if (!current_aggr && (TREE_CODE (type) != TYPENAME_TYPE ! || IMPLICIT_TYPENAME_P (type))) { if (TREE_CODE (type) == TEMPLATE_TYPE_PARM) ! pedwarn ("template parameters cannot be friends"); else if (TREE_CODE (type) == TYPENAME_TYPE) ! pedwarn ("\ ! friend declaration requires class-key, i.e. `friend class %T::%T'", ! constructor_name (current_class_type), ! TYPE_IDENTIFIER (type)); else ! pedwarn ("\ ! friend declaration requires class-key, i.e. `friend %#T'", ! type); } /* Only try to do this stuff if we didn't already give up. */ --- 11795,11813 ---- inlinep = 0; } ! if (!current_aggr) { + /* Don't allow friend declaration without a class-key. */ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM) ! pedwarn ("template parameters cannot be friends"); else if (TREE_CODE (type) == TYPENAME_TYPE) ! pedwarn ("friend declaration requires class-key, " ! "i.e. `friend class %T::%D'", ! TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type)); else ! pedwarn ("friend declaration requires class-key, " ! "i.e. `friend %#T'", ! type); } /* Only try to do this stuff if we didn't already give up. */ *************** friend declaration requires class-key, i *** 11530,11546 **** if (decl_context == PARM) { ! decl = build_decl (PARM_DECL, declarator, type); bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); - - /* Compute the type actually passed in the parmlist, - for the case where there is no prototype. - (For example, shorts and chars are passed as ints.) - When there is a prototype, this is overridden later. */ - - DECL_ARG_TYPE (decl) = type_promotes_to (type); } else if (decl_context == FIELD) { --- 11903,11912 ---- if (decl_context == PARM) { ! decl = cp_build_parm_decl (declarator, type); bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); } else if (decl_context == FIELD) { *************** friend declaration requires class-key, i *** 11820,11825 **** --- 12186,12193 ---- error ("storage class `auto' invalid for function `%s'", name); else if (RIDBIT_SETP (RID_REGISTER, specbits)) error ("storage class `register' invalid for function `%s'", name); + else if (RIDBIT_SETP (RID_THREAD, specbits)) + error ("storage class `__thread' invalid for function `%s'", name); /* Function declaration not at top level. Storage classes other than `extern' are not allowed *************** friend declaration requires class-key, i *** 11862,11884 **** if (staticp == 1) { ! int illegal_static = 0; /* Don't allow a static member function in a class, and forbid declaring main to be static. */ if (TREE_CODE (type) == METHOD_TYPE) { pedwarn ("cannot declare member function `%D' to have static linkage", decl); ! illegal_static = 1; } else if (current_function_decl) { /* FIXME need arm citation */ error ("cannot declare static function inside another function"); ! illegal_static = 1; } ! if (illegal_static) { staticp = 0; RIDBIT_RESET (RID_STATIC, specbits); --- 12230,12252 ---- if (staticp == 1) { ! int invalid_static = 0; /* Don't allow a static member function in a class, and forbid declaring main to be static. */ if (TREE_CODE (type) == METHOD_TYPE) { pedwarn ("cannot declare member function `%D' to have static linkage", decl); ! invalid_static = 1; } else if (current_function_decl) { /* FIXME need arm citation */ error ("cannot declare static function inside another function"); ! invalid_static = 1; } ! if (invalid_static) { staticp = 0; RIDBIT_RESET (RID_STATIC, specbits); *************** friend declaration requires class-key, i *** 11893,11899 **** decl = grokvardecl (type, declarator, &specbits, initialized, (type_quals & TYPE_QUAL_CONST) != 0, ! in_namespace); bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); --- 12261,12267 ---- decl = grokvardecl (type, declarator, &specbits, initialized, (type_quals & TYPE_QUAL_CONST) != 0, ! ctype ? ctype : in_namespace); bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); *************** require_complete_types_for_parms (parms) *** 11985,11997 **** /* grokparms will have already issued an error */ TREE_TYPE (parms) = error_mark_node; else if (complete_type_or_else (TREE_TYPE (parms), parms)) ! layout_decl (parms, 0); else TREE_TYPE (parms) = error_mark_node; } } ! /* Returns non-zero if T is a local variable. */ int local_variable_p (t) --- 12353,12368 ---- /* grokparms will have already issued an error */ TREE_TYPE (parms) = error_mark_node; else if (complete_type_or_else (TREE_TYPE (parms), parms)) ! { ! layout_decl (parms, 0); ! DECL_ARG_TYPE (parms) = type_passed_as (TREE_TYPE (parms)); ! } else TREE_TYPE (parms) = error_mark_node; } } ! /* Returns nonzero if T is a local variable. */ int local_variable_p (t) *************** local_variable_p (t) *** 12009,12015 **** return 0; } ! /* Returns non-zero if T is an automatic local variable or a label. (These are the declarations that need to be remapped when the code containing them is duplicated.) */ --- 12380,12386 ---- return 0; } ! /* Returns nonzero if T is an automatic local variable or a label. (These are the declarations that need to be remapped when the code containing them is duplicated.) */ *************** local_variable_p_walkfn (tp, walk_subtre *** 12036,12042 **** } /* Check that ARG, which is a default-argument expression for a ! parameter DECL, is legal. Returns ARG, or ERROR_MARK_NODE, if something goes wrong. DECL may also be a _TYPE node, rather than a DECL, if there is no DECL available. */ --- 12407,12413 ---- } /* Check that ARG, which is a default-argument expression for a ! parameter DECL, is valid. Returns ARG, or ERROR_MARK_NODE, if something goes wrong. DECL may also be a _TYPE node, rather than a DECL, if there is no DECL available. */ *************** grokparms (first_parm) *** 12175,12181 **** && !DECL_NAME (decl) && !result && !chain && !ellipsis) /* this is a parmlist of `(void)', which is ok. */ break; ! incomplete_type_error (decl, type); /* It's not a good idea to actually create parameters of type `void'; other parts of the compiler assume that a void type terminates the parameter list. */ --- 12546,12552 ---- && !DECL_NAME (decl) && !result && !chain && !ellipsis) /* this is a parmlist of `(void)', which is ok. */ break; ! cxx_incomplete_type_error (decl, type); /* It's not a good idea to actually create parameters of type `void'; other parts of the compiler assume that a void type terminates the parameter list. */ *************** grokparms (first_parm) *** 12201,12207 **** TREE_TYPE (decl) = type; } else if (abstract_virtuals_error (decl, type)) ! any_error = 1; /* Seems like a good idea. */ else if (POINTER_TYPE_P (type)) { /* [dcl.fct]/6, parameter types cannot contain pointers --- 12572,12578 ---- TREE_TYPE (decl) = type; } else if (abstract_virtuals_error (decl, type)) ! any_error = 1; /* Seems like a good idea. */ else if (POINTER_TYPE_P (type)) { /* [dcl.fct]/6, parameter types cannot contain pointers *************** grokparms (first_parm) *** 12224,12234 **** decl, ptr ? "pointer" : "reference", t); } - DECL_ARG_TYPE (decl) = TREE_TYPE (decl); - if (PROMOTE_PROTOTYPES - && INTEGRAL_TYPE_P (type) - && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) - DECL_ARG_TYPE (decl) = integer_type_node; if (!any_error && init) init = check_default_argument (decl, init); else --- 12595,12600 ---- *************** grokparms (first_parm) *** 12264,12270 **** first parameter is a reference to non-const qualified T. This function can be used as a predicate. Positive values indicate ! a copy constructor and non-zero values indicate a copy assignment operator. */ int --- 12630,12636 ---- first parameter is a reference to non-const qualified T. This function can be used as a predicate. Positive values indicate ! a copy constructor and nonzero values indicate a copy assignment operator. */ int *************** grok_op_properties (decl, friendp) *** 12569,12575 **** } if (operator_code == CALL_EXPR) ! return; /* No restrictions on args. */ if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl)) { --- 12935,12941 ---- } if (operator_code == CALL_EXPR) ! return; /* No restrictions on args. */ if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl)) { *************** tag_name (code) *** 12773,12778 **** --- 13139,13176 ---- } } + /* Name lookup in an elaborated-type-specifier (after the keyword + indicated by TAG_CODE) has found TYPE. If the + elaborated-type-specifier is invalid, issue a diagnostic and return + error_mark_node; otherwise, return TYPE itself. */ + + static tree + check_elaborated_type_specifier (enum tag_types tag_code, + tree type) + { + tree t; + + t = follow_tag_typedef (type); + + /* [dcl.type.elab] If the identifier resolves to a typedef-name or a + template type-parameter, the elaborated-type-specifier is + ill-formed. */ + if (!t) + { + error ("using typedef-name `%D' after `%s'", + TYPE_NAME (type), tag_name (tag_code)); + t = error_mark_node; + } + else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM) + { + error ("using template type parameter `%T' after `%s'", + type, tag_name (tag_code)); + t = error_mark_node; + } + + return t; + } + /* Get the struct, enum or union (CODE says which) with tag NAME. Define the tag as a forward-reference if it is not defined. *************** tag_name (code) *** 12784,12812 **** scope.) */ tree ! xref_tag (code_type_node, name, globalize) ! tree code_type_node; ! tree name; ! int globalize; { - enum tag_types tag_code; enum tree_code code; register tree ref, t; ! struct binding_level *b = current_binding_level; ! tree attributes = NULL_TREE; tree context = NULL_TREE; ! /* If we are called from the parser, code_type_node will sometimes be a ! TREE_LIST. This indicates that the user wrote ! "class __attribute__ ((foo)) bar". Extract the attributes so we can ! use them later. */ ! if (TREE_CODE (code_type_node) == TREE_LIST) ! { ! attributes = TREE_PURPOSE (code_type_node); ! code_type_node = TREE_VALUE (code_type_node); ! } - tag_code = (enum tag_types) tree_low_cst (code_type_node, 1); switch (tag_code) { case record_type: --- 13182,13197 ---- scope.) */ tree ! xref_tag (enum tag_types tag_code, tree name, tree attributes, ! bool globalize) { enum tree_code code; register tree ref, t; ! struct cp_binding_level *b = current_binding_level; tree context = NULL_TREE; ! timevar_push (TV_NAME_LOOKUP); switch (tag_code) { case record_type: *************** xref_tag (code_type_node, name, globaliz *** 12848,12854 **** TYPE_IDENTIFIER (t)); /* We need to remove the class scope binding for the ! TYPENAME_TYPE as otherwise poplevel_class gets confused. */ for (shadowed = b->class_shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) --- 13233,13239 ---- TYPE_IDENTIFIER (t)); /* We need to remove the class scope binding for the ! TYPENAME_TYPE as otherwise poplevel_class gets confused. */ for (shadowed = b->class_shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) *************** xref_tag (code_type_node, name, globaliz *** 12873,12892 **** { if (t) { ! ref = follow_tag_typedef (t); ! ! /* [dcl.type.elab] If the identifier resolves to a ! typedef-name or a template type-parameter, the ! elaborated-type-specifier is ill-formed. */ ! if (!ref) ! { ! pedwarn ("using typedef-name `%D' after `%s'", ! TYPE_NAME (t), tag_name (tag_code)); ! ref = t; ! } ! else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM) ! error ("using template type parameter `%T' after `%s'", ! t, tag_name (tag_code)); } else ref = lookup_tag (code, name, b, 0); --- 13258,13266 ---- { if (t) { ! ref = check_elaborated_type_specifier (tag_code, t); ! if (ref == error_mark_node) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); } else ref = lookup_tag (code, name, b, 0); *************** xref_tag (code_type_node, name, globaliz *** 12905,12913 **** template, so we want this type. */ ref = DECL_TEMPLATE_RESULT (ref); ! if (ref && TREE_CODE (ref) == TYPE_DECL ! && TREE_CODE (TREE_TYPE (ref)) == code) ! ref = TREE_TYPE (ref); else ref = NULL_TREE; } --- 13279,13293 ---- template, so we want this type. */ ref = DECL_TEMPLATE_RESULT (ref); ! if (ref && TREE_CODE (ref) == TYPE_DECL) ! { ! ref = check_elaborated_type_specifier (tag_code, ! TREE_TYPE (ref)); ! if (ref == error_mark_node) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); ! if (ref && TREE_CODE (ref) != code) ! ref = NULL_TREE; ! } else ref = NULL_TREE; } *************** xref_tag (code_type_node, name, globaliz *** 12916,12922 **** && template_class_depth (current_class_type) && PROCESSING_REAL_TEMPLATE_DECL_P ()) { ! /* Since GLOBALIZE is non-zero, we are not looking at a definition of this tag. Since, in addition, we are currently processing a (member) template declaration of a template class, we must be very careful; consider: --- 13296,13302 ---- && template_class_depth (current_class_type) && PROCESSING_REAL_TEMPLATE_DECL_P ()) { ! /* Since GLOBALIZE is nonzero, we are not looking at a definition of this tag. Since, in addition, we are currently processing a (member) template declaration of a template class, we must be very careful; consider: *************** xref_tag (code_type_node, name, globaliz *** 12988,13001 **** } else { ! struct binding_level *old_b = class_binding_level; ref = make_aggr_type (code); TYPE_CONTEXT (ref) = context; #ifdef NONNESTED_CLASSES /* Class types don't nest the way enums do. */ ! class_binding_level = (struct binding_level *)0; #endif pushtag (name, ref, globalize); class_binding_level = old_b; --- 13368,13381 ---- } else { ! struct cp_binding_level *old_b = class_binding_level; ref = make_aggr_type (code); TYPE_CONTEXT (ref) = context; #ifdef NONNESTED_CLASSES /* Class types don't nest the way enums do. */ ! class_binding_level = (struct cp_binding_level *)0; #endif pushtag (name, ref, globalize); class_binding_level = old_b; *************** xref_tag (code_type_node, name, globaliz *** 13009,13015 **** TYPE_ATTRIBUTES (ref) = attributes; ! return ref; } tree --- 13389,13395 ---- TYPE_ATTRIBUTES (ref) = attributes; ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ref); } tree *************** xref_tag_from_type (old, id, globalize) *** 13017,13034 **** tree old, id; int globalize; { ! tree code_type_node; if (TREE_CODE (old) == RECORD_TYPE) ! code_type_node = (CLASSTYPE_DECLARED_CLASS (old) ! ? class_type_node : record_type_node); else ! code_type_node = union_type_node; if (id == NULL_TREE) id = TYPE_IDENTIFIER (old); ! return xref_tag (code_type_node, id, globalize); } /* REF is a type (named NAME), for which we have just seen some --- 13397,13413 ---- tree old, id; int globalize; { ! enum tag_types tag_kind; if (TREE_CODE (old) == RECORD_TYPE) ! tag_kind = (CLASSTYPE_DECLARED_CLASS (old) ? class_type : record_type); else ! tag_kind = union_type; if (id == NULL_TREE) id = TYPE_IDENTIFIER (old); ! return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize); } /* REF is a type (named NAME), for which we have just seen some *************** xref_tag_from_type (old, id, globalize) *** 13038,13046 **** struct, or union. */ void ! xref_basetypes (code_type_node, name, ref, binfo) ! tree code_type_node; ! tree name ATTRIBUTE_UNUSED; tree ref; tree binfo; { --- 13417,13423 ---- struct, or union. */ void ! xref_basetypes (ref, binfo) tree ref; tree binfo; { *************** xref_basetypes (code_type_node, name, re *** 13052,13072 **** int i, len; enum tag_types tag_code; ! /* If we are called from the parser, code_type_node will sometimes be a ! TREE_LIST. This indicates that the user wrote ! "class __attribute__ ((foo)) bar". Extract the attributes so that ! tree_low_cst doesn't crash. */ ! if (TREE_CODE (code_type_node) == TREE_LIST) ! code_type_node = TREE_VALUE (code_type_node); ! ! tag_code = (enum tag_types) tree_low_cst (code_type_node, 1); ! ! if (tag_code == union_type) { error ("derived union `%T' invalid", ref); return; } len = list_length (binfo); /* First, make sure that any templates in base-classes are --- 13429,13442 ---- int i, len; enum tag_types tag_code; ! if (TREE_CODE (ref) == UNION_TYPE) { error ("derived union `%T' invalid", ref); return; } + tag_code = (CLASSTYPE_DECLARED_CLASS (ref) ? class_type : record_type); + len = list_length (binfo); /* First, make sure that any templates in base-classes are *************** start_enum (name) *** 13227,13233 **** tree name; { register tree enumtype = NULL_TREE; ! struct binding_level *b = current_binding_level; /* If this is the real definition for a previous forward reference, fill in the contents in the same object that used to be the --- 13597,13603 ---- tree name; { register tree enumtype = NULL_TREE; ! struct cp_binding_level *b = current_binding_level; /* If this is the real definition for a previous forward reference, fill in the contents in the same object that used to be the *************** finish_enum (enumtype) *** 13272,13318 **** /* We built up the VALUES in reverse order. */ TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype)); ! /* [dcl.enum] ! ! Following the closing brace of an enum-specifier, each ! enumerator has the type of its enumeration. Prior to the ! closing brace, the type of each enumerator is the type of ! its initializing value. */ ! for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair)) ! TREE_TYPE (TREE_VALUE (pair)) = enumtype; ! ! /* For a enum defined in a template, all further processing is ! postponed until the template is instantiated. */ if (processing_template_decl) { ! tree scope = current_scope (); ! if (scope && TREE_CODE (scope) == FUNCTION_DECL) add_stmt (build_min (TAG_DEFN, enumtype)); - - return; } - /* Figure out what the minimum and maximum values of the enumerators - are. */ if (TYPE_VALUES (enumtype)) { minnode = maxnode = NULL_TREE; ! for (pair = TYPE_VALUES (enumtype); ! pair; ! pair = TREE_CHAIN (pair)) { ! tree value; ! value = DECL_INITIAL (TREE_VALUE (pair)); if (!minnode) minnode = maxnode = value; else if (tree_int_cst_lt (maxnode, value)) maxnode = value; else if (tree_int_cst_lt (value, minnode)) minnode = value; } } else --- 13642,13697 ---- /* We built up the VALUES in reverse order. */ TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype)); ! /* For an enum defined in a template, just set the type of the values; ! all further processing is postponed until the template is ! instantiated. We need to set the type so that tsubst of a CONST_DECL ! works. */ if (processing_template_decl) { ! for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair)) ! TREE_TYPE (TREE_VALUE (pair)) = enumtype; ! if (at_function_scope_p ()) add_stmt (build_min (TAG_DEFN, enumtype)); return; } if (TYPE_VALUES (enumtype)) { minnode = maxnode = NULL_TREE; ! for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair)) { ! tree decl = TREE_VALUE (pair); ! tree value = DECL_INITIAL (decl); ! /* [dcl.enum]: Following the closing brace of an enum-specifier, ! each enumerator has the type of its enumeration. Prior to the ! closing brace, the type of each enumerator is the type of its ! initializing value. */ ! TREE_TYPE (decl) = enumtype; + /* Figure out what the minimum and maximum values of the + enumerators are. */ if (!minnode) minnode = maxnode = value; else if (tree_int_cst_lt (maxnode, value)) maxnode = value; else if (tree_int_cst_lt (value, minnode)) minnode = value; + + /* Set the TREE_TYPE for the values as well. That's so that when + we call decl_constant_value we get an entity of the right type + (but with the constant value). But first make a copy so we + don't clobber shared INTEGER_CSTs. */ + if (TREE_TYPE (value) != enumtype) + { + value = DECL_INITIAL (decl) = copy_node (value); + TREE_TYPE (value) = enumtype; + } + + /* In addition, transform the TYPE_VALUES list to contain the + values, rather than the CONST_DECLs for them. */ + TREE_VALUE (pair) = value; } } else *************** finish_enum (enumtype) *** 13327,13344 **** highprec = min_precision (maxnode, unsignedp); precision = MAX (lowprec, highprec); - /* Set the TREE_TYPE for the values as well. That's so that when we - call decl_constant_value we get an entity of the right type (but - with the constant value). In addition, transform the TYPE_VALUES - list to contain the values, rather than the CONST_DECLs for them. */ - for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair)) - { - tree value = DECL_INITIAL (TREE_VALUE (pair)); - - TREE_TYPE (value) = enumtype; - TREE_VALUE (pair) = value; - } - /* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'. */ TYPE_SIZE (enumtype) = NULL_TREE; TYPE_PRECISION (enumtype) = precision; --- 13706,13711 ---- *************** finish_enum (enumtype) *** 13350,13356 **** if (flag_short_enums || (precision > TYPE_PRECISION (integer_type_node))) /* Use the width of the narrowest normal C type which is wide enough. */ ! TYPE_PRECISION (enumtype) = TYPE_PRECISION (type_for_size (precision, 1)); else TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node); --- 13717,13723 ---- if (flag_short_enums || (precision > TYPE_PRECISION (integer_type_node))) /* Use the width of the narrowest normal C type which is wide enough. */ ! TYPE_PRECISION (enumtype) = TYPE_PRECISION (c_common_type_for_size (precision, 1)); else TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node); *************** build_enumerator (name, value, enumtype) *** 13390,13396 **** tree decl; tree context; tree type; - tree values; /* Remove no-op casts from the value. */ if (value) --- 13757,13762 ---- *************** build_enumerator (name, value, enumtype) *** 13422,13428 **** if (TYPE_VALUES (enumtype)) { ! /* The next value is the previous value ... */ prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype))); /* ... plus one. */ value = cp_build_binary_op (PLUS_EXPR, --- 13788,13794 ---- if (TYPE_VALUES (enumtype)) { ! /* The next value is the previous value ... */ prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype))); /* ... plus one. */ value = cp_build_binary_op (PLUS_EXPR, *************** build_enumerator (name, value, enumtype) *** 13437,13462 **** } /* Remove no-op casts from the value. */ ! if (value) ! STRIP_TYPE_NOPS (value); ! #if 0 ! /* To fix MAX_VAL enum consts. (bkoz) */ ! TREE_TYPE (value) = integer_type_node; ! #endif } - /* We always have to copy here; not all INTEGER_CSTs are unshared. - Even in other cases, we will later (in finish_enum) be setting - the type of VALUE. But, we don't need to make a copy if this - VALUE is one of the enumeration constants for this same - enumeration type. */ - for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values)) - if (TREE_VALUE (values) == value) - break; - /* If we didn't break out of the loop, then we do need a copy. */ - if (!values && value) - value = copy_node (value); - /* C++ associates enums with global, function, or class declarations. */ context = current_scope (); --- 13803,13811 ---- } /* Remove no-op casts from the value. */ ! STRIP_TYPE_NOPS (value); } /* C++ associates enums with global, function, or class declarations. */ context = current_scope (); *************** build_enumerator (name, value, enumtype) *** 13472,13478 **** initializing value. In finish_enum we will reset the type. Of course, if we're ! processing a template, there may be no value. */ type = value ? TREE_TYPE (value) : NULL_TREE; if (context && context == current_class_type) --- 13821,13827 ---- initializing value. In finish_enum we will reset the type. Of course, if we're ! processing a template, there may be no value. */ type = value ? TREE_TYPE (value) : NULL_TREE; if (context && context == current_class_type) *************** start_function (declspecs, declarator, a *** 13571,13580 **** tree ctype = NULL_TREE; tree fntype; tree restype; - extern int have_extern_spec; - extern int used_extern_spec; int doing_friend = 0; ! struct binding_level *bl; tree current_function_parms; /* Sanity check. */ --- 13920,13927 ---- tree ctype = NULL_TREE; tree fntype; tree restype; int doing_friend = 0; ! struct cp_binding_level *bl; tree current_function_parms; /* Sanity check. */ *************** start_function (declspecs, declarator, a *** 13582,13591 **** my_friendly_assert (TREE_CHAIN (void_list_node) == NULL_TREE, 161); /* This should only be done once on the top most decl. */ ! if (have_extern_spec && !used_extern_spec) { declspecs = tree_cons (NULL_TREE, get_identifier ("extern"), declspecs); ! used_extern_spec = 1; } if (flags & SF_PRE_PARSED) --- 13929,13938 ---- my_friendly_assert (TREE_CHAIN (void_list_node) == NULL_TREE, 161); /* This should only be done once on the top most decl. */ ! if (have_extern_spec) { declspecs = tree_cons (NULL_TREE, get_identifier ("extern"), declspecs); ! have_extern_spec = false; } if (flags & SF_PRE_PARSED) *************** start_function (declspecs, declarator, a *** 13783,13789 **** decl1 = pushdecl (decl1); else { ! /* We need to set the DECL_CONTEXT. */ if (!DECL_CONTEXT (decl1) && DECL_TEMPLATE_INFO (decl1)) DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (decl1)); /* And make sure we have enough default args. */ --- 14130,14136 ---- decl1 = pushdecl (decl1); else { ! /* We need to set the DECL_CONTEXT. */ if (!DECL_CONTEXT (decl1) && DECL_TEMPLATE_INFO (decl1)) DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (decl1)); /* And make sure we have enough default args. */ *************** start_function (declspecs, declarator, a *** 13798,13809 **** /* If we are (erroneously) defining a function that we have already defined before, wipe out what we knew before. */ ! if (!DECL_PENDING_INLINE_P (decl1) ! && DECL_SAVED_FUNCTION_DATA (decl1)) ! { ! free (DECL_SAVED_FUNCTION_DATA (decl1)); ! DECL_SAVED_FUNCTION_DATA (decl1) = NULL; ! } if (ctype && !doing_friend && !DECL_STATIC_FUNCTION_P (decl1)) { --- 14145,14152 ---- /* If we are (erroneously) defining a function that we have already defined before, wipe out what we knew before. */ ! if (!DECL_PENDING_INLINE_P (decl1)) ! DECL_SAVED_FUNCTION_DATA (decl1) = NULL; if (ctype && !doing_friend && !DECL_STATIC_FUNCTION_P (decl1)) { *************** static void *** 14012,14018 **** save_function_data (decl) tree decl; { ! struct cp_language_function *f; /* Save the language-specific per-function data so that we can get it back when we really expand this function. */ --- 14355,14361 ---- save_function_data (decl) tree decl; { ! struct language_function *f; /* Save the language-specific per-function data so that we can get it back when we really expand this function. */ *************** save_function_data (decl) *** 14020,14028 **** 19990908); /* Make a copy. */ ! f = ((struct cp_language_function *) ! xmalloc (sizeof (struct cp_language_function))); ! memcpy (f, cp_function_chain, sizeof (struct cp_language_function)); DECL_SAVED_FUNCTION_DATA (decl) = f; /* Clear out the bits we don't need. */ --- 14363,14371 ---- 19990908); /* Make a copy. */ ! f = ((struct language_function *) ! ggc_alloc (sizeof (struct language_function))); ! memcpy (f, cp_function_chain, sizeof (struct language_function)); DECL_SAVED_FUNCTION_DATA (decl) = f; /* Clear out the bits we don't need. */ *************** save_function_data (decl) *** 14052,14060 **** static void begin_constructor_body () { - tree ctor_stmt = build_stmt (CTOR_STMT); - CTOR_BEGIN_P (ctor_stmt) = 1; - add_stmt (ctor_stmt); } /* Add a note to mark the end of the main body of the constructor. This is --- 14395,14400 ---- *************** begin_constructor_body () *** 14064,14075 **** static void finish_constructor_body () { - /* Mark the end of the cleanups for a partially constructed object. - - ??? These should really be handled automatically by closing the block, - as with the destructor cleanups; the only difference is that these are - only run if an exception is thrown. */ - add_stmt (build_stmt (CTOR_STMT)); } /* Do all the processing for the beginning of a destructor; set up the --- 14404,14409 ---- *************** begin_destructor_body () *** 14102,14108 **** appropriately, so we just assume that we always need to initialize the vtables.) */ finish_if_stmt_cond (boolean_true_node, if_stmt); - current_vcalls_possible_p = &IF_COND (if_stmt); compound_stmt = begin_compound_stmt (/*has_no_scope=*/0); --- 14436,14441 ---- *************** begin_destructor_body () *** 14114,14119 **** --- 14447,14456 ---- finish_compound_stmt (/*has_no_scope=*/0, compound_stmt); finish_then_clause (if_stmt); finish_if_stmt (); + + /* And insert cleanups for our bases and members so that they + will be properly destroyed if we throw. */ + push_base_cleanups (); } /* At the end of every destructor we generate code to delete the object if *************** finish_destructor_body () *** 14128,14141 **** and member cleanups will be run when the function returns. */ add_stmt (build_stmt (LABEL_STMT, dtor_label)); - /* And perform cleanups for our bases and members. */ - perform_base_cleanups (); - /* In a virtual destructor, we must call delete. */ if (DECL_VIRTUAL_P (current_function_decl)) { tree if_stmt; ! tree virtual_size = c_sizeof (current_class_type); /* [class.dtor] --- 14465,14475 ---- and member cleanups will be run when the function returns. */ add_stmt (build_stmt (LABEL_STMT, dtor_label)); /* In a virtual destructor, we must call delete. */ if (DECL_VIRTUAL_P (current_function_decl)) { tree if_stmt; ! tree virtual_size = cxx_sizeof (current_class_type); /* [class.dtor] *************** finish_function (flags) *** 14238,14243 **** --- 14572,14586 ---- if (fndecl == NULL_TREE) return error_mark_node; + if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl) + && DECL_VIRTUAL_P (fndecl) + && !processing_template_decl) + { + tree fnclass = DECL_CONTEXT (fndecl); + if (fndecl == CLASSTYPE_KEY_METHOD (fnclass)) + keyed_classes = tree_cons (NULL_TREE, fnclass, keyed_classes); + } + nested = function_depth > 1; fntype = TREE_TYPE (fndecl); *************** finish_function (flags) *** 14275,14280 **** --- 14618,14629 ---- /* If we're saving up tree structure, tie off the function now. */ finish_stmt_tree (&DECL_SAVED_TREE (fndecl)); + /* If this function can't throw any exceptions, remember that. */ + if (!processing_template_decl + && !cp_function_chain->can_throw + && !flag_non_call_exceptions) + TREE_NOTHROW (fndecl) = 1; + /* This must come after expand_function_end because cleanups might have declarations (from inline functions) that need to go into this function's blocks. */ *************** finish_function (flags) *** 14380,14386 **** free_after_compilation (cfun); cfun = NULL; ! /* If this is a in-class inline definition, we may have to pop the bindings for the template parameters that we added in maybe_begin_member_template_processing when start_function was called. */ --- 14729,14735 ---- free_after_compilation (cfun); cfun = NULL; ! /* If this is an in-class inline definition, we may have to pop the bindings for the template parameters that we added in maybe_begin_member_template_processing when start_function was called. */ *************** finish_function (flags) *** 14397,14403 **** if (! nested) /* Let the error reporting routines know that we're outside a function. For a nested function, this value is used in ! pop_cp_function_context and then reset via pop_function_context. */ current_function_decl = NULL_TREE; return fndecl; --- 14746,14752 ---- if (! nested) /* Let the error reporting routines know that we're outside a function. For a nested function, this value is used in ! cxx_pop_function_context and then reset via pop_function_context. */ current_function_decl = NULL_TREE; return fndecl; *************** start_method (declspecs, declarator, att *** 14462,14467 **** --- 14811,14817 ---- DECL_DECLARED_INLINE_P (fndecl) = 1; + DID_INLINE_FUNC (fndecl) = 0; if (flag_default_inline) DECL_INLINE (fndecl) = 1; *************** complete_vars (type) *** 14609,14615 **** here. */ tree ! maybe_build_cleanup (decl) tree decl; { tree type = TREE_TYPE (decl); --- 14959,14965 ---- here. */ tree ! cxx_maybe_build_cleanup (decl) tree decl; { tree type = TREE_TYPE (decl); *************** maybe_build_cleanup (decl) *** 14623,14629 **** rval = decl; else { ! mark_addressable (decl); rval = build_unary_op (ADDR_EXPR, decl, 0); } --- 14973,14979 ---- rval = decl; else { ! cxx_mark_addressable (decl); rval = build_unary_op (ADDR_EXPR, decl, 0); } *************** revert_static_member_fn (decl) *** 14686,14699 **** /* Initialize the variables used during compilation of a C++ function. */ ! static void ! push_cp_function_context (f) struct function *f; { ! struct cp_language_function *p ! = ((struct cp_language_function *) ! xcalloc (1, sizeof (struct cp_language_function))); ! f->language = (struct language_function *) p; /* It takes an explicit call to expand_body to generate RTL for a function. */ --- 15036,15049 ---- /* Initialize the variables used during compilation of a C++ function. */ ! void ! cxx_push_function_context (f) struct function *f; { ! struct language_function *p ! = ((struct language_function *) ! ggc_alloc_cleared (sizeof (struct language_function))); ! f->language = p; /* It takes an explicit call to expand_body to generate RTL for a function. */ *************** push_cp_function_context (f) *** 14707,14847 **** /* Free the language-specific parts of F, now that we've finished compiling the function. */ ! static void ! pop_cp_function_context (f) struct function *f; { - if (f->language) - { - struct cp_language_function *cp = - (struct cp_language_function *) f->language; - if (cp->x_local_names) - VARRAY_FREE (cp->x_local_names); - free (f->language); - } f->language = 0; } ! /* Mark P for GC. */ ! ! static void ! mark_lang_function (p) ! struct cp_language_function *p; ! { ! if (!p) ! return; ! ! mark_c_language_function (&p->base); ! ! ggc_mark_tree (p->x_dtor_label); ! ggc_mark_tree (p->x_current_class_ptr); ! ggc_mark_tree (p->x_current_class_ref); ! ggc_mark_tree (p->x_eh_spec_block); ! ggc_mark_tree_varray (p->x_local_names); ! ! mark_named_label_lists (&p->x_named_labels, &p->x_named_label_uses); ! mark_binding_level (&p->bindings); ! mark_pending_inlines (&p->unparsed_inlines); ! } ! ! /* Mark the language-specific data in F for GC. */ ! ! static void ! mark_cp_function_context (f) ! struct function *f; ! { ! mark_lang_function ((struct cp_language_function *) f->language); ! } ! void ! lang_mark_tree (t) ! tree t; { ! enum tree_code code = TREE_CODE (t); ! if (code == IDENTIFIER_NODE) ! { ! struct lang_identifier *li = (struct lang_identifier *) t; ! struct lang_id2 *li2 = li->x; ! ggc_mark_tree (li->namespace_bindings); ! ggc_mark_tree (li->bindings); ! ggc_mark_tree (li->class_value); ! ggc_mark_tree (li->class_template_info); ! ! if (li2) ! { ! ggc_mark_tree (li2->label_value); ! ggc_mark_tree (li2->implicit_decl); ! ggc_mark_tree (li2->error_locus); ! } ! } ! else if (code == CPLUS_BINDING) ! { ! if (BINDING_HAS_LEVEL_P (t)) ! mark_binding_level (&BINDING_LEVEL (t)); ! else ! ggc_mark_tree (BINDING_SCOPE (t)); ! ggc_mark_tree (BINDING_VALUE (t)); ! } ! else if (code == OVERLOAD) ! ggc_mark_tree (OVL_FUNCTION (t)); ! else if (code == TEMPLATE_PARM_INDEX) ! ggc_mark_tree (TEMPLATE_PARM_DECL (t)); ! else if (TREE_CODE_CLASS (code) == 'd') ! { ! struct lang_decl *ld = DECL_LANG_SPECIFIC (t); ! ! if (ld) ! { ! ggc_mark (ld); ! c_mark_lang_decl (&ld->decl_flags.base); ! if (!DECL_GLOBAL_CTOR_P (t) ! && !DECL_GLOBAL_DTOR_P (t) ! && !DECL_THUNK_P (t) ! && !DECL_DISCRIMINATOR_P (t)) ! ggc_mark_tree (ld->decl_flags.u2.access); ! else if (DECL_THUNK_P (t)) ! ggc_mark_tree (ld->decl_flags.u2.vcall_offset); ! if (TREE_CODE (t) != NAMESPACE_DECL) ! ggc_mark_tree (ld->decl_flags.u.template_info); ! else ! mark_binding_level (&NAMESPACE_LEVEL (t)); ! if (CAN_HAVE_FULL_LANG_DECL_P (t)) ! { ! ggc_mark_tree (ld->befriending_classes); ! ggc_mark_tree (ld->context); ! ggc_mark_tree (ld->cloned_function); ! if (TREE_CODE (t) == TYPE_DECL) ! ggc_mark_tree (ld->u.sorted_fields); ! else if (TREE_CODE (t) == FUNCTION_DECL ! && !DECL_PENDING_INLINE_P (t)) ! mark_lang_function (DECL_SAVED_FUNCTION_DATA (t)); ! } ! } ! } ! else if (TREE_CODE_CLASS (code) == 't') { ! struct lang_type *lt = TYPE_LANG_SPECIFIC (t); ! ! if (lt && !(TREE_CODE (t) == POINTER_TYPE ! && TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE)) ! { ! ggc_mark (lt); ! ggc_mark_tree (lt->primary_base); ! ggc_mark_tree (lt->vfields); ! ggc_mark_tree (lt->vbases); ! ggc_mark_tree (lt->tags); ! ggc_mark_tree (lt->size); ! ggc_mark_tree (lt->pure_virtuals); ! ggc_mark_tree (lt->friend_classes); ! ggc_mark_tree (lt->rtti); ! ggc_mark_tree (lt->methods); ! ggc_mark_tree (lt->template_info); ! ggc_mark_tree (lt->befriending_classes); ! } ! else if (lt) ! /* In the case of pointer-to-member function types, the ! TYPE_LANG_SPECIFIC is really just a tree. */ ! ggc_mark_tree ((tree) lt); } } --- 15057,15086 ---- /* Free the language-specific parts of F, now that we've finished compiling the function. */ ! void ! cxx_pop_function_context (f) struct function *f; { f->language = 0; } ! /* Return which tree structure is used by T, or TS_CP_GENERIC if T is ! one of the language-independent trees. */ ! enum cp_tree_node_structure_enum ! cp_tree_node_structure (t) ! union lang_tree_node *t; { ! switch (TREE_CODE (&t->generic)) { ! case DEFAULT_ARG: return TS_CP_IDENTIFIER; ! case IDENTIFIER_NODE: return TS_CP_IDENTIFIER; ! case OVERLOAD: return TS_CP_OVERLOAD; ! case TEMPLATE_PARM_INDEX: return TS_CP_TPI; ! case PTRMEM_CST: return TS_CP_PTRMEM; ! case WRAPPER: return TS_CP_WRAPPER; ! case SRCLOC: return TS_CP_SRCLOC; ! default: return TS_CP_GENERIC; } } *************** cp_missing_noreturn_ok_p (decl) *** 14871,14873 **** --- 15110,15115 ---- /* A missing noreturn is ok for the `main' function. */ return DECL_MAIN_P (decl); } + + #include "gt-cp-decl.h" + #include "gtype-cp.h" diff -Nrc3pad gcc-3.2.3/gcc/cp/decl.h gcc-3.3/gcc/cp/decl.h *** gcc-3.2.3/gcc/cp/decl.h 2002-01-09 06:32:47.000000000 +0000 --- gcc-3.3/gcc/cp/decl.h 2002-06-04 07:10:07.000000000 +0000 *************** extern tree grokdeclarator PARAMS ((tree *** 36,48 **** /* Parsing a function declarator leaves a list of parameter names or a chain or parameter decls here. */ ! extern tree last_function_parms; /* A list of objects which have constructors or destructors which reside in the global scope. The decl is stored in the TREE_VALUE slot and the initializer is stored in the TREE_PURPOSE slot. */ ! extern tree static_aggregates; #ifdef DEBUG_CP_BINDING_LEVELS /* Purely for debugging purposes. */ --- 36,48 ---- /* Parsing a function declarator leaves a list of parameter names or a chain or parameter decls here. */ ! extern GTY(()) tree last_function_parms; /* A list of objects which have constructors or destructors which reside in the global scope. The decl is stored in the TREE_VALUE slot and the initializer is stored in the TREE_PURPOSE slot. */ ! extern GTY(()) tree static_aggregates; #ifdef DEBUG_CP_BINDING_LEVELS /* Purely for debugging purposes. */ diff -Nrc3pad gcc-3.2.3/gcc/cp/dump.c gcc-3.3/gcc/cp/dump.c *** gcc-3.2.3/gcc/cp/dump.c 2002-03-16 01:08:03.000000000 +0000 --- gcc-3.3/gcc/cp/dump.c 2002-12-30 13:41:17.000000000 +0000 *************** dump_access (di, t) *** 48,55 **** } /* Dump a representation of the specific operator for an overloaded ! operator associated with node t. ! */ static void dump_op (di, t) --- 48,54 ---- } /* Dump a representation of the specific operator for an overloaded ! operator associated with node t. */ static void dump_op (di, t) *************** cp_dump_tree (dump_info, t) *** 264,269 **** --- 263,276 ---- return 1; } + /* Is it a type used as a base? */ + if (TYPE_CONTEXT (t) && TREE_CODE (TYPE_CONTEXT (t)) == TREE_CODE (t) + && CLASSTYPE_AS_BASE (TYPE_CONTEXT (t)) == t) + { + dump_child ("bfld", TYPE_CONTEXT (t)); + return 1; + } + dump_child ("vfld", TYPE_VFIELD (t)); if (CLASSTYPE_TEMPLATE_SPECIALIZATION(t)) dump_string(di, "spec"); *************** cp_dump_tree (dump_info, t) *** 324,330 **** dump_string (di, "global init"); if (DECL_GLOBAL_DTOR_P (t)) dump_string (di, "global fini"); - dump_int (di, "prio", GLOBAL_INIT_PRIORITY (t)); } if (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)) dump_string (di, "pseudo tmpl"); --- 331,336 ---- *************** cp_dump_tree (dump_info, t) *** 390,404 **** dump_child ("decl", TREE_OPERAND (t, 2)); break; - case CTOR_STMT: - dump_stmt (di, t); - if (CTOR_BEGIN_P (t)) - dump_string (di, "begn"); - else - dump_string (di, "end"); - dump_next_stmt (di, t); - break; - case HANDLER: dump_stmt (di, t); dump_child ("parm", HANDLER_PARMS (t)); --- 396,401 ---- *************** cp_dump_tree (dump_info, t) *** 412,423 **** dump_next_stmt (di, t); break; - case SUBOBJECT: - dump_stmt (di, t); - dump_child ("clnp", TREE_OPERAND (t, 0)); - dump_next_stmt (di, t); - break; - case USING_STMT: dump_stmt (di, t); dump_child ("nmsp", USING_STMT_NAMESPACE (t)); --- 409,414 ---- *************** cp_dump_tree (dump_info, t) *** 428,433 **** break; } ! return 0; } - --- 419,423 ---- break; } ! return c_dump_tree (di, t); } diff -Nrc3pad gcc-3.2.3/gcc/cp/error.c gcc-3.3/gcc/cp/error.c *** gcc-3.2.3/gcc/cp/error.c 2003-02-19 15:28:26.000000000 +0000 --- gcc-3.3/gcc/cp/error.c 2003-04-29 20:15:34.000000000 +0000 *************** Boston, MA 02111-1307, USA. */ *** 24,33 **** #include "tree.h" #include "cp-tree.h" #include "real.h" - #include "obstack.h" #include "toplev.h" #include "flags.h" #include "diagnostic.h" enum pad { none, before, after }; --- 24,33 ---- #include "tree.h" #include "cp-tree.h" #include "real.h" #include "toplev.h" #include "flags.h" #include "diagnostic.h" + #include "langhooks-def.h" enum pad { none, before, after }; *************** enum pad { none, before, after }; *** 44,54 **** print_non_consecutive_character ((BUFFER), '<') #define print_template_argument_list_end(BUFFER) \ print_non_consecutive_character ((BUFFER), '>') - #define print_whitespace(BUFFER, TFI) \ - do { \ - output_add_space (BUFFER); \ - put_whitespace (TFI) = none; \ - } while (0) #define print_tree_identifier(BUFFER, TID) \ output_add_string ((BUFFER), IDENTIFIER_POINTER (TID)) #define print_identifier(BUFFER, ID) output_add_string ((BUFFER), (ID)) --- 44,49 ---- *************** static void dump_scope PARAMS ((tree, in *** 104,123 **** static void dump_template_parms PARAMS ((tree, int, int)); static const char *function_category PARAMS ((tree)); ! static void lang_print_error_function PARAMS ((diagnostic_context *, ! const char *)); ! static void maybe_print_instantiation_context PARAMS ((output_buffer *)); ! static void print_instantiation_full_context PARAMS ((output_buffer *)); ! static void print_instantiation_partial_context PARAMS ((output_buffer *, tree, const char *, int)); ! static void cp_diagnostic_starter PARAMS ((output_buffer *, ! diagnostic_context *)); ! static void cp_diagnostic_finalizer PARAMS ((output_buffer *, ! diagnostic_context *)); ! static void cp_print_error_function PARAMS ((output_buffer *, ! diagnostic_context *)); ! static int cp_printer PARAMS ((output_buffer *)); static void print_non_consecutive_character PARAMS ((output_buffer *, int)); static void print_integer PARAMS ((output_buffer *, HOST_WIDE_INT)); static tree locate_error PARAMS ((const char *, va_list)); --- 99,117 ---- static void dump_template_parms PARAMS ((tree, int, int)); static const char *function_category PARAMS ((tree)); ! static void maybe_print_instantiation_context PARAMS ((diagnostic_context *)); ! static void print_instantiation_full_context PARAMS ((diagnostic_context *)); ! static void print_instantiation_partial_context PARAMS ((diagnostic_context *, ! tree, const char *, int)); ! static void cp_diagnostic_starter PARAMS ((diagnostic_context *, ! diagnostic_info *)); ! static void cp_diagnostic_finalizer PARAMS ((diagnostic_context *, ! diagnostic_info *)); ! static void cp_print_error_function PARAMS ((diagnostic_context *, ! diagnostic_info *)); ! static bool cp_printer PARAMS ((output_buffer *, text_info *)); static void print_non_consecutive_character PARAMS ((output_buffer *, int)); static void print_integer PARAMS ((output_buffer *, HOST_WIDE_INT)); static tree locate_error PARAMS ((const char *, va_list)); *************** static tree locate_error PARAMS ((const *** 125,131 **** void init_error () { - print_error_function = lang_print_error_function; diagnostic_starter (global_dc) = cp_diagnostic_starter; diagnostic_finalizer (global_dc) = cp_diagnostic_finalizer; diagnostic_format_decoder (global_dc) = cp_printer; --- 119,124 ---- *************** dump_template_bindings (parms, args) *** 322,329 **** } } ! /* Dump into the obstack a human-readable equivalent of TYPE. FLAGS ! controls the format. */ static void dump_type (t, flags) --- 315,322 ---- } } ! /* Dump a human-readable equivalent of TYPE. FLAGS controls the ! format. */ static void dump_type (t, flags) *************** dump_type (t, flags) *** 387,393 **** which has no name and is not very useful for diagnostics. So look up the equivalent C type and print its name. */ tree elt = TREE_TYPE (t); ! elt = type_for_mode (TYPE_MODE (elt), TREE_UNSIGNED (elt)); dump_type (elt, flags); } break; --- 380,386 ---- which has no name and is not very useful for diagnostics. So look up the equivalent C type and print its name. */ tree elt = TREE_TYPE (t); ! elt = c_common_type_for_mode (TYPE_MODE (elt), TREE_UNSIGNED (elt)); dump_type (elt, flags); } break; *************** dump_type (t, flags) *** 417,423 **** break; case TEMPLATE_TEMPLATE_PARM: ! /* For parameters inside template signature. */ if (TYPE_IDENTIFIER (t)) print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t)); else --- 410,416 ---- break; case TEMPLATE_TEMPLATE_PARM: ! /* For parameters inside template signature. */ if (TYPE_IDENTIFIER (t)) print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t)); else *************** dump_type (t, flags) *** 459,465 **** break; } case TYPENAME_TYPE: ! if (IMPLICIT_TYPENAME_P (t)) output_add_string (scratch_buffer, "typename "); dump_typename (t, flags); break; --- 452,458 ---- break; } case TYPENAME_TYPE: ! if (!IMPLICIT_TYPENAME_P (t)) output_add_string (scratch_buffer, "typename "); dump_typename (t, flags); break; *************** dump_type (t, flags) *** 479,485 **** default: sorry_for_unsupported_tree (t); ! /* Fall through to error. */ case ERROR_MARK: print_identifier (scratch_buffer, ""); --- 472,478 ---- default: sorry_for_unsupported_tree (t); ! /* Fall through to error. */ case ERROR_MARK: print_identifier (scratch_buffer, ""); *************** dump_decl (t, flags) *** 857,863 **** { if ((flags & TFF_DECL_SPECIFIERS) && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM) ! /* Say `class T' not just `T'. */ output_add_string (scratch_buffer, "class "); dump_type (TREE_TYPE (t), flags); --- 850,856 ---- { if ((flags & TFF_DECL_SPECIFIERS) && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM) ! /* Say `class T' not just `T'. */ output_add_string (scratch_buffer, "class "); dump_type (TREE_TYPE (t), flags); *************** dump_decl (t, flags) *** 1018,1023 **** --- 1011,1020 ---- print_tree_identifier (scratch_buffer, DECL_NAME (t)); break; + case BASELINK: + dump_decl (BASELINK_FUNCTIONS (t), flags); + break; + default: sorry_for_unsupported_tree (t); /* Fallthrough to error. */ *************** dump_template_decl (t, flags) *** 1067,1073 **** nreverse(orig_parms); if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)) ! /* Say `template class TT' not just `template TT'. */ output_add_string (scratch_buffer, "class "); } --- 1064,1070 ---- nreverse(orig_parms); if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)) ! /* Say `template class TT' not just `template TT'. */ output_add_string (scratch_buffer, "class "); } *************** dump_template_decl (t, flags) *** 1087,1093 **** dump_function_decl (t, flags | TFF_TEMPLATE_NAME); break; default: ! /* This case can occur with some illegal code. */ dump_type (TREE_TYPE (t), (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0)); --- 1084,1090 ---- dump_function_decl (t, flags | TFF_TEMPLATE_NAME); break; default: ! /* This case can occur with some invalid code. */ dump_type (TREE_TYPE (t), (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0)); *************** dump_template_decl (t, flags) *** 1097,1103 **** /* Pretty print a function decl. There are several ways we want to print a function declaration. The TFF_ bits in FLAGS tells us how to behave. As error can only apply the '#' flag once to give 0 and 1 for V, there ! is %D which doesn't print the throw specs, and %F which does. */ static void dump_function_decl (t, flags) --- 1094,1100 ---- /* Pretty print a function decl. There are several ways we want to print a function declaration. The TFF_ bits in FLAGS tells us how to behave. As error can only apply the '#' flag once to give 0 and 1 for V, there ! is %D which doesn't print the throw specs, and %F which does. */ static void dump_function_decl (t, flags) *************** dump_function_decl (t, flags) *** 1191,1197 **** /* Print a parameter list. If this is for a member function, the member object ptr (and any other hidden args) should have ! already been removed. */ static void dump_parameters (parmtypes, flags) --- 1188,1194 ---- /* Print a parameter list. If this is for a member function, the member object ptr (and any other hidden args) should have ! already been removed. */ static void dump_parameters (parmtypes, flags) *************** dump_parameters (parmtypes, flags) *** 1225,1231 **** print_right_paren (scratch_buffer); } ! /* Print an exception specification. T is the exception specification. */ static void dump_exception_spec (t, flags) --- 1222,1228 ---- print_right_paren (scratch_buffer); } ! /* Print an exception specification. T is the exception specification. */ static void dump_exception_spec (t, flags) *************** dump_function_name (t, flags) *** 1258,1263 **** --- 1255,1263 ---- { tree name = DECL_NAME (t); + if (TREE_CODE (t) == TEMPLATE_DECL) + t = DECL_TEMPLATE_RESULT (t); + /* Don't let the user see __comp_ctor et al. */ if (DECL_CONSTRUCTOR_P (t) || DECL_DESTRUCTOR_P (t)) *************** dump_expr_list (l, flags) *** 1438,1453 **** } } ! /* Print out an expression E under control of FLAGS. */ static void dump_expr (t, flags) tree t; int flags; { ! if (t == 0) ! return; ! switch (TREE_CODE (t)) { case VAR_DECL: --- 1438,1453 ---- } } ! /* Print out an expression E under control of FLAGS. */ static void dump_expr (t, flags) tree t; int flags; { ! if (t == 0) ! return; ! switch (TREE_CODE (t)) { case VAR_DECL: *************** dump_expr (t, flags) *** 1536,1552 **** break; case REAL_CST: ! #ifndef REAL_IS_NOT_DOUBLE ! sprintf (digit_buffer, "%g", TREE_REAL_CST (t)); ! #else ! { ! const unsigned char *p = (const unsigned char *) &TREE_REAL_CST (t); ! size_t i; ! strcpy (digit_buffer, "0x"); ! for (i = 0; i < sizeof TREE_REAL_CST (t); i++) ! sprintf (digit_buffer + 2 + 2*i, "%02x", *p++); ! } ! #endif output_add_string (scratch_buffer, digit_buffer); break; --- 1536,1543 ---- break; case REAL_CST: ! real_to_decimal (digit_buffer, &TREE_REAL_CST (t), ! sizeof (digit_buffer), 0, 1); output_add_string (scratch_buffer, digit_buffer); break; *************** dump_expr (t, flags) *** 1659,1664 **** --- 1650,1656 ---- case NEW_EXPR: { tree type = TREE_OPERAND (t, 1); + tree init = TREE_OPERAND (t, 2); if (NEW_EXPR_USE_GLOBAL (t)) print_scope_operator (scratch_buffer); output_add_string (scratch_buffer, "new "); *************** dump_expr (t, flags) *** 1675,1684 **** TREE_OPERAND (type, 1), integer_one_node)))); dump_type (type, flags); ! if (TREE_OPERAND (t, 2)) { print_left_paren (scratch_buffer); ! dump_expr_list (TREE_OPERAND (t, 2), flags); print_right_paren (scratch_buffer); } } --- 1667,1683 ---- TREE_OPERAND (type, 1), integer_one_node)))); dump_type (type, flags); ! if (init) { print_left_paren (scratch_buffer); ! if (TREE_CODE (init) == TREE_LIST) ! dump_expr_list (init, flags); ! else if (init == void_zero_node) ! /* This representation indicates an empty initializer, ! e.g.: "new int()". */ ! ; ! else ! dump_expr (init, flags); print_right_paren (scratch_buffer); } } *************** dump_expr (t, flags) *** 1862,1868 **** case CONSTRUCTOR: if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))) { ! tree idx = build_component_ref (t, pfn_identifier, NULL_TREE, 0); if (integer_zerop (idx)) { --- 1861,1867 ---- case CONSTRUCTOR: if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))) { ! tree idx = build_ptrmemfunc_access_expr (t, pfn_identifier); if (integer_zerop (idx)) { *************** dump_expr (t, flags) *** 1915,1921 **** /* A::f */ dump_expr (t, flags | TFF_EXPR_IN_PARENS); else if (BASELINK_P (t)) ! dump_expr (OVL_CURRENT (TREE_VALUE (t)), flags | TFF_EXPR_IN_PARENS); else dump_decl (t, flags); } --- 1914,1921 ---- /* A::f */ dump_expr (t, flags | TFF_EXPR_IN_PARENS); else if (BASELINK_P (t)) ! dump_expr (OVL_CURRENT (BASELINK_FUNCTIONS (t)), ! flags | TFF_EXPR_IN_PARENS); else dump_decl (t, flags); } *************** dump_expr (t, flags) *** 2058,2063 **** --- 2058,2067 ---- output_add_string (scratch_buffer, ") break; "); break; + case BASELINK: + print_tree_identifier (scratch_buffer, DECL_NAME (get_first_fn (t))); + break; + case TREE_LIST: if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL) { *************** context_as_string (context, flags) *** 2161,2167 **** return output_finalize_message (scratch_buffer); } ! /* Generate the three forms of printable names for lang_printable_name. */ const char * lang_decl_name (decl, v) --- 2165,2171 ---- return output_finalize_message (scratch_buffer); } ! /* Generate the three forms of printable names for cxx_printable_name. */ const char * lang_decl_name (decl, v) *************** cv_to_string (p, v) *** 2407,2476 **** return output_finalize_message (scratch_buffer); } ! static void ! lang_print_error_function (context, file) diagnostic_context *context; const char *file; { ! output_state os; ! ! default_print_error_function (context, file); ! os = output_buffer_state (context); ! output_set_prefix ((output_buffer *)context, file); ! maybe_print_instantiation_context ((output_buffer *)context); ! output_buffer_state (context) = os; } static void ! cp_diagnostic_starter (buffer, dc) ! output_buffer *buffer; ! diagnostic_context *dc; { ! report_problematic_module (buffer); ! cp_print_error_function (buffer, dc); ! maybe_print_instantiation_context (buffer); ! output_set_prefix (buffer, ! context_as_prefix (diagnostic_file_location (dc), ! diagnostic_line_location (dc), ! diagnostic_is_warning (dc))); } static void ! cp_diagnostic_finalizer (buffer, dc) ! output_buffer *buffer; ! diagnostic_context *dc __attribute__ ((__unused__)); { ! output_destroy_prefix (buffer); } /* Print current function onto BUFFER, in the process of reporting a diagnostic message. Called from cp_diagnostic_starter. */ static void ! cp_print_error_function (buffer, dc) ! output_buffer *buffer; ! diagnostic_context *dc; { ! if (error_function_changed ()) { ! char *prefix = diagnostic_file_location (dc) ! ? file_name_as_prefix (diagnostic_file_location (dc)) : NULL; - output_state os; ! os = output_buffer_state (buffer); ! output_set_prefix (buffer, prefix); if (current_function_decl == NULL) ! output_add_string (buffer, "At global scope:"); else ! output_printf ! (buffer, "In %s `%s':", function_category (current_function_decl), ! (*decl_printable_name) (current_function_decl, 2)); ! output_add_newline (buffer); ! record_last_error_function (); ! output_destroy_prefix (buffer); ! output_buffer_state (buffer) = os; } } --- 2411,2473 ---- return output_finalize_message (scratch_buffer); } ! /* Langhook for print_error_function. */ ! void ! cxx_print_error_function (context, file) diagnostic_context *context; const char *file; { ! lhd_print_error_function (context, file); ! output_set_prefix (&context->buffer, file); ! maybe_print_instantiation_context (context); } static void ! cp_diagnostic_starter (context, diagnostic) ! diagnostic_context *context; ! diagnostic_info *diagnostic; { ! diagnostic_report_current_module (context); ! cp_print_error_function (context, diagnostic); ! maybe_print_instantiation_context (context); ! output_set_prefix (&context->buffer, diagnostic_build_prefix (diagnostic)); } static void ! cp_diagnostic_finalizer (context, diagnostic) ! diagnostic_context *context; ! diagnostic_info *diagnostic __attribute__((unused)); { ! output_destroy_prefix (&context->buffer); } /* Print current function onto BUFFER, in the process of reporting a diagnostic message. Called from cp_diagnostic_starter. */ static void ! cp_print_error_function (context, diagnostic) ! diagnostic_context *context; ! diagnostic_info *diagnostic; { ! if (diagnostic_last_function_changed (context)) { ! const char *old_prefix = output_prefix (&context->buffer); ! char *new_prefix = diagnostic->location.file ! ? file_name_as_prefix (diagnostic->location.file) : NULL; ! output_set_prefix (&context->buffer, new_prefix); if (current_function_decl == NULL) ! output_add_string (&context->buffer, "At global scope:"); else ! output_printf (&context->buffer, "In %s `%s':", ! function_category (current_function_decl), ! cxx_printable_name (current_function_decl, 2)); ! output_add_newline (&context->buffer); ! diagnostic_set_last_function (context); ! output_destroy_prefix (&context->buffer); ! context->buffer.state.prefix = old_prefix; } } *************** function_category (fn) *** 2499,2506 **** /* Report the full context of a current template instantiation, onto BUFFER. */ static void ! print_instantiation_full_context (buffer) ! output_buffer *buffer; { tree p = current_instantiation (); int line = lineno; --- 2496,2503 ---- /* Report the full context of a current template instantiation, onto BUFFER. */ static void ! print_instantiation_full_context (context) ! diagnostic_context *context; { tree p = current_instantiation (); int line = lineno; *************** print_instantiation_full_context (buffer *** 2519,2525 **** if (current_function_decl == TINST_DECL (p)) /* Avoid redundancy with the the "In function" line. */; else ! output_verbatim (buffer, "%s: In instantiation of `%s':\n", file, decl_as_string (TINST_DECL (p), TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE)); --- 2516,2523 ---- if (current_function_decl == TINST_DECL (p)) /* Avoid redundancy with the the "In function" line. */; else ! output_verbatim (&context->buffer, ! "%s: In instantiation of `%s':\n", file, decl_as_string (TINST_DECL (p), TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE)); *************** print_instantiation_full_context (buffer *** 2529,2541 **** } } ! print_instantiation_partial_context (buffer, p, file, line); } /* Same as above but less verbose. */ static void ! print_instantiation_partial_context (buffer, t, file, line) ! output_buffer *buffer; tree t; const char *file; int line; --- 2527,2539 ---- } } ! print_instantiation_partial_context (context, p, file, line); } /* Same as above but less verbose. */ static void ! print_instantiation_partial_context (context, t, file, line) ! diagnostic_context *context; tree t; const char *file; int line; *************** print_instantiation_partial_context (buf *** 2543,2566 **** for (; t; t = TREE_CHAIN (t)) { output_verbatim ! (buffer, "%s:%d: instantiated from `%s'\n", file, line, decl_as_string (TINST_DECL (t), TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE)); line = TINST_LINE (t); file = TINST_FILE (t); } ! output_verbatim (buffer, "%s:%d: instantiated from here\n", file, line); } /* Called from cp_thing to print the template context for an error. */ static void ! maybe_print_instantiation_context (buffer) ! output_buffer *buffer; { if (!problematic_instantiation_changed () || current_instantiation () == 0) return; record_last_problematic_instantiation (); ! print_instantiation_full_context (buffer); } /* Report the bare minimum context of a template instantiation. */ --- 2541,2564 ---- for (; t; t = TREE_CHAIN (t)) { output_verbatim ! (&context->buffer, "%s:%d: instantiated from `%s'\n", file, line, decl_as_string (TINST_DECL (t), TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE)); line = TINST_LINE (t); file = TINST_FILE (t); } ! output_verbatim (&context->buffer, "%s:%d: instantiated from here\n", file, line); } /* Called from cp_thing to print the template context for an error. */ static void ! maybe_print_instantiation_context (context) ! diagnostic_context *context; { if (!problematic_instantiation_changed () || current_instantiation () == 0) return; record_last_problematic_instantiation (); ! print_instantiation_full_context (context); } /* Report the bare minimum context of a template instantiation. */ *************** void *** 2568,2575 **** print_instantiation_context () { print_instantiation_partial_context ! (diagnostic_buffer, current_instantiation (), input_filename, lineno); ! flush_diagnostic_buffer (); } /* Called from output_format -- during diagnostic message processing -- --- 2566,2573 ---- print_instantiation_context () { print_instantiation_partial_context ! (global_dc, current_instantiation (), input_filename, lineno); ! diagnostic_flush_buffer (global_dc); } /* Called from output_format -- during diagnostic message processing -- *************** print_instantiation_context () *** 2585,2610 **** %Q assignment operator. %T type. %V cv-qualifier. */ ! static int ! cp_printer (buffer) output_buffer *buffer; { int verbose = 0; const char *result; ! #define next_tree va_arg (output_buffer_format_args (buffer), tree) ! #define next_tcode va_arg (output_buffer_format_args (buffer), enum tree_code) ! #define next_lang va_arg (output_buffer_format_args (buffer), enum languages) ! #define next_int va_arg (output_buffer_format_args (buffer), int) ! if (*output_buffer_text_cursor (buffer) == '+') ! ++output_buffer_text_cursor (buffer); ! if (*output_buffer_text_cursor (buffer) == '#') { verbose = 1; ! ++output_buffer_text_cursor (buffer); } ! switch (*output_buffer_text_cursor (buffer)) { case 'A': result = args_to_string (next_tree, verbose); break; case 'C': result = code_to_string (next_tcode, verbose); break; --- 2583,2609 ---- %Q assignment operator. %T type. %V cv-qualifier. */ ! static bool ! cp_printer (buffer, text) output_buffer *buffer; + text_info *text; { int verbose = 0; const char *result; ! #define next_tree va_arg (*text->args_ptr, tree) ! #define next_tcode va_arg (*text->args_ptr, enum tree_code) ! #define next_lang va_arg (*text->args_ptr, enum languages) ! #define next_int va_arg (*text->args_ptr, int) ! if (*text->format_spec == '+') ! ++text->format_spec; ! if (*text->format_spec == '#') { verbose = 1; ! ++text->format_spec; } ! switch (*text->format_spec) { case 'A': result = args_to_string (next_tree, verbose); break; case 'C': result = code_to_string (next_tcode, verbose); break; *************** cp_printer (buffer) *** 2619,2629 **** case 'V': result = cv_to_string (next_tree, verbose); break; default: ! return 0; } output_add_string (buffer, result); ! return 1; #undef next_tree #undef next_tcode #undef next_lang --- 2618,2628 ---- case 'V': result = cv_to_string (next_tree, verbose); break; default: ! return false; } output_add_string (buffer, result); ! return true; #undef next_tree #undef next_tcode #undef next_lang *************** void *** 2717,2723 **** cp_error_at VPARAMS ((const char *msgid, ...)) { tree here; ! diagnostic_context dc; VA_OPEN (ap, msgid); VA_FIXEDARG (ap, const char *, msgid); --- 2716,2722 ---- cp_error_at VPARAMS ((const char *msgid, ...)) { tree here; ! diagnostic_info diagnostic; VA_OPEN (ap, msgid); VA_FIXEDARG (ap, const char *, msgid); *************** cp_error_at VPARAMS ((const char *msgid, *** 2727,2736 **** VA_OPEN (ap, msgid); VA_FIXEDARG (ap, const char *, msgid); ! set_diagnostic_context (&dc, msgid, &ap, ! cp_file_of (here), ! cp_line_of (here), /* warning = */ 0); ! report_diagnostic (&dc); VA_CLOSE (ap); } --- 2726,2734 ---- VA_OPEN (ap, msgid); VA_FIXEDARG (ap, const char *, msgid); ! diagnostic_set_info (&diagnostic, msgid, &ap, ! cp_file_of (here), cp_line_of (here), DK_ERROR); ! report_diagnostic (&diagnostic); VA_CLOSE (ap); } *************** void *** 2738,2744 **** cp_warning_at VPARAMS ((const char *msgid, ...)) { tree here; ! diagnostic_context dc; VA_OPEN (ap, msgid); VA_FIXEDARG (ap, const char *, msgid); --- 2736,2742 ---- cp_warning_at VPARAMS ((const char *msgid, ...)) { tree here; ! diagnostic_info diagnostic; VA_OPEN (ap, msgid); VA_FIXEDARG (ap, const char *, msgid); *************** cp_warning_at VPARAMS ((const char *msgi *** 2748,2757 **** VA_OPEN (ap, msgid); VA_FIXEDARG (ap, const char *, msgid); ! set_diagnostic_context (&dc, msgid, &ap, ! cp_file_of (here), ! cp_line_of (here), /* warning = */ 1); ! report_diagnostic (&dc); VA_CLOSE (ap); } --- 2746,2754 ---- VA_OPEN (ap, msgid); VA_FIXEDARG (ap, const char *, msgid); ! diagnostic_set_info (&diagnostic, msgid, &ap, ! cp_file_of (here), cp_line_of (here), DK_WARNING); ! report_diagnostic (&diagnostic); VA_CLOSE (ap); } *************** void *** 2759,2765 **** cp_pedwarn_at VPARAMS ((const char *msgid, ...)) { tree here; ! diagnostic_context dc; VA_OPEN (ap, msgid); VA_FIXEDARG (ap, const char *, msgid); --- 2756,2762 ---- cp_pedwarn_at VPARAMS ((const char *msgid, ...)) { tree here; ! diagnostic_info diagnostic; VA_OPEN (ap, msgid); VA_FIXEDARG (ap, const char *, msgid); *************** cp_pedwarn_at VPARAMS ((const char *msgi *** 2769,2778 **** VA_OPEN (ap, msgid); VA_FIXEDARG (ap, const char *, msgid); ! set_diagnostic_context (&dc, msgid, &ap, ! cp_file_of (here), ! cp_line_of (here), ! /* warning = */ !flag_pedantic_errors); ! report_diagnostic (&dc); VA_CLOSE (ap); } --- 2766,2774 ---- VA_OPEN (ap, msgid); VA_FIXEDARG (ap, const char *, msgid); ! diagnostic_set_info (&diagnostic, msgid, &ap, ! cp_file_of (here), cp_line_of (here), ! pedantic_error_kind()); ! report_diagnostic (&diagnostic); VA_CLOSE (ap); } diff -Nrc3pad gcc-3.2.3/gcc/cp/except.c gcc-3.3/gcc/cp/except.c *** gcc-3.2.3/gcc/cp/except.c 2002-12-01 18:19:12.000000000 +0000 --- gcc-3.3/gcc/cp/except.c 2002-12-04 20:13:01.000000000 +0000 *************** Boston, MA 02111-1307, USA. */ *** 31,40 **** #include "libfuncs.h" #include "cp-tree.h" #include "flags.h" - #include "obstack.h" #include "output.h" #include "except.h" #include "toplev.h" static void push_eh_cleanup PARAMS ((tree)); static tree prepare_eh_type PARAMS ((tree)); --- 31,40 ---- #include "libfuncs.h" #include "cp-tree.h" #include "flags.h" #include "output.h" #include "except.h" #include "toplev.h" + #include "tree-inline.h" static void push_eh_cleanup PARAMS ((tree)); static tree prepare_eh_type PARAMS ((tree)); *************** static void push_eh_cleanup PARAMS ((tre *** 46,60 **** static bool decl_is_java_type PARAMS ((tree decl, int err)); static void initialize_handler_parm PARAMS ((tree, tree)); static tree do_allocate_exception PARAMS ((tree)); static int complete_ptr_ref_or_void_ptr_p PARAMS ((tree, tree)); static bool is_admissible_throw_operand PARAMS ((tree)); static int can_convert_eh PARAMS ((tree, tree)); static void check_handlers_1 PARAMS ((tree, tree)); static tree cp_protect_cleanup_actions PARAMS ((void)); - #include "decl.h" - #include "obstack.h" - /* Sets up all the global eh stuff that needs to be initialized at the start of compilation. */ --- 46,59 ---- static bool decl_is_java_type PARAMS ((tree decl, int err)); static void initialize_handler_parm PARAMS ((tree, tree)); static tree do_allocate_exception PARAMS ((tree)); + static tree stabilize_throw_expr PARAMS ((tree, tree *)); + static tree wrap_cleanups_r PARAMS ((tree *, int *, void *)); static int complete_ptr_ref_or_void_ptr_p PARAMS ((tree, tree)); static bool is_admissible_throw_operand PARAMS ((tree)); static int can_convert_eh PARAMS ((tree, tree)); static void check_handlers_1 PARAMS ((tree, tree)); static tree cp_protect_cleanup_actions PARAMS ((void)); /* Sets up all the global eh stuff that needs to be initialized at the start of compilation. */ *************** prepare_eh_type (type) *** 118,124 **** } /* Build the address of a typeinfo decl for use in the runtime ! matching field of the exception model. */ static tree build_eh_type_type (type) --- 117,123 ---- } /* Build the address of a typeinfo decl for use in the runtime ! matching field of the exception model. */ static tree build_eh_type_type (type) *************** static int *** 175,191 **** dtor_nothrow (type) tree type; { - tree fn; - if (type == NULL_TREE) return 0; if (! TYPE_HAS_DESTRUCTOR (type)) return 1; ! fn = lookup_member (type, dtor_identifier, 0, 0); ! fn = TREE_VALUE (fn); ! return TREE_NOTHROW (fn); } /* Build up a call to __cxa_end_catch, to destroy the exception object --- 174,186 ---- dtor_nothrow (type) tree type; { if (type == NULL_TREE) return 0; if (! TYPE_HAS_DESTRUCTOR (type)) return 1; ! return TREE_NOTHROW (CLASSTYPE_DESTRUCTORS (type)); } /* Build up a call to __cxa_end_catch, to destroy the exception object *************** do_allocate_exception (type) *** 518,524 **** #if 0 /* Call __cxa_free_exception from a cleanup. This is never invoked ! directly. */ static tree do_free_exception (ptr) --- 513,519 ---- #if 0 /* Call __cxa_free_exception from a cleanup. This is never invoked ! directly, but see the comment for stabilize_throw_expr. */ static tree do_free_exception (ptr) *************** do_free_exception (ptr) *** 540,545 **** --- 535,626 ---- } #endif + /* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR. + Called from build_throw via walk_tree_without_duplicates. */ + + static tree + wrap_cleanups_r (tp, walk_subtrees, data) + tree *tp; + int *walk_subtrees ATTRIBUTE_UNUSED; + void *data ATTRIBUTE_UNUSED; + { + tree exp = *tp; + tree cleanup; + + /* Don't walk into types. */ + if (TYPE_P (exp)) + { + *walk_subtrees = 0; + return NULL_TREE; + } + if (TREE_CODE (exp) != TARGET_EXPR) + return NULL_TREE; + + cleanup = TARGET_EXPR_CLEANUP (exp); + if (cleanup) + { + cleanup = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (cleanup), cleanup); + TARGET_EXPR_CLEANUP (exp) = cleanup; + } + + /* Keep iterating. */ + return NULL_TREE; + } + + /* Like stabilize_expr, but specifically for a thrown expression. When + throwing a temporary class object, we want to construct it directly into + the thrown exception, so we look past the TARGET_EXPR and stabilize the + arguments of the call instead. + + The case where EXP is a call to a function returning a class is a bit of + a grey area in the standard; it's unclear whether or not it should be + allowed to throw. I'm going to say no, as that allows us to optimize + this case without worrying about deallocating the exception object if it + does. The alternatives would be either not optimizing this case, or + wrapping the initialization in a TRY_CATCH_EXPR to call do_free_exception + rather than in a MUST_NOT_THROW_EXPR, for this case only. */ + + static tree + stabilize_throw_expr (exp, initp) + tree exp; + tree *initp; + { + tree init_expr; + + if (TREE_CODE (exp) == TARGET_EXPR + && TREE_CODE (TARGET_EXPR_INITIAL (exp)) == AGGR_INIT_EXPR + && flag_elide_constructors) + { + tree aggr_init = AGGR_INIT_EXPR_CHECK (TARGET_EXPR_INITIAL (exp)); + tree args = TREE_OPERAND (aggr_init, 1); + tree newargs = NULL_TREE; + tree *p = &newargs; + + init_expr = void_zero_node; + for (; args; args = TREE_CHAIN (args)) + { + tree arg = TREE_VALUE (args); + tree arg_init_expr; + + arg = stabilize_expr (arg, &arg_init_expr); + + if (TREE_SIDE_EFFECTS (arg_init_expr)) + init_expr = build (COMPOUND_EXPR, void_type_node, init_expr, + arg_init_expr); + *p = tree_cons (NULL_TREE, arg, NULL_TREE); + p = &TREE_CHAIN (*p); + } + TREE_OPERAND (aggr_init, 1) = newargs; + } + else + { + exp = stabilize_expr (exp, &init_expr); + } + + *initp = init_expr; + return exp; + } + /* Build a throw expression. */ tree *************** build_throw (exp) *** 585,594 **** { tree throw_type; tree cleanup; - tree stmt_expr; - tree compound_stmt; tree object, ptr; tree tmp; fn = get_identifier ("__cxa_throw"); if (IDENTIFIER_GLOBAL_VALUE (fn)) --- 666,674 ---- { tree throw_type; tree cleanup; tree object, ptr; tree tmp; + tree temp_expr, allocate_expr; fn = get_identifier ("__cxa_throw"); if (IDENTIFIER_GLOBAL_VALUE (fn)) *************** build_throw (exp) *** 614,621 **** fn = push_throw_library_fn (fn, tmp); } - begin_init_stmts (&stmt_expr, &compound_stmt); - /* throw expression */ /* First, decay it. */ exp = decay_conversion (exp); --- 694,699 ---- *************** build_throw (exp) *** 633,669 **** the call to __cxa_allocate_exception first (which doesn't matter, since it can't throw). */ ! my_friendly_assert (stmts_are_full_exprs_p () == 1, 19990926); ! ! /* Store the throw expression into a temp. This can be less ! efficient than storing it into the allocated space directly, but ! if we allocated the space first we would have to deal with ! cleaning it up if evaluating this expression throws. */ ! if (TREE_SIDE_EFFECTS (exp)) ! { ! tmp = create_temporary_var (TREE_TYPE (exp)); ! DECL_INITIAL (tmp) = exp; ! cp_finish_decl (tmp, exp, NULL_TREE, LOOKUP_ONLYCONVERTING); ! exp = tmp; ! } /* Allocate the space for the exception. */ ! ptr = create_temporary_var (ptr_type_node); ! DECL_REGISTER (ptr) = 1; ! cp_finish_decl (ptr, NULL_TREE, NULL_TREE, LOOKUP_ONLYCONVERTING); ! tmp = do_allocate_exception (TREE_TYPE (exp)); ! tmp = build_modify_expr (ptr, INIT_EXPR, tmp); ! finish_expr_stmt (tmp); ! object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr); object = build_indirect_ref (object, NULL); ! exp = build_modify_expr (object, INIT_EXPR, exp); if (exp == error_mark_node) ! error (" in thrown expression"); exp = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (exp), exp); ! finish_expr_stmt (exp); throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object))); --- 711,750 ---- the call to __cxa_allocate_exception first (which doesn't matter, since it can't throw). */ ! /* Pre-evaluate the thrown expression first, since if we allocated ! the space first we would have to deal with cleaning it up if ! evaluating this expression throws. */ ! exp = stabilize_throw_expr (exp, &temp_expr); /* Allocate the space for the exception. */ ! allocate_expr = do_allocate_exception (TREE_TYPE (exp)); ! allocate_expr = get_target_expr (allocate_expr); ! ptr = TARGET_EXPR_SLOT (allocate_expr); object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr); object = build_indirect_ref (object, NULL); ! /* And initialize the exception object. */ ! exp = build_init (object, exp, LOOKUP_ONLYCONVERTING); if (exp == error_mark_node) ! { ! error (" in thrown expression"); ! return error_mark_node; ! } exp = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (exp), exp); ! /* Prepend the allocation. */ ! exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp); ! if (temp_expr != void_zero_node) ! { ! /* Prepend the calculation of the throw expression. Also, force ! any cleanups from the expression to be evaluated here so that ! we don't have to do them during unwinding. But first wrap ! them in MUST_NOT_THROW_EXPR, since they are run after the ! exception object is initialized. */ ! walk_tree_without_duplicates (&temp_expr, wrap_cleanups_r, 0); ! exp = build (COMPOUND_EXPR, TREE_TYPE (exp), temp_expr, exp); ! exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp); ! } throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object))); *************** build_throw (exp) *** 671,679 **** { cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)), complete_dtor_identifier, 0); ! cleanup = TREE_VALUE (cleanup); mark_used (cleanup); ! mark_addressable (cleanup); /* Pretend it's a normal function. */ cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup); } --- 752,760 ---- { cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)), complete_dtor_identifier, 0); ! cleanup = BASELINK_FUNCTIONS (cleanup); mark_used (cleanup); ! cxx_mark_addressable (cleanup); /* Pretend it's a normal function. */ cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup); } *************** build_throw (exp) *** 686,698 **** tmp = tree_cons (NULL_TREE, cleanup, NULL_TREE); tmp = tree_cons (NULL_TREE, throw_type, tmp); tmp = tree_cons (NULL_TREE, ptr, tmp); - tmp = build_function_call (fn, tmp); - /* ??? Indicate that this function call throws throw_type. */ ! finish_expr_stmt (tmp); ! ! exp = finish_init_stmts (stmt_expr, compound_stmt); } else { --- 767,777 ---- tmp = tree_cons (NULL_TREE, cleanup, NULL_TREE); tmp = tree_cons (NULL_TREE, throw_type, tmp); tmp = tree_cons (NULL_TREE, ptr, tmp); /* ??? Indicate that this function call throws throw_type. */ + tmp = build_function_call (fn, tmp); ! /* Tack on the initialization stuff. */ ! exp = build (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp); } else { *************** build_throw (exp) *** 708,713 **** --- 787,794 ---- (fn, build_function_type (void_type_node, void_list_node)); } + /* ??? Indicate that this function call allows exceptions of the type + of the enclosing catch block (if known). */ exp = build_function_call (fn, NULL_TREE); } *************** build_throw (exp) *** 718,724 **** /* Make sure TYPE is complete, pointer to complete, reference to complete, or pointer to cv void. Issue diagnostic on failure. ! Return the zero on failure and non-zero on success. FROM can be the expr or decl from whence TYPE came, if available. */ static int --- 799,805 ---- /* Make sure TYPE is complete, pointer to complete, reference to complete, or pointer to cv void. Issue diagnostic on failure. ! Return the zero on failure and nonzero on success. FROM can be the expr or decl from whence TYPE came, if available. */ static int diff -Nrc3pad gcc-3.2.3/gcc/cp/expr.c gcc-3.3/gcc/cp/expr.c *** gcc-3.2.3/gcc/cp/expr.c 2003-03-12 22:59:37.000000000 +0000 --- gcc-3.3/gcc/cp/expr.c 2003-03-12 22:51:56.000000000 +0000 *************** Boston, MA 02111-1307, USA. */ *** 32,40 **** #include "except.h" #include "tm_p.h" - static rtx cplus_expand_expr PARAMS ((tree, rtx, enum machine_mode, - enum expand_modifier)); - /* Hook used by output_constant to expand language-specific constants. */ --- 32,37 ---- *************** cplus_expand_constant (cst) *** 79,90 **** /* Hook used by expand_expr to expand language-specific tree codes. */ ! static rtx ! cplus_expand_expr (exp, target, tmode, modifier) tree exp; rtx target; enum machine_mode tmode; ! enum expand_modifier modifier; { tree type = TREE_TYPE (exp); register enum machine_mode mode = TYPE_MODE (type); --- 76,87 ---- /* Hook used by expand_expr to expand language-specific tree codes. */ ! rtx ! cxx_expand_expr (exp, target, tmode, modifier) tree exp; rtx target; enum machine_mode tmode; ! int modifier; /* Actually an enum expand_modifier. */ { tree type = TREE_TYPE (exp); register enum machine_mode mode = TYPE_MODE (type); *************** cplus_expand_expr (exp, target, tmode, m *** 105,111 **** target, tmode, modifier); case OFFSET_REF: ! /* Offset refs should not make it through to here. */ abort (); return const0_rtx; --- 102,108 ---- target, tmode, modifier); case OFFSET_REF: ! /* Offset refs should not make it through to here. */ abort (); return const0_rtx; *************** cplus_expand_expr (exp, target, tmode, m *** 130,146 **** /* NOTREACHED */ return NULL; } - - void - init_cplus_expand () - { - lang_expand_expr = cplus_expand_expr; - } - - int - extract_init (decl, init) - tree decl ATTRIBUTE_UNUSED, init ATTRIBUTE_UNUSED; - { - return 0; - } - --- 127,129 ---- diff -Nrc3pad gcc-3.2.3/gcc/cp/friend.c gcc-3.3/gcc/cp/friend.c *** gcc-3.2.3/gcc/cp/friend.c 2002-02-04 08:55:43.000000000 +0000 --- gcc-3.3/gcc/cp/friend.c 2003-01-31 12:26:10.000000000 +0000 *************** Boston, MA 02111-1307, USA. */ *** 30,36 **** /* Friend data structures are described in cp-tree.h. */ ! /* Returns non-zero if SUPPLICANT is a friend of TYPE. */ int is_friend (type, supplicant) --- 30,36 ---- /* Friend data structures are described in cp-tree.h. */ ! /* Returns nonzero if SUPPLICANT is a friend of TYPE. */ int is_friend (type, supplicant) *************** is_friend (type, supplicant) *** 64,69 **** --- 64,73 ---- if (supplicant == TREE_VALUE (friends)) return 1; + /* We haven't completed the instantiation yet. */ + if (TREE_CODE (supplicant) == TEMPLATE_DECL) + return 1; + /* Temporarily, we are more lenient to deal with nested friend functions, for which there can be more than one FUNCTION_DECL, despite being the *************** is_friend (type, supplicant) *** 114,120 **** else context = NULL_TREE; ! /* A namespace is not friend to anybody. */ if (context && TREE_CODE (context) == NAMESPACE_DECL) context = NULL_TREE; --- 118,124 ---- else context = NULL_TREE; ! /* A namespace is not friend to anybody. */ if (context && TREE_CODE (context) == NAMESPACE_DECL) context = NULL_TREE; *************** add_friend (type, decl) *** 159,164 **** --- 163,171 ---- return; } } + + maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1); + TREE_VALUE (list) = tree_cons (error_mark_node, decl, TREE_VALUE (list)); return; *************** add_friend (type, decl) *** 166,171 **** --- 173,180 ---- list = TREE_CHAIN (list); } + maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1); + DECL_FRIENDLIST (typedecl) = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl), DECL_FRIENDLIST (typedecl)); *************** make_friend_class (type, friend_type) *** 198,221 **** return; } - if (CLASS_TYPE_P (friend_type) - && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type) - && uses_template_parms (friend_type)) - { - /* [temp.friend] - - Friend declarations shall not declare partial - specializations. */ - error ("partial specialization `%T' declared `friend'", - friend_type); - return; - } - if (processing_template_decl > template_class_depth (type)) /* If the TYPE is a template then it makes sense for it to be friends with itself; this means that each instantiation is friends with all other instantiations. */ ! is_template_friend = 1; else if (same_type_p (type, friend_type)) { pedwarn ("class `%T' is implicitly friends with itself", --- 207,231 ---- return; } if (processing_template_decl > template_class_depth (type)) /* If the TYPE is a template then it makes sense for it to be friends with itself; this means that each instantiation is friends with all other instantiations. */ ! { ! if (CLASS_TYPE_P (friend_type) ! && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type) ! && uses_template_parms (friend_type)) ! { ! /* [temp.friend] ! Friend declarations shall not declare partial ! specializations. */ ! error ("partial specialization `%T' declared `friend'", ! friend_type); ! return; ! } ! ! is_template_friend = 1; ! } else if (same_type_p (type, friend_type)) { pedwarn ("class `%T' is implicitly friends with itself", *************** make_friend_class (type, friend_type) *** 230,236 **** A friend of a class or class template can be a function or class template, a specialization of a function template or class template, or an ordinary (nontemplate) function or ! class. */ if (!is_template_friend) ;/* ok */ else if (TREE_CODE (friend_type) == TYPENAME_TYPE) --- 240,246 ---- A friend of a class or class template can be a function or class template, a specialization of a function template or class template, or an ordinary (nontemplate) function or ! class. */ if (!is_template_friend) ;/* ok */ else if (TREE_CODE (friend_type) == TYPENAME_TYPE) *************** make_friend_class (type, friend_type) *** 267,272 **** --- 277,284 ---- TREE_VALUE (classes), type); else { + maybe_add_class_template_decl_list (type, friend_type, /*friend_p=*/1); + CLASSTYPE_FRIEND_CLASSES (type) = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type)); if (is_template_friend) *************** do_friend (ctype, declarator, decl, parm *** 396,409 **** /* This must be a local class, so pushdecl will be ok, and insert an unqualified friend into the local scope (rather than the containing namespace scope, which the ! next choice will do). */ decl = pushdecl (decl); else { /* We can't use pushdecl, as we might be in a template class specialization, and pushdecl will insert an unqualified friend decl into the template parameter ! scope, rather than the namespace containing it. */ tree ns = decl_namespace_context (decl); push_nested_namespace (ns); --- 408,421 ---- /* This must be a local class, so pushdecl will be ok, and insert an unqualified friend into the local scope (rather than the containing namespace scope, which the ! next choice will do). */ decl = pushdecl (decl); else { /* We can't use pushdecl, as we might be in a template class specialization, and pushdecl will insert an unqualified friend decl into the template parameter ! scope, rather than the namespace containing it. */ tree ns = decl_namespace_context (decl); push_nested_namespace (ns); diff -Nrc3pad gcc-3.2.3/gcc/cp/g++spec.c gcc-3.3/gcc/cp/g++spec.c *** gcc-3.2.3/gcc/cp/g++spec.c 2002-04-23 16:36:52.000000000 +0000 --- gcc-3.3/gcc/cp/g++spec.c 2003-03-11 00:59:25.000000000 +0000 *************** lang_specific_driver (in_argc, in_argv, *** 51,60 **** { int i, j; ! /* If non-zero, the user gave us the `-p' or `-pg' flag. */ int saw_profile_flag = 0; ! /* If non-zero, the user gave us the `-v' flag. */ int saw_verbose_flag = 0; /* This will be 0 if we encounter a situation where we should not --- 51,60 ---- { int i, j; ! /* If nonzero, the user gave us the `-p' or `-pg' flag. */ int saw_profile_flag = 0; ! /* If nonzero, the user gave us the `-v' flag. */ int saw_verbose_flag = 0; /* This will be 0 if we encounter a situation where we should not *************** lang_specific_driver (in_argc, in_argv, *** 73,79 **** /* The new argument list will be contained in this. */ const char **arglist; ! /* Non-zero if we saw a `-xfoo' language specification on the command line. Used to avoid adding our own -xc++ if the user already gave a language for the file. */ int saw_speclang = 0; --- 73,79 ---- /* The new argument list will be contained in this. */ const char **arglist; ! /* Nonzero if we saw a `-xfoo' language specification on the command line. Used to avoid adding our own -xc++ if the user already gave a language for the file. */ int saw_speclang = 0; *************** lang_specific_driver (in_argc, in_argv, *** 178,183 **** --- 178,185 ---- else if (strcmp (argv[i], "-static-libgcc") == 0 || strcmp (argv[i], "-static") == 0) shared_libgcc = 0; + else if (DEFAULT_WORD_SWITCH_TAKES_ARG (&argv[i][1])) + i++; else /* Pass other options through. */ continue; *************** lang_specific_driver (in_argc, in_argv, *** 272,277 **** --- 274,286 ---- { arglist[j++] = saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX; added_libraries++; + #ifdef USE_LIBUNWIND_EXCEPTIONS + # ifndef LIBUNWIND + # define LIBUNWIND "-lunwind" + # endif + arglist[j++] = LIBUNWIND; + added_libraries++; + #endif } if (saw_math) arglist[j++] = saw_math; *************** lang_specific_driver (in_argc, in_argv, *** 292,302 **** *in_added_libraries = added_libraries; } ! /* Called before linking. Returns 0 on success and -1 on failure. */ ! int lang_specific_pre_link () /* Not used for C++. */ { return 0; } ! /* Number of extra output files that lang_specific_pre_link may generate. */ ! int lang_specific_extra_outfiles = 0; /* Not used for C++. */ --- 301,317 ---- *in_added_libraries = added_libraries; } ! /* Called before linking. Returns 0 on success and -1 on failure. */ ! int lang_specific_pre_link () /* Not used for C++. */ { return 0; } ! /* Number of extra output files that lang_specific_pre_link may generate. */ ! int lang_specific_extra_outfiles = 0; /* Not used for C++. */ ! ! /* Table of language-specific spec functions. */ ! const struct spec_function lang_specific_spec_functions[] = ! { ! { 0, 0 } ! }; diff -Nrc3pad gcc-3.2.3/gcc/cp/init.c gcc-3.3/gcc/cp/init.c *** gcc-3.2.3/gcc/cp/init.c 2002-12-01 20:40:36.000000000 +0000 --- gcc-3.3/gcc/cp/init.c 2003-04-15 14:58:00.000000000 +0000 *************** *** 1,6 **** /* Handle initialization things in C++. Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, ! 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. --- 1,6 ---- /* Handle initialization things in C++. Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, ! 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. *************** Boston, MA 02111-1307, USA. */ *** 34,81 **** #include "toplev.h" #include "ggc.h" ! static void expand_aggr_vbase_init_1 PARAMS ((tree, tree, tree, tree)); ! static void construct_virtual_bases PARAMS ((tree, tree, tree, tree, tree)); static void expand_aggr_init_1 PARAMS ((tree, tree, tree, tree, int)); static void expand_default_init PARAMS ((tree, tree, tree, tree, int)); static tree build_vec_delete_1 PARAMS ((tree, tree, tree, special_function_kind, int)); ! static void perform_member_init PARAMS ((tree, tree, int)); ! static void sort_base_init PARAMS ((tree, tree, tree *, tree *)); static tree build_builtin_delete_call PARAMS ((tree)); static int member_init_ok_or_else PARAMS ((tree, tree, tree)); static void expand_virtual_init PARAMS ((tree, tree)); ! static tree sort_member_init PARAMS ((tree, tree)); static tree initializing_context PARAMS ((tree)); static void expand_cleanup_for_base PARAMS ((tree, tree)); static tree get_temp_regvar PARAMS ((tree, tree)); static tree dfs_initialize_vtbl_ptrs PARAMS ((tree, void *)); ! static tree build_default_init PARAMS ((tree)); static tree build_new_1 PARAMS ((tree)); static tree get_cookie_size PARAMS ((tree)); static tree build_dtor_call PARAMS ((tree, special_function_kind, int)); static tree build_field_list PARAMS ((tree, tree, int *)); static tree build_vtbl_address PARAMS ((tree)); - /* Set up local variable for this file. MUST BE CALLED AFTER - INIT_DECL_PROCESSING. */ - - static tree BI_header_type; - - void init_init_processing () - { - tree fields[1]; - - /* Define the structure that holds header information for - arrays allocated via operator new. */ - BI_header_type = make_aggr_type (RECORD_TYPE); - fields[0] = build_decl (FIELD_DECL, nelts_identifier, sizetype); - - finish_builtin_type (BI_header_type, "__new_cookie", fields, - 0, double_type_node); - - ggc_add_tree_root (&BI_header_type, 1); - } - /* We are about to generate some complex initialization code. Conceptually, it is all a single expression. However, we may want to include conditionals, loops, and other such statement-level --- 34,59 ---- #include "toplev.h" #include "ggc.h" ! static void construct_virtual_base (tree, tree); static void expand_aggr_init_1 PARAMS ((tree, tree, tree, tree, int)); static void expand_default_init PARAMS ((tree, tree, tree, tree, int)); static tree build_vec_delete_1 PARAMS ((tree, tree, tree, special_function_kind, int)); ! static void perform_member_init (tree, tree); static tree build_builtin_delete_call PARAMS ((tree)); static int member_init_ok_or_else PARAMS ((tree, tree, tree)); static void expand_virtual_init PARAMS ((tree, tree)); ! static tree sort_mem_initializers (tree, tree); static tree initializing_context PARAMS ((tree)); static void expand_cleanup_for_base PARAMS ((tree, tree)); static tree get_temp_regvar PARAMS ((tree, tree)); static tree dfs_initialize_vtbl_ptrs PARAMS ((tree, void *)); ! static tree build_default_init PARAMS ((tree, tree)); static tree build_new_1 PARAMS ((tree)); static tree get_cookie_size PARAMS ((tree)); static tree build_dtor_call PARAMS ((tree, special_function_kind, int)); static tree build_field_list PARAMS ((tree, tree, int *)); static tree build_vtbl_address PARAMS ((tree)); /* We are about to generate some complex initialization code. Conceptually, it is all a single expression. However, we may want to include conditionals, loops, and other such statement-level *************** initialize_vtbl_ptrs (addr) *** 167,173 **** list = build_tree_list (type, addr); /* Walk through the hierarchy, initializing the vptr in each base ! class. We do these in pre-order because can't find the virtual bases for a class until we've initialized the vtbl for that class. */ dfs_walk_real (TYPE_BINFO (type), dfs_initialize_vtbl_ptrs, --- 145,151 ---- list = build_tree_list (type, addr); /* Walk through the hierarchy, initializing the vptr in each base ! class. We do these in pre-order because we can't find the virtual bases for a class until we've initialized the vtbl for that class. */ dfs_walk_real (TYPE_BINFO (type), dfs_initialize_vtbl_ptrs, *************** initialize_vtbl_ptrs (addr) *** 176,261 **** dfs_marked_real_bases_queue_p, type); } ! /* Types containing pointers to data members cannot be ! zero-initialized with zeros, because the NULL value for such ! pointers is -1. ! ! TYPE is a type that requires such zero initialization. The ! returned value is the initializer. */ tree ! build_forced_zero_init (type) ! tree type; { ! tree init = NULL; ! if (AGGREGATE_TYPE_P (type) && !TYPE_PTRMEMFUNC_P (type)) { ! /* This is a default initialization of an aggregate, but not one of ! non-POD class type. We cleverly notice that the initialization ! rules in such a case are the same as for initialization with an ! empty brace-initialization list. */ ! init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE); } ! else if (TREE_CODE (type) == REFERENCE_TYPE) ! /* --if T is a reference type, no initialization is performed. */ ! return NULL_TREE; ! else { ! init = integer_zero_node; ! ! if (TREE_CODE (type) == ENUMERAL_TYPE) ! /* We must make enumeral types the right type. */ ! init = fold (build1 (NOP_EXPR, type, init)); } ! init = digest_init (type, init, 0); return init; } ! /* [dcl.init]: ! To default-initialize an object of type T means: ! --if T is a non-POD class type (clause _class_), the default construc- ! tor for T is called (and the initialization is ill-formed if T has ! no accessible default constructor); ! --if T is an array type, each element is default-initialized; ! --otherwise, the storage for the object is zero-initialized. ! A program that calls for default-initialization of an entity of refer- ! ence type is ill-formed. */ ! static tree ! build_default_init (type) ! tree type; ! { ! tree init = NULL_TREE; if (TYPE_NEEDS_CONSTRUCTING (type)) - /* Other code will handle running the default constructor. We can't do - anything with a CONSTRUCTOR for arrays here, as that would imply - copy-initialization. */ return NULL_TREE; ! ! return build_forced_zero_init (type); } ! /* Subroutine of emit_base_init. */ static void ! perform_member_init (member, init, explicit) ! tree member, init; ! int explicit; { tree decl; tree type = TREE_TYPE (member); ! decl = build_component_ref (current_class_ref, member, NULL_TREE, explicit); if (decl == error_mark_node) return; --- 154,341 ---- dfs_marked_real_bases_queue_p, type); } ! /* Return an expression for the zero-initialization of an object with ! type T. This expression will either be a constant (in the case ! that T is a scalar), or a CONSTRUCTOR (in the case that T is an ! aggregate). In either case, the value can be used as DECL_INITIAL ! for a decl of the indicated TYPE; it is a valid static initializer. ! If NELTS is non-NULL, and TYPE is an ARRAY_TYPE, NELTS is the ! number of elements in the array. If STATIC_STORAGE_P is TRUE, ! initializers are only generated for entities for which ! zero-initialization does not simply mean filling the storage with ! zero bytes. */ tree ! build_zero_init (tree type, tree nelts, bool static_storage_p) { ! tree init = NULL_TREE; ! /* [dcl.init] ! ! To zero-initialization storage for an object of type T means: ! ! -- if T is a scalar type, the storage is set to the value of zero ! converted to T. ! ! -- if T is a non-union class type, the storage for each nonstatic ! data member and each base-class subobject is zero-initialized. ! ! -- if T is a union type, the storage for its first data member is ! zero-initialized. ! ! -- if T is an array type, the storage for each element is ! zero-initialized. ! ! -- if T is a reference type, no initialization is performed. */ ! ! if (type == error_mark_node) ! ; ! else if (static_storage_p && zero_init_p (type)) ! /* In order to save space, we do not explicitly build initializers ! for items that do not need them. GCC's semantics are that ! items with static storage duration that are not otherwise ! initialized are initialized to zero. */ ! ; ! else if (SCALAR_TYPE_P (type)) ! init = convert (type, integer_zero_node); ! else if (CLASS_TYPE_P (type)) { ! tree field; ! tree inits; ! ! /* Build a constructor to contain the initializations. */ ! init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE); ! /* Iterate over the fields, building initializations. */ ! inits = NULL_TREE; ! for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) ! { ! if (TREE_CODE (field) != FIELD_DECL) ! continue; ! ! /* Note that for class types there will be FIELD_DECLs ! corresponding to base classes as well. Thus, iterating ! over TYPE_FIELDs will result in correct initialization of ! all of the subobjects. */ ! if (static_storage_p && !zero_init_p (TREE_TYPE (field))) ! inits = tree_cons (field, ! build_zero_init (TREE_TYPE (field), ! /*nelts=*/NULL_TREE, ! static_storage_p), ! inits); ! ! /* For unions, only the first field is initialized. */ ! if (TREE_CODE (type) == UNION_TYPE) ! break; ! } ! CONSTRUCTOR_ELTS (init) = nreverse (inits); } ! else if (TREE_CODE (type) == ARRAY_TYPE) { ! tree index; ! tree max_index; ! tree inits; ! ! /* Build a constructor to contain the initializations. */ ! init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE); ! /* Iterate over the array elements, building initializations. */ ! inits = NULL_TREE; ! max_index = nelts ? nelts : array_type_nelts (type); ! for (index = size_zero_node; ! !tree_int_cst_lt (max_index, index); ! index = size_binop (PLUS_EXPR, index, size_one_node)) ! inits = tree_cons (index, ! build_zero_init (TREE_TYPE (type), ! /*nelts=*/NULL_TREE, ! static_storage_p), ! inits); ! CONSTRUCTOR_ELTS (init) = nreverse (inits); } + else if (TREE_CODE (type) == REFERENCE_TYPE) + ; + else + abort (); ! /* In all cases, the initializer is a constant. */ ! if (init) ! TREE_CONSTANT (init) = 1; return init; } ! /* Build an expression for the default-initialization of an object of ! the indicated TYPE. If NELTS is non-NULL, and TYPE is an ! ARRAY_TYPE, NELTS is the number of elements in the array. If ! initialization of TYPE requires calling constructors, this function ! returns NULL_TREE; the caller is responsible for arranging for the ! constructors to be called. */ ! static tree ! build_default_init (type, nelts) ! tree type; ! tree nelts; ! { ! /* [dcl.init]: ! To default-initialize an object of type T means: ! --if T is a non-POD class type (clause _class_), the default construc- ! tor for T is called (and the initialization is ill-formed if T has ! no accessible default constructor); ! --if T is an array type, each element is default-initialized; ! --otherwise, the storage for the object is zero-initialized. ! A program that calls for default-initialization of an entity of refer- ! ence type is ill-formed. */ + /* If TYPE_NEEDS_CONSTRUCTING is true, the caller is responsible for + performing the initialization. This is confusing in that some + non-PODs do not have TYPE_NEEDS_CONSTRUCTING set. (For example, + a class with a pointer-to-data member as a non-static data member + does not have TYPE_NEEDS_CONSTRUCTING set.) Therefore, we end up + passing non-PODs to build_zero_init below, which is contrary to + the semantics quoted above from [dcl.init]. + + It happens, however, that the behavior of the constructor the + standard says we should have generated would be precisely the + same as that obtained by calling build_zero_init below, so things + work out OK. */ if (TYPE_NEEDS_CONSTRUCTING (type)) return NULL_TREE; ! ! /* At this point, TYPE is either a POD class type, an array of POD ! classes, or something even more inoccuous. */ ! return build_zero_init (type, nelts, /*static_storage_p=*/false); } ! /* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of ! arguments. If TREE_LIST is void_type_node, an empty initializer ! list was given; if NULL_TREE no initializer was given. */ static void ! perform_member_init (tree member, tree init) { tree decl; tree type = TREE_TYPE (member); + bool explicit; ! explicit = (init != NULL_TREE); + /* Effective C++ rule 12 requires that all data members be + initialized. */ + if (warn_ecpp && !explicit && TREE_CODE (type) != ARRAY_TYPE) + warning ("`%D' should be initialized in the member initialization " + "list", + member); + + if (init == void_type_node) + init = NULL_TREE; + + /* Get an lvalue for the data member. */ + decl = build_class_member_access_expr (current_class_ref, member, + /*access_path=*/NULL_TREE, + /*preserve_reference=*/true); if (decl == error_mark_node) return; *************** perform_member_init (member, init, expli *** 273,283 **** else if (TYPE_NEEDS_CONSTRUCTING (type) || (init && TYPE_HAS_CONSTRUCTOR (type))) { - /* Since `init' is already a TREE_LIST on the member_init_list, - only build it into one if we aren't already a list. */ - if (init != NULL_TREE && TREE_CODE (init) != TREE_LIST) - init = build_tree_list (NULL_TREE, init); - if (explicit && TREE_CODE (type) == ARRAY_TYPE && init != NULL_TREE --- 353,358 ---- *************** perform_member_init (member, init, expli *** 285,291 **** && TREE_CODE (TREE_TYPE (TREE_VALUE (init))) == ARRAY_TYPE) { /* Initialization of one array from another. */ ! finish_expr_stmt (build_vec_init (decl, TREE_VALUE (init), 1)); } else finish_expr_stmt (build_aggr_init (decl, init, 0)); --- 360,367 ---- && TREE_CODE (TREE_TYPE (TREE_VALUE (init))) == ARRAY_TYPE) { /* Initialization of one array from another. */ ! finish_expr_stmt (build_vec_init (decl, NULL_TREE, TREE_VALUE (init), ! /* from_array=*/1)); } else finish_expr_stmt (build_aggr_init (decl, init, 0)); *************** perform_member_init (member, init, expli *** 296,302 **** { if (explicit) { ! init = build_default_init (type); if (TREE_CODE (type) == REFERENCE_TYPE) warning ("default-initialization of `%#D', which has reference type", --- 372,378 ---- { if (explicit) { ! init = build_default_init (type, /*nelts=*/NULL_TREE); if (TREE_CODE (type) == REFERENCE_TYPE) warning ("default-initialization of `%#D', which has reference type", *************** perform_member_init (member, init, expli *** 327,339 **** { tree expr; ! expr = build_component_ref (current_class_ref, member, NULL_TREE, ! explicit); expr = build_delete (type, expr, sfk_complete_destructor, LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0); if (expr != error_mark_node) ! finish_subobject (expr); } } --- 403,416 ---- { tree expr; ! expr = build_class_member_access_expr (current_class_ref, member, ! /*access_path=*/NULL_TREE, ! /*preserve_reference=*/false); expr = build_delete (type, expr, sfk_complete_destructor, LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0); if (expr != error_mark_node) ! finish_eh_cleanup (expr); } } *************** build_field_list (t, list, uses_unions_p *** 357,363 **** for (fields = TYPE_FIELDS (t); fields; fields = TREE_CHAIN (fields)) { /* Skip CONST_DECLs for enumeration constants and so forth. */ ! if (TREE_CODE (fields) != FIELD_DECL) continue; /* Keep track of whether or not any fields are unions. */ --- 434,440 ---- for (fields = TYPE_FIELDS (t); fields; fields = TREE_CHAIN (fields)) { /* Skip CONST_DECLs for enumeration constants and so forth. */ ! if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields)) continue; /* Keep track of whether or not any fields are unions. */ *************** build_field_list (t, list, uses_unions_p *** 384,462 **** return list; } ! /* The MEMBER_INIT_LIST is a TREE_LIST. The TREE_PURPOSE of each list ! gives a FIELD_DECL in T that needs initialization. The TREE_VALUE ! gives the initializer, or list of initializer arguments. Sort the ! MEMBER_INIT_LIST, returning a version that contains the same ! information but in the order that the fields should actually be ! initialized. Perform error-checking in the process. */ static tree ! sort_member_init (t, member_init_list) ! tree t; ! tree member_init_list; { - tree init_list; - tree last_field; tree init; int uses_unions_p; ! /* Build up a list of the various fields, in sorted order. */ ! init_list = nreverse (build_field_list (t, NULL_TREE, &uses_unions_p)); ! /* Go through the explicit initializers, adding them to the ! INIT_LIST. */ ! last_field = init_list; ! for (init = member_init_list; init; init = TREE_CHAIN (init)) { ! tree f; ! tree initialized_field; ! initialized_field = TREE_PURPOSE (init); ! my_friendly_assert (TREE_CODE (initialized_field) == FIELD_DECL, ! 20000516); ! /* If the explicit initializers are in sorted order, then the ! INITIALIZED_FIELD will be for a field following the ! LAST_FIELD. */ ! for (f = last_field; f; f = TREE_CHAIN (f)) ! if (TREE_PURPOSE (f) == initialized_field) break; ! /* Give a warning, if appropriate. */ ! if (warn_reorder && !f) { ! cp_warning_at ("member initializers for `%#D'", ! TREE_PURPOSE (last_field)); ! cp_warning_at (" and `%#D'", initialized_field); ! warning (" will be re-ordered to match declaration order"); } ! /* Look again, from the beginning of the list. We must find the ! field on this loop. */ ! if (!f) { ! f = init_list; ! while (TREE_PURPOSE (f) != initialized_field) ! f = TREE_CHAIN (f); } ! ! /* If there was already an explicit initializer for this field, ! issue an error. */ ! if (TREE_TYPE (f)) ! error ("multiple initializations given for member `%D'", ! initialized_field); ! else { ! /* Mark the field as explicitly initialized. */ ! TREE_TYPE (f) = error_mark_node; ! /* And insert the initializer. */ ! TREE_VALUE (f) = TREE_VALUE (init); } ! /* Remember the location of the last explicitly initialized ! field. */ ! last_field = f; } /* [class.base.init] --- 461,567 ---- return list; } ! /* The MEM_INITS are a TREE_LIST. The TREE_PURPOSE of each list gives ! a FIELD_DECL or BINFO in T that needs initialization. The ! TREE_VALUE gives the initializer, or list of initializer arguments. ! ! Return a TREE_LIST containing all of the initializations required ! for T, in the order in which they should be performed. The output ! list has the same format as the input. */ static tree ! sort_mem_initializers (tree t, tree mem_inits) { tree init; + tree base; + tree sorted_inits; + tree next_subobject; + int i; int uses_unions_p; ! /* Build up a list of initializations. The TREE_PURPOSE of entry ! will be the subobject (a FIELD_DECL or BINFO) to initialize. The ! TREE_VALUE will be the constructor arguments, or NULL if no ! explicit initialization was provided. */ ! sorted_inits = NULL_TREE; ! /* Process the virtual bases. */ ! for (base = CLASSTYPE_VBASECLASSES (t); base; base = TREE_CHAIN (base)) ! sorted_inits = tree_cons (TREE_VALUE (base), NULL_TREE, sorted_inits); ! /* Process the direct bases. */ ! for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); ++i) ! { ! base = BINFO_BASETYPE (TYPE_BINFO (t), i); ! if (!TREE_VIA_VIRTUAL (base)) ! sorted_inits = tree_cons (base, NULL_TREE, sorted_inits); ! } ! /* Process the non-static data members. */ ! sorted_inits = build_field_list (t, sorted_inits, &uses_unions_p); ! /* Reverse the entire list of initializations, so that they are in ! the order that they will actually be performed. */ ! sorted_inits = nreverse (sorted_inits); ! /* If the user presented the initializers in an order different from ! that in which they will actually occur, we issue a warning. Keep ! track of the next subobject which can be explicitly initialized ! without issuing a warning. */ ! next_subobject = sorted_inits; ! ! /* Go through the explicit initializers, filling in TREE_PURPOSE in ! the SORTED_INITS. */ ! for (init = mem_inits; init; init = TREE_CHAIN (init)) { ! tree subobject; ! tree subobject_init; ! subobject = TREE_PURPOSE (init); ! /* If the explicit initializers are in sorted order, then ! SUBOBJECT will be NEXT_SUBOBJECT, or something following ! it. */ ! for (subobject_init = next_subobject; ! subobject_init; ! subobject_init = TREE_CHAIN (subobject_init)) ! if (TREE_PURPOSE (subobject_init) == subobject) break; ! /* Issue a warning if the explicit initializer order does not ! match that which will actually occur. */ ! if (warn_reorder && !subobject_init) { ! if (TREE_CODE (TREE_PURPOSE (next_subobject)) == FIELD_DECL) ! cp_warning_at ("`%D' will be initialized after", ! TREE_PURPOSE (next_subobject)); ! else ! warning ("base `%T' will be initialized after", ! TREE_PURPOSE (next_subobject)); ! if (TREE_CODE (subobject) == FIELD_DECL) ! cp_warning_at (" `%#D'", subobject); ! else ! warning (" base `%T'", subobject); } ! /* Look again, from the beginning of the list. */ ! if (!subobject_init) { ! subobject_init = sorted_inits; ! while (TREE_PURPOSE (subobject_init) != subobject) ! subobject_init = TREE_CHAIN (subobject_init); } ! ! /* It is invalid to initialize the same subobject more than ! once. */ ! if (TREE_VALUE (subobject_init)) { ! if (TREE_CODE (subobject) == FIELD_DECL) ! error ("multiple initializations given for `%D'", subobject); ! else ! error ("multiple initializations given for base `%T'", ! subobject); } ! /* Record the initialization. */ ! TREE_VALUE (subobject_init) = TREE_VALUE (init); ! next_subobject = subobject_init; } /* [class.base.init] *************** sort_member_init (t, member_init_list) *** 466,480 **** anonymous unions), the ctor-initializer is ill-formed. */ if (uses_unions_p) { ! last_field = NULL_TREE; ! for (init = init_list; init; init = TREE_CHAIN (init)) { tree field; tree field_type; int done; ! /* Skip uninitialized members. */ ! if (!TREE_TYPE (init)) continue; /* See if this field is a member of a union, or a member of a structure contained in a union, etc. */ --- 571,586 ---- anonymous unions), the ctor-initializer is ill-formed. */ if (uses_unions_p) { ! tree last_field = NULL_TREE; ! for (init = sorted_inits; init; init = TREE_CHAIN (init)) { tree field; tree field_type; int done; ! /* Skip uninitialized members and base classes. */ ! if (!TREE_VALUE (init) ! || TREE_CODE (TREE_PURPOSE (init)) != FIELD_DECL) continue; /* See if this field is a member of a union, or a member of a structure contained in a union, etc. */ *************** sort_member_init (t, member_init_list) *** 541,771 **** } } ! return init_list; ! } ! ! /* Like sort_member_init, but used for initializers of base classes. ! *RBASE_PTR is filled in with the initializers for non-virtual bases; ! vbase_ptr gets the virtual bases. */ ! ! static void ! sort_base_init (t, base_init_list, rbase_ptr, vbase_ptr) ! tree t; ! tree base_init_list; ! tree *rbase_ptr, *vbase_ptr; ! { ! tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); ! int n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; ! ! int i; ! tree x; ! tree last; ! ! /* For warn_reorder. */ ! int last_pos = 0; ! tree last_base = NULL_TREE; ! ! tree rbases = NULL_TREE; ! tree vbases = NULL_TREE; ! ! /* First walk through and splice out vbase and invalid initializers. ! Also replace types with binfos. */ ! ! last = tree_cons (NULL_TREE, NULL_TREE, base_init_list); ! for (x = TREE_CHAIN (last); x; x = TREE_CHAIN (x)) ! { ! tree basetype = TREE_PURPOSE (x); ! tree binfo = (TREE_CODE (basetype) == TREE_VEC ! ? basetype : binfo_or_else (basetype, t)); ! ! if (binfo == NULL_TREE) ! /* BASETYPE might be an inaccessible direct base (because it ! is also an indirect base). */ ! continue; ! ! if (TREE_VIA_VIRTUAL (binfo)) ! { ! /* Virtual base classes are special cases. Their ! initializers are recorded with this constructor, and they ! are used when this constructor is the top-level ! constructor called. */ ! tree v = binfo_for_vbase (BINFO_TYPE (binfo), t); ! vbases = tree_cons (v, TREE_VALUE (x), vbases); ! } ! else ! { ! /* Otherwise, it must be an immediate base class. */ ! my_friendly_assert ! (same_type_p (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)), ! t), 20011113); ! ! TREE_PURPOSE (x) = binfo; ! TREE_CHAIN (last) = x; ! last = x; ! } ! } ! TREE_CHAIN (last) = NULL_TREE; ! ! /* Now walk through our regular bases and make sure they're initialized. */ ! ! for (i = 0; i < n_baseclasses; ++i) ! { ! /* The base for which we're currently initializing. */ ! tree base_binfo = TREE_VEC_ELT (binfos, i); ! /* The initializer for BASE_BINFO. */ ! tree init; ! int pos; ! ! if (TREE_VIA_VIRTUAL (base_binfo)) ! continue; ! ! /* We haven't found the BASE_BINFO yet. */ ! init = NULL_TREE; ! /* Loop through all the explicitly initialized bases, looking ! for an appropriate initializer. */ ! for (x = base_init_list, pos = 0; x; x = TREE_CHAIN (x), ++pos) ! { ! tree binfo = TREE_PURPOSE (x); ! ! if (binfo == base_binfo && !init) ! { ! if (warn_reorder) ! { ! if (pos < last_pos) ! { ! cp_warning_at ("base initializers for `%#T'", last_base); ! cp_warning_at (" and `%#T'", BINFO_TYPE (binfo)); ! warning (" will be re-ordered to match inheritance order"); ! } ! last_pos = pos; ! last_base = BINFO_TYPE (binfo); ! } ! ! /* Make sure we won't try to work on this init again. */ ! TREE_PURPOSE (x) = NULL_TREE; ! init = build_tree_list (binfo, TREE_VALUE (x)); ! } ! else if (binfo == base_binfo) ! { ! error ("base class `%T' already initialized", ! BINFO_TYPE (binfo)); ! break; ! } ! } ! ! /* If we didn't find BASE_BINFO in the list, create a dummy entry ! so the two lists (RBASES and the list of bases) will be ! symmetrical. */ ! if (!init) ! init = build_tree_list (NULL_TREE, NULL_TREE); ! rbases = chainon (rbases, init); ! } ! ! *rbase_ptr = rbases; ! *vbase_ptr = vbases; } ! /* Perform whatever initializations have yet to be done on the base ! class, and non-static data members, of the CURRENT_CLASS_TYPE. ! These actions are given by the BASE_INIT_LIST and MEM_INIT_LIST, ! respectively. ! ! If there is a need for a call to a constructor, we must surround ! that call with a pushlevel/poplevel pair, since we are technically ! at the PARM level of scope. */ void ! emit_base_init (mem_init_list, base_init_list) ! tree mem_init_list; ! tree base_init_list; { ! tree member; ! tree rbase_init_list, vbase_init_list; ! tree t = current_class_type; ! tree t_binfo = TYPE_BINFO (t); ! tree binfos = BINFO_BASETYPES (t_binfo); ! int i; ! int n_baseclasses = BINFO_N_BASETYPES (t_binfo); ! ! mem_init_list = sort_member_init (t, mem_init_list); ! sort_base_init (t, base_init_list, &rbase_init_list, &vbase_init_list); ! ! /* First, initialize the virtual base classes, if we are ! constructing the most-derived object. */ ! if (TYPE_USES_VIRTUAL_BASECLASSES (t)) ! { ! tree first_arg = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)); ! construct_virtual_bases (t, current_class_ref, current_class_ptr, ! vbase_init_list, first_arg); ! } ! /* Now, perform initialization of non-virtual base classes. */ ! for (i = 0; i < n_baseclasses; i++) { ! tree base_binfo = TREE_VEC_ELT (binfos, i); ! tree init = void_list_node; ! ! if (TREE_VIA_VIRTUAL (base_binfo)) ! continue; ! my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == t_binfo, ! 999); ! if (TREE_PURPOSE (rbase_init_list)) ! init = TREE_VALUE (rbase_init_list); ! else if (TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (base_binfo))) ! { ! init = NULL_TREE; ! if (extra_warnings ! && DECL_COPY_CONSTRUCTOR_P (current_function_decl)) ! warning ("base class `%#T' should be explicitly initialized in the copy constructor", ! BINFO_TYPE (base_binfo)); ! } ! if (init != void_list_node) { ! member = build_base_path (PLUS_EXPR, current_class_ptr, ! base_binfo, 1); ! expand_aggr_init_1 (base_binfo, NULL_TREE, ! build_indirect_ref (member, NULL), init, LOOKUP_NORMAL); } ! expand_cleanup_for_base (base_binfo, NULL_TREE); ! rbase_init_list = TREE_CHAIN (rbase_init_list); } ! /* Initialize the vtable pointers for the class. */ initialize_vtbl_ptrs (current_class_ptr); ! ! while (mem_init_list) { ! tree init; ! tree member; ! int from_init_list; ! ! member = TREE_PURPOSE (mem_init_list); ! ! /* See if we had a user-specified member initialization. */ ! if (TREE_TYPE (mem_init_list)) ! { ! init = TREE_VALUE (mem_init_list); ! from_init_list = 1; ! } ! else ! { ! init = DECL_INITIAL (member); ! from_init_list = 0; ! ! /* Effective C++ rule 12. */ ! if (warn_ecpp && init == NULL_TREE ! && !DECL_ARTIFICIAL (member) ! && TREE_CODE (TREE_TYPE (member)) != ARRAY_TYPE) ! warning ("`%D' should be initialized in the member initialization list", member); ! } ! ! perform_member_init (member, init, from_init_list); ! mem_init_list = TREE_CHAIN (mem_init_list); } } --- 647,722 ---- } } ! return sorted_inits; } ! /* Initialize all bases and members of CURRENT_CLASS_TYPE. MEM_INITS ! is a TREE_LIST giving the explicit mem-initializer-list for the ! constructor. The TREE_PURPOSE of each entry is a subobject (a ! FIELD_DECL or a BINFO) of the CURRENT_CLASS_TYPE. The TREE_VALUE ! is a TREE_LIST giving the arguments to the constructor or ! void_type_node for an empty list of arguments. */ void ! emit_mem_initializers (tree mem_inits) { ! /* Sort the mem-initializers into the order in which the ! initializations should be performed. */ ! mem_inits = sort_mem_initializers (current_class_type, mem_inits); ! in_base_initializer = 1; ! ! /* Initialize base classes. */ ! while (mem_inits ! && TREE_CODE (TREE_PURPOSE (mem_inits)) != FIELD_DECL) { ! tree subobject = TREE_PURPOSE (mem_inits); ! tree arguments = TREE_VALUE (mem_inits); ! /* If these initializations are taking place in a copy ! constructor, the base class should probably be explicitly ! initialized. */ ! if (extra_warnings && !arguments ! && DECL_COPY_CONSTRUCTOR_P (current_function_decl) ! && TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (subobject))) ! warning ("base class `%#T' should be explicitly initialized in the " ! "copy constructor", ! BINFO_TYPE (subobject)); ! /* If an explicit -- but empty -- initializer list was present, ! treat it just like default initialization at this point. */ ! if (arguments == void_type_node) ! arguments = NULL_TREE; ! /* Initialize the base. */ ! if (TREE_VIA_VIRTUAL (subobject)) ! construct_virtual_base (subobject, arguments); ! else { ! tree base_addr; ! ! base_addr = build_base_path (PLUS_EXPR, current_class_ptr, ! subobject, 1); ! expand_aggr_init_1 (subobject, NULL_TREE, ! build_indirect_ref (base_addr, NULL), ! arguments, LOOKUP_NORMAL); + expand_cleanup_for_base (subobject, NULL_TREE); } ! mem_inits = TREE_CHAIN (mem_inits); } + in_base_initializer = 0; ! /* Initialize the vptrs. */ initialize_vtbl_ptrs (current_class_ptr); ! ! /* Initialize the data members. */ ! while (mem_inits) { ! perform_member_init (TREE_PURPOSE (mem_inits), ! TREE_VALUE (mem_inits)); ! mem_inits = TREE_CHAIN (mem_inits); } } *************** expand_virtual_init (binfo, decl) *** 862,868 **** /* If an exception is thrown in a constructor, those base classes already constructed must be destroyed. This function creates the cleanup for BINFO, which has just been constructed. If FLAG is non-NULL, ! it is a DECL which is non-zero when this base needs to be destroyed. */ static void --- 813,819 ---- /* If an exception is thrown in a constructor, those base classes already constructed must be destroyed. This function creates the cleanup for BINFO, which has just been constructed. If FLAG is non-NULL, ! it is a DECL which is nonzero when this base needs to be destroyed. */ static void *************** expand_cleanup_for_base (binfo, flag) *** 876,974 **** return; /* Call the destructor. */ ! expr = (build_scoped_method_call ! (current_class_ref, binfo, base_dtor_identifier, NULL_TREE)); if (flag) expr = fold (build (COND_EXPR, void_type_node, ! truthvalue_conversion (flag), expr, integer_zero_node)); ! finish_subobject (expr); ! } ! ! /* Subroutine of `expand_aggr_vbase_init'. ! BINFO is the binfo of the type that is being initialized. ! INIT_LIST is the list of initializers for the virtual baseclass. */ ! ! static void ! expand_aggr_vbase_init_1 (binfo, exp, addr, init_list) ! tree binfo, exp, addr, init_list; ! { ! tree init = purpose_member (binfo, init_list); ! tree ref = build_indirect_ref (addr, NULL); ! ! if (init) ! init = TREE_VALUE (init); ! /* Call constructors, but don't set up vtables. */ ! expand_aggr_init_1 (binfo, exp, ref, init, LOOKUP_COMPLAIN); } ! /* Construct the virtual base-classes of THIS_REF (whose address is ! THIS_PTR). The object has the indicated TYPE. The construction ! actually takes place only if FLAG is non-zero. INIT_LIST is list ! of initializations for constructors to perform. */ static void ! construct_virtual_bases (type, this_ref, this_ptr, init_list, flag) ! tree type; ! tree this_ref; ! tree this_ptr; ! tree init_list; ! tree flag; { ! tree vbases; ! ! /* If there are no virtual baseclasses, we shouldn't even be here. */ ! my_friendly_assert (TYPE_USES_VIRTUAL_BASECLASSES (type), 19990621); ! /* Now, run through the baseclasses, initializing each. */ ! for (vbases = CLASSTYPE_VBASECLASSES (type); vbases; ! vbases = TREE_CHAIN (vbases)) ! { ! tree inner_if_stmt; ! tree compound_stmt; ! tree exp; ! tree vbase; ! /* If there are virtual base classes with destructors, we need to ! emit cleanups to destroy them if an exception is thrown during ! the construction process. These exception regions (i.e., the ! period during which the cleanups must occur) begin from the time ! the construction is complete to the end of the function. If we ! create a conditional block in which to initialize the ! base-classes, then the cleanup region for the virtual base begins ! inside a block, and ends outside of that block. This situation ! confuses the sjlj exception-handling code. Therefore, we do not ! create a single conditional block, but one for each ! initialization. (That way the cleanup regions always begin ! in the outer block.) We trust the back-end to figure out ! that the FLAG will not change across initializations, and ! avoid doing multiple tests. */ ! inner_if_stmt = begin_if_stmt (); ! finish_if_stmt_cond (flag, inner_if_stmt); ! compound_stmt = begin_compound_stmt (/*has_no_scope=*/1); ! /* Compute the location of the virtual base. If we're ! constructing virtual bases, then we must be the most derived ! class. Therefore, we don't have to look up the virtual base; ! we already know where it is. */ ! vbase = TREE_VALUE (vbases); ! exp = build (PLUS_EXPR, ! TREE_TYPE (this_ptr), ! this_ptr, ! fold (build1 (NOP_EXPR, TREE_TYPE (this_ptr), ! BINFO_OFFSET (vbase)))); ! exp = build1 (NOP_EXPR, ! build_pointer_type (BINFO_TYPE (vbase)), ! exp); ! expand_aggr_vbase_init_1 (vbase, this_ref, exp, init_list); ! finish_compound_stmt (/*has_no_scope=*/1, compound_stmt); ! finish_then_clause (inner_if_stmt); ! finish_if_stmt (); ! ! expand_cleanup_for_base (vbase, flag); ! } } /* Find the context in which this FIELD can be initialized. */ --- 827,896 ---- return; /* Call the destructor. */ ! expr = build_special_member_call (current_class_ref, ! base_dtor_identifier, ! NULL_TREE, ! binfo, ! LOOKUP_NORMAL | LOOKUP_NONVIRTUAL); if (flag) expr = fold (build (COND_EXPR, void_type_node, ! c_common_truthvalue_conversion (flag), expr, integer_zero_node)); ! finish_eh_cleanup (expr); } ! /* Construct the virtual base-class VBASE passing the ARGUMENTS to its ! constructor. */ static void ! construct_virtual_base (tree vbase, tree arguments) { ! tree inner_if_stmt; ! tree compound_stmt; ! tree exp; ! tree flag; ! /* If there are virtual base classes with destructors, we need to ! emit cleanups to destroy them if an exception is thrown during ! the construction process. These exception regions (i.e., the ! period during which the cleanups must occur) begin from the time ! the construction is complete to the end of the function. If we ! create a conditional block in which to initialize the ! base-classes, then the cleanup region for the virtual base begins ! inside a block, and ends outside of that block. This situation ! confuses the sjlj exception-handling code. Therefore, we do not ! create a single conditional block, but one for each ! initialization. (That way the cleanup regions always begin ! in the outer block.) We trust the back-end to figure out ! that the FLAG will not change across initializations, and ! avoid doing multiple tests. */ ! flag = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)); ! inner_if_stmt = begin_if_stmt (); ! finish_if_stmt_cond (flag, inner_if_stmt); ! compound_stmt = begin_compound_stmt (/*has_no_scope=*/1); ! /* Compute the location of the virtual base. If we're ! constructing virtual bases, then we must be the most derived ! class. Therefore, we don't have to look up the virtual base; ! we already know where it is. */ ! exp = build (PLUS_EXPR, ! TREE_TYPE (current_class_ptr), ! current_class_ptr, ! fold (build1 (NOP_EXPR, TREE_TYPE (current_class_ptr), ! BINFO_OFFSET (vbase)))); ! exp = build1 (NOP_EXPR, ! build_pointer_type (BINFO_TYPE (vbase)), ! exp); ! exp = build1 (INDIRECT_REF, BINFO_TYPE (vbase), exp); ! expand_aggr_init_1 (vbase, current_class_ref, exp, ! arguments, LOOKUP_COMPLAIN); ! finish_compound_stmt (/*has_no_scope=*/1, compound_stmt); ! finish_then_clause (inner_if_stmt); ! finish_if_stmt (); ! expand_cleanup_for_base (vbase, flag); } /* Find the context in which this FIELD can be initialized. */ *************** member_init_ok_or_else (field, type, mem *** 1017,1062 **** return 1; } ! /* EXP is an expression of aggregate type. NAME is an IDENTIFIER_NODE ! which names a field, or it is a _TYPE node or TYPE_DECL which names ! a base for that type. INIT is a parameter list for that field's or ! base's constructor. Check the validity of NAME, and return a ! TREE_LIST of the base _TYPE or FIELD_DECL and the INIT. EXP is used ! only to get its type. If NAME is invalid, return NULL_TREE and ! issue a diagnostic. An old style unnamed direct single base construction is permitted, where NAME is NULL. */ tree ! expand_member_init (exp, name, init) ! tree exp, name, init; { ! tree basetype = NULL_TREE, field; ! tree type; ! if (exp == NULL_TREE) return NULL_TREE; - type = TYPE_MAIN_VARIANT (TREE_TYPE (exp)); - my_friendly_assert (IS_AGGR_TYPE (type), 20011113); - if (!name) { /* This is an obsolete unnamed base class initializer. The parser will already have warned about its use. */ ! switch (CLASSTYPE_N_BASECLASSES (type)) { case 0: error ("unnamed initializer for `%T', which has no base classes", ! type); return NULL_TREE; case 1: ! basetype = TYPE_BINFO_BASETYPE (type, 0); break; default: error ("unnamed initializer for `%T', which uses multiple inheritance", ! type); return NULL_TREE; } } --- 939,978 ---- return 1; } ! /* NAME is a FIELD_DECL, an IDENTIFIER_NODE which names a field, or it ! is a _TYPE node or TYPE_DECL which names a base for that type. ! Check the validity of NAME, and return either the base _TYPE, base ! binfo, or the FIELD_DECL of the member. If NAME is invalid, return ! NULL_TREE and issue a diagnostic. An old style unnamed direct single base construction is permitted, where NAME is NULL. */ tree ! expand_member_init (tree name) { ! tree basetype; ! tree field; ! if (!current_class_ref) return NULL_TREE; if (!name) { /* This is an obsolete unnamed base class initializer. The parser will already have warned about its use. */ ! switch (CLASSTYPE_N_BASECLASSES (current_class_type)) { case 0: error ("unnamed initializer for `%T', which has no base classes", ! current_class_type); return NULL_TREE; case 1: ! basetype = TYPE_BINFO_BASETYPE (current_class_type, 0); break; default: error ("unnamed initializer for `%T', which uses multiple inheritance", ! current_class_type); return NULL_TREE; } } *************** expand_member_init (exp, name, init) *** 1067,1113 **** } else if (TREE_CODE (name) == TYPE_DECL) basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name)); ! ! my_friendly_assert (init != NULL_TREE, 0); ! ! if (init == void_type_node) ! init = NULL_TREE; if (basetype) { if (current_template_parms) ! ; ! else if (vec_binfo_member (basetype, TYPE_BINFO_BASETYPES (type))) ! /* A direct base. */; ! else if (binfo_for_vbase (basetype, type)) ! /* A virtual base. */; ! else { ! if (TYPE_USES_VIRTUAL_BASECLASSES (type)) error ("type `%D' is not a direct or virtual base of `%T'", ! name, type); else error ("type `%D' is not a direct base of `%T'", ! name, type); return NULL_TREE; } ! init = build_tree_list (basetype, init); } else { if (TREE_CODE (name) == IDENTIFIER_NODE) ! field = lookup_field (type, name, 1, 0); else field = name; ! if (! member_init_ok_or_else (field, type, name)) ! return NULL_TREE; ! ! init = build_tree_list (field, init); } ! return init; } /* This is like `expand_member_init', only it stores one aggregate --- 983,1034 ---- } else if (TREE_CODE (name) == TYPE_DECL) basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name)); ! else ! basetype = NULL_TREE; if (basetype) { + tree binfo; + if (current_template_parms) ! return basetype; ! ! binfo = lookup_base (current_class_type, basetype, ! ba_ignore, NULL); ! if (binfo) { ! if (TREE_VIA_VIRTUAL (binfo)) ! binfo = binfo_for_vbase (basetype, current_class_type); ! else if (BINFO_INHERITANCE_CHAIN (binfo) ! != TYPE_BINFO (current_class_type)) ! binfo = NULL_TREE; ! } ! if (!binfo) ! { ! if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) error ("type `%D' is not a direct or virtual base of `%T'", ! name, current_class_type); else error ("type `%D' is not a direct base of `%T'", ! name, current_class_type); return NULL_TREE; } ! if (binfo) ! return binfo; } else { if (TREE_CODE (name) == IDENTIFIER_NODE) ! field = lookup_field (current_class_type, name, 1, 0); else field = name; ! if (member_init_ok_or_else (field, current_class_type, name)) ! return field; } ! return NULL_TREE; } /* This is like `expand_member_init', only it stores one aggregate *************** expand_member_init (exp, name, init) *** 1131,1138 **** The virtual function table pointer cannot be set up here, because we do not really know its type. - Virtual baseclass pointers are also set up here. - This never calls operator=(). When initializing, nothing is CONST. --- 1052,1057 ---- *************** build_aggr_init (exp, init, flags) *** 1191,1197 **** TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type); if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED) TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype); ! stmt_expr = build_vec_init (exp, init, init && same_type_p (TREE_TYPE (init), TREE_TYPE (exp))); TREE_READONLY (exp) = was_const; --- 1110,1116 ---- TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type); if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED) TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype); ! stmt_expr = build_vec_init (exp, NULL_TREE, init, init && same_type_p (TREE_TYPE (init), TREE_TYPE (exp))); TREE_READONLY (exp) = was_const; *************** build_aggr_init (exp, init, flags) *** 1221,1226 **** --- 1140,1163 ---- return stmt_expr; } + /* Like build_aggr_init, but not just for aggregates. */ + + tree + build_init (decl, init, flags) + tree decl, init; + int flags; + { + tree expr; + + if (IS_AGGR_TYPE (TREE_TYPE (decl)) + || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) + expr = build_aggr_init (decl, init, flags); + else + expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init); + + return expr; + } + static void expand_default_init (binfo, true_exp, exp, init, flags) tree binfo; *************** expand_default_init (binfo, true_exp, ex *** 1253,1262 **** to run a new constructor; and catching an exception, where we have already built up the constructor call so we could wrap it in an exception region. */; ! else if (TREE_CODE (init) == CONSTRUCTOR) ! /* A brace-enclosed initializer has whatever type is ! required. There's no need to convert it. */ ! ; else init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); --- 1190,1202 ---- to run a new constructor; and catching an exception, where we have already built up the constructor call so we could wrap it in an exception region. */; ! else if (TREE_CODE (init) == CONSTRUCTOR ! && TREE_HAS_CONSTRUCTOR (init)) ! { ! /* A brace-enclosed initializer for an aggregate. */ ! my_friendly_assert (CP_AGGREGATE_TYPE_P (type), 20021016); ! init = digest_init (type, init, (tree *)NULL); ! } else init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); *************** expand_default_init (binfo, true_exp, ex *** 1289,1295 **** else ctor_name = base_ctor_identifier; ! rval = build_method_call (exp, ctor_name, parms, binfo, flags); if (TREE_SIDE_EFFECTS (rval)) { if (building_stmt_tree ()) --- 1229,1235 ---- else ctor_name = base_ctor_identifier; ! rval = build_special_member_call (exp, ctor_name, parms, binfo, flags); if (TREE_SIDE_EFFECTS (rval)) { if (building_stmt_tree ()) *************** expand_aggr_init_1 (binfo, true_exp, exp *** 1329,1334 **** --- 1269,1275 ---- tree type = TREE_TYPE (exp); my_friendly_assert (init != error_mark_node && type != error_mark_node, 211); + my_friendly_assert (building_stmt_tree (), 20021010); /* Use a function returning the desired type to initialize EXP for us. If the function is a constructor, and its first argument is *************** expand_aggr_init_1 (binfo, true_exp, exp *** 1343,1354 **** /* If store_init_value returns NULL_TREE, the INIT has been record in the DECL_INITIAL for EXP. That means there's nothing more we have to do. */ ! if (!store_init_value (exp, init)) ! { ! if (!building_stmt_tree ()) ! expand_decl_init (exp); ! } ! else finish_expr_stmt (build (INIT_EXPR, type, exp, init)); return; } --- 1284,1290 ---- /* If store_init_value returns NULL_TREE, the INIT has been record in the DECL_INITIAL for EXP. That means there's nothing more we have to do. */ ! if (store_init_value (exp, init)) finish_expr_stmt (build (INIT_EXPR, type, exp, init)); return; } *************** build_member_call (type, name, parmlist) *** 1438,1443 **** --- 1374,1380 ---- { tree t; tree method_name; + tree fns; int dtor = 0; tree basetype_path, decl; *************** build_member_call (type, name, parmlist) *** 1458,1472 **** TREE_OPERAND (name, 0) = method_name; } my_friendly_assert (is_overloaded_fn (method_name), 980519); ! return build_x_function_call (name, parmlist, current_class_ref); } if (DECL_P (name)) name = DECL_NAME (name); if (TREE_CODE (type) == NAMESPACE_DECL) ! return build_x_function_call (lookup_namespace_name (type, name), ! parmlist, current_class_ref); if (TREE_CODE (name) == TEMPLATE_ID_EXPR) { --- 1395,1410 ---- TREE_OPERAND (name, 0) = method_name; } my_friendly_assert (is_overloaded_fn (method_name), 980519); ! return finish_call_expr (name, parmlist, /*disallow_virtual=*/true); } if (DECL_P (name)) name = DECL_NAME (name); if (TREE_CODE (type) == NAMESPACE_DECL) ! return finish_call_expr (lookup_namespace_name (type, name), ! parmlist, ! /*disallow_virtual=*/true); if (TREE_CODE (name) == TEMPLATE_ID_EXPR) { *************** build_member_call (type, name, parmlist) *** 1493,1502 **** { tree ns = lookup_name (type, 0); if (ns && TREE_CODE (ns) == NAMESPACE_DECL) ! { ! return build_x_function_call (build_offset_ref (type, name), ! parmlist, current_class_ref); ! } } if (type == NULL_TREE || ! is_aggr_type (type, 1)) --- 1431,1439 ---- { tree ns = lookup_name (type, 0); if (ns && TREE_CODE (ns) == NAMESPACE_DECL) ! return finish_call_expr (lookup_namespace_name (ns, name), ! parmlist, ! /*disallow_virtual=*/true); } if (type == NULL_TREE || ! is_aggr_type (type, 1)) *************** build_member_call (type, name, parmlist) *** 1515,1544 **** decl = maybe_dummy_object (type, &basetype_path); /* Convert 'this' to the specified type to disambiguate conversion to the function's context. */ if (decl == current_class_ref && ACCESSIBLY_UNIQUELY_DERIVED_P (type, current_class_type)) { ! tree olddecl = current_class_ptr; ! tree oldtype = TREE_TYPE (TREE_TYPE (olddecl)); ! if (oldtype != type) ! { ! tree newtype = build_qualified_type (type, TYPE_QUALS (oldtype)); ! decl = convert_force (build_pointer_type (newtype), olddecl, 0); ! decl = build_indirect_ref (decl, NULL); ! } } ! if (method_name == constructor_name (type) ! || method_name == constructor_name_full (type)) return build_functional_cast (type, parmlist); - if (lookup_fnfields (basetype_path, method_name, 0)) - return build_method_call (decl, - TREE_CODE (name) == TEMPLATE_ID_EXPR - ? name : method_name, - parmlist, basetype_path, - LOOKUP_NORMAL|LOOKUP_NONVIRTUAL); if (TREE_CODE (name) == IDENTIFIER_NODE && ((t = lookup_field (TYPE_BINFO (type), name, 1, 0)))) { --- 1452,1485 ---- decl = maybe_dummy_object (type, &basetype_path); + fns = lookup_fnfields (basetype_path, method_name, 0); + if (fns) + { + if (TREE_CODE (name) == TEMPLATE_ID_EXPR) + BASELINK_FUNCTIONS (fns) = build_nt (TEMPLATE_ID_EXPR, + BASELINK_FUNCTIONS (fns), + TREE_OPERAND (name, 1)); + return build_new_method_call (decl, fns, parmlist, + /*conversion_path=*/NULL_TREE, + LOOKUP_NORMAL|LOOKUP_NONVIRTUAL); + } + /* Convert 'this' to the specified type to disambiguate conversion to the function's context. */ if (decl == current_class_ref + /* ??? this is wrong, but if this conversion is invalid we need to + defer it until we know whether we are calling a static or + non-static member function. Be conservative for now. */ && ACCESSIBLY_UNIQUELY_DERIVED_P (type, current_class_type)) { ! basetype_path = NULL_TREE; ! decl = build_scoped_ref (decl, type, &basetype_path); ! if (decl == error_mark_node) ! return error_mark_node; } ! if (constructor_name_p (method_name, type)) return build_functional_cast (type, parmlist); if (TREE_CODE (name) == IDENTIFIER_NODE && ((t = lookup_field (TYPE_BINFO (type), name, 1, 0)))) { *************** build_offset_ref (type, name) *** 1667,1683 **** decl = maybe_dummy_object (type, &basebinfo); ! member = lookup_member (basebinfo, name, 1, 0); ! ! if (member == error_mark_node) ! return error_mark_node; /* A lot of this logic is now handled in lookup_member. */ if (member && BASELINK_P (member)) { /* Go from the TREE_BASELINK to the member function info. */ tree fnfields = member; ! t = TREE_VALUE (fnfields); if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR) { --- 1608,1629 ---- decl = maybe_dummy_object (type, &basebinfo); ! if (BASELINK_P (name) || DECL_P (name)) ! member = name; ! else ! { ! member = lookup_member (basebinfo, name, 1, 0); ! ! if (member == error_mark_node) ! return error_mark_node; ! } /* A lot of this logic is now handled in lookup_member. */ if (member && BASELINK_P (member)) { /* Go from the TREE_BASELINK to the member function info. */ tree fnfields = member; ! t = BASELINK_FUNCTIONS (fnfields); if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR) { *************** build_offset_ref (type, name) *** 1702,1708 **** return t; } ! if (!really_overloaded_fn (t)) { /* Get rid of a potential OVERLOAD around it */ t = OVL_CURRENT (t); --- 1648,1654 ---- return t; } ! if (TREE_CODE (t) != TEMPLATE_ID_EXPR && !really_overloaded_fn (t)) { /* Get rid of a potential OVERLOAD around it */ t = OVL_CURRENT (t); *************** build_offset_ref (type, name) *** 1748,1754 **** if (TREE_CODE (t) == FIELD_DECL && DECL_C_BIT_FIELD (t)) { ! error ("illegal pointer to bit-field `%D'", t); return error_mark_node; } --- 1694,1700 ---- if (TREE_CODE (t) == FIELD_DECL && DECL_C_BIT_FIELD (t)) { ! error ("invalid pointer to bit-field `%D'", t); return error_mark_node; } *************** resolve_offset_ref (exp) *** 1814,1820 **** || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE) { /* These were static members. */ ! if (mark_addressable (member) == 0) return error_mark_node; return member; } --- 1760,1766 ---- || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE) { /* These were static members. */ ! if (!cxx_mark_addressable (member)) return error_mark_node; return member; } *************** resolve_offset_ref (exp) *** 1837,1843 **** if (TREE_CODE (member) == FIELD_DECL && (base == current_class_ref || is_dummy_object (base))) { ! tree binfo = TYPE_BINFO (current_class_type); /* Try to get to basetype from 'this'; if that doesn't work, nothing will. */ --- 1783,1789 ---- if (TREE_CODE (member) == FIELD_DECL && (base == current_class_ref || is_dummy_object (base))) { ! tree binfo = NULL_TREE; /* Try to get to basetype from 'this'; if that doesn't work, nothing will. */ *************** resolve_offset_ref (exp) *** 1845,1859 **** /* First convert to the intermediate base specified, if appropriate. */ if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE) ! { ! binfo = binfo_or_else (TYPE_OFFSET_BASETYPE (type), ! current_class_type); ! if (!binfo) ! return error_mark_node; ! base = build_base_path (PLUS_EXPR, base, binfo, 1); ! } ! return build_component_ref (base, member, binfo, 1); } /* Ensure that we have an object. */ --- 1791,1801 ---- /* First convert to the intermediate base specified, if appropriate. */ if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE) ! base = build_scoped_ref (base, TYPE_OFFSET_BASETYPE (type), &binfo); ! return build_class_member_access_expr (base, member, ! /*access_path=*/NULL_TREE, ! /*preserve_reference=*/false); } /* Ensure that we have an object. */ *************** build_new (placement, decl, init, use_gl *** 2122,2128 **** return rval; } ! /* Given a Java class, return a decl for the corresponding java.lang.Class. */ tree build_java_class_ref (type) --- 2064,2070 ---- return rval; } ! /* Given a Java class, return a decl for the corresponding java.lang.Class. */ tree build_java_class_ref (type) *************** build_new_1 (exp) *** 2205,2210 **** --- 2147,2153 ---- tree placement, init; tree type, true_type, size, rval, t; tree full_type; + tree outer_nelts = NULL_TREE; tree nelts = NULL_TREE; tree alloc_call, alloc_expr, alloc_node; tree alloc_fn; *************** build_new_1 (exp) *** 2234,2245 **** if (TREE_CODE (type) == ARRAY_REF) { has_array = 1; ! nelts = TREE_OPERAND (type, 1); type = TREE_OPERAND (type, 0); ! full_type = cp_build_binary_op (MINUS_EXPR, nelts, integer_one_node); ! full_type = build_index_type (full_type); ! full_type = build_cplus_array_type (type, full_type); } else full_type = type; --- 2177,2187 ---- if (TREE_CODE (type) == ARRAY_REF) { has_array = 1; ! nelts = outer_nelts = TREE_OPERAND (type, 1); type = TREE_OPERAND (type, 0); ! /* Use an incomplete array type to avoid VLA headaches. */ ! full_type = build_cplus_array_type (type, NULL_TREE); } else full_type = type; *************** build_new_1 (exp) *** 2341,2347 **** args)); else alloc_call = build_method_call (build_dummy_object (true_type), ! fnname, args, NULL_TREE, LOOKUP_NORMAL); } --- 2283,2290 ---- args)); else alloc_call = build_method_call (build_dummy_object (true_type), ! fnname, args, ! TYPE_BINFO (true_type), LOOKUP_NORMAL); } *************** build_new_1 (exp) *** 2423,2439 **** init_expr = build_indirect_ref (alloc_node, NULL); if (init == void_zero_node) ! init = build_default_init (full_type); else if (init && pedantic && has_array) pedwarn ("ISO C++ forbids initialization in array new"); if (has_array) ! init_expr = build_vec_init (init_expr, init, 0); else if (TYPE_NEEDS_CONSTRUCTING (type)) ! init_expr = build_method_call (init_expr, ! complete_ctor_identifier, ! init, TYPE_BINFO (true_type), ! LOOKUP_NORMAL); else { /* We are processing something like `new int (10)', which --- 2366,2386 ---- init_expr = build_indirect_ref (alloc_node, NULL); if (init == void_zero_node) ! init = build_default_init (full_type, nelts); else if (init && pedantic && has_array) pedwarn ("ISO C++ forbids initialization in array new"); if (has_array) ! init_expr ! = build_vec_init (init_expr, ! cp_build_binary_op (MINUS_EXPR, outer_nelts, ! integer_one_node), ! init, /*from_array=*/0); else if (TYPE_NEEDS_CONSTRUCTING (type)) ! init_expr = build_special_member_call (init_expr, ! complete_ctor_identifier, ! init, TYPE_BINFO (true_type), ! LOOKUP_NORMAL); else { /* We are processing something like `new int (10)', which *************** build_new_1 (exp) *** 2509,2524 **** constructor, that would fix the nesting problem and we could do away with this complexity. But that would complicate other things; in particular, it would make it difficult to bail out ! if the allocation function returns null. */ if (cleanup) { tree end, sentry, begin; begin = get_target_expr (boolean_true_node); ! sentry = TREE_OPERAND (begin, 0); ! TREE_OPERAND (begin, 2) = build (COND_EXPR, void_type_node, sentry, cleanup, void_zero_node); --- 2456,2475 ---- constructor, that would fix the nesting problem and we could do away with this complexity. But that would complicate other things; in particular, it would make it difficult to bail out ! if the allocation function returns null. Er, no, it wouldn't; ! we just don't run the constructor. The standard says it's ! unspecified whether or not the args are evaluated. */ if (cleanup) { tree end, sentry, begin; begin = get_target_expr (boolean_true_node); ! CLEANUP_EH_ONLY (begin) = 1; ! sentry = TARGET_EXPR_SLOT (begin); ! ! TARGET_EXPR_CLEANUP (begin) = build (COND_EXPR, void_type_node, sentry, cleanup, void_zero_node); *************** build_new_1 (exp) *** 2552,2559 **** { if (check_new) { ! tree ifexp = cp_build_binary_op (NE_EXPR, alloc_node, ! integer_zero_node); rval = build_conditional_expr (ifexp, rval, alloc_node); } --- 2503,2514 ---- { if (check_new) { ! tree nullexp; ! tree ifexp; ! ! nullexp = convert (TREE_TYPE (alloc_node), ! use_cookie ? cookie_size : size_zero_node); ! ifexp = cp_build_binary_op (NE_EXPR, alloc_node, nullexp); rval = build_conditional_expr (ifexp, rval, alloc_node); } *************** get_temp_regvar (type, init) *** 2748,2753 **** --- 2703,2711 ---- initialization of a vector of aggregate types. BASE is a reference to the vector, of ARRAY_TYPE. + MAXINDEX is the maximum index of the array (one less than the + number of elements). It is only used if + TYPE_DOMAIN (TREE_TYPE (BASE)) == NULL_TREE. INIT is the (possibly NULL) initializer. FROM_ARRAY is 0 if we should init everything with INIT *************** get_temp_regvar (type, init) *** 2758,2765 **** but use assignment instead of initialization. */ tree ! build_vec_init (base, init, from_array) ! tree base, init; int from_array; { tree rval; --- 2716,2723 ---- but use assignment instead of initialization. */ tree ! build_vec_init (base, maxindex, init, from_array) ! tree base, init, maxindex; int from_array; { tree rval; *************** build_vec_init (base, init, from_array) *** 2779,2794 **** tree try_block = NULL_TREE; tree try_body = NULL_TREE; int num_initialized_elts = 0; - tree maxindex = array_type_nelts (TREE_TYPE (base)); ! if (maxindex == error_mark_node) return error_mark_node; ! /* For g++.ext/arrnew.C. */ ! if (init && TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == NULL_TREE) ! init = digest_init (atype, init, 0); ! ! if (init && !TYPE_NEEDS_CONSTRUCTING (type) && ((TREE_CODE (init) == CONSTRUCTOR /* Don't do this if the CONSTRUCTOR might contain something that might throw and require us to clean up. */ --- 2737,2753 ---- tree try_block = NULL_TREE; tree try_body = NULL_TREE; int num_initialized_elts = 0; ! if (TYPE_DOMAIN (atype)) ! maxindex = array_type_nelts (atype); ! ! if (maxindex == NULL_TREE || maxindex == error_mark_node) return error_mark_node; ! if (init ! && (from_array == 2 ! ? (!CLASS_TYPE_P (type) || !TYPE_HAS_COMPLEX_ASSIGN_REF (type)) ! : !TYPE_NEEDS_CONSTRUCTING (type)) && ((TREE_CODE (init) == CONSTRUCTOR /* Don't do this if the CONSTRUCTOR might contain something that might throw and require us to clean up. */ *************** build_vec_init (base, init, from_array) *** 2801,2807 **** store_constructor will handle the semantics for us. */ stmt_expr = build (INIT_EXPR, atype, base, init); - TREE_SIDE_EFFECTS (stmt_expr) = 1; return stmt_expr; } --- 2760,2765 ---- *************** build_vec_init (base, init, from_array) *** 2973,2979 **** sorry ("cannot initialize multi-dimensional array with initializer"); elt_init = build_vec_init (build1 (INDIRECT_REF, type, base), ! 0, 0); } else elt_init = build_aggr_init (build1 (INDIRECT_REF, type, base), --- 2931,2937 ---- sorry ("cannot initialize multi-dimensional array with initializer"); elt_init = build_vec_init (build1 (INDIRECT_REF, type, base), ! 0, 0, 0); } else elt_init = build_aggr_init (build1 (INDIRECT_REF, type, base), *************** build_dtor_call (exp, dtor_kind, flags) *** 3098,3104 **** default: abort (); } ! return build_method_call (exp, name, NULL_TREE, NULL_TREE, flags); } /* Generate a call to a destructor. TYPE is the type to cast ADDR to. --- 3056,3063 ---- default: abort (); } ! return build_method_call (exp, name, NULL_TREE, ! TYPE_BINFO (TREE_TYPE (exp)), flags); } /* Generate a call to a destructor. TYPE is the type to cast ADDR to. *************** build_delete (type, addr, auto_delete, f *** 3132,3142 **** if (TREE_CODE (type) == POINTER_TYPE) { type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); - if (!VOID_TYPE_P (type) && !complete_type_or_else (type, addr)) - return error_mark_node; if (TREE_CODE (type) == ARRAY_TYPE) goto handle_array; ! if (! IS_AGGR_TYPE (type)) { /* Call the builtin operator delete. */ return build_builtin_delete_call (addr); --- 3091,3108 ---- if (TREE_CODE (type) == POINTER_TYPE) { type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); if (TREE_CODE (type) == ARRAY_TYPE) goto handle_array; ! ! if (VOID_TYPE_P (type) ! /* We don't want to warn about delete of void*, only other ! incomplete types. Deleting other incomplete types ! invokes undefined behavior, but it is not ill-formed, so ! compile to something that would even do The Right Thing ! (TM) should the type have a trivial dtor and no delete ! operator. */ ! || !complete_type_or_diagnostic (type, addr, 1) ! || !IS_AGGR_TYPE (type)) { /* Call the builtin operator delete. */ return build_builtin_delete_call (addr); *************** build_delete (type, addr, auto_delete, f *** 3150,3157 **** else if (TREE_CODE (type) == ARRAY_TYPE) { handle_array: ! if (TREE_SIDE_EFFECTS (addr)) ! addr = save_expr (addr); if (TYPE_DOMAIN (type) == NULL_TREE) { error ("unknown array size in delete"); --- 3116,3122 ---- else if (TREE_CODE (type) == ARRAY_TYPE) { handle_array: ! if (TYPE_DOMAIN (type) == NULL_TREE) { error ("unknown array size in delete"); *************** build_delete (type, addr, auto_delete, f *** 3180,3186 **** return void_zero_node; return build_op_delete_call ! (DELETE_EXPR, addr, c_sizeof_nowarn (type), LOOKUP_NORMAL | (use_global_delete * LOOKUP_GLOBAL), NULL_TREE); } --- 3145,3151 ---- return void_zero_node; return build_op_delete_call ! (DELETE_EXPR, addr, cxx_sizeof_nowarn (type), LOOKUP_NORMAL | (use_global_delete * LOOKUP_GLOBAL), NULL_TREE); } *************** build_delete (type, addr, auto_delete, f *** 3198,3204 **** { /* We will use ADDR multiple times so we must save it. */ addr = save_expr (addr); ! /* Delete the object. */ do_delete = build_builtin_delete_call (addr); /* Otherwise, treat this like a complete object destructor call. */ --- 3163,3169 ---- { /* We will use ADDR multiple times so we must save it. */ addr = save_expr (addr); ! /* Delete the object. */ do_delete = build_builtin_delete_call (addr); /* Otherwise, treat this like a complete object destructor call. */ *************** build_delete (type, addr, auto_delete, f *** 3215,3221 **** /* Build the call. */ do_delete = build_op_delete_call (DELETE_EXPR, addr, ! c_sizeof_nowarn (type), LOOKUP_NORMAL, NULL_TREE); /* Call the complete object destructor. */ --- 3180,3186 ---- /* Build the call. */ do_delete = build_op_delete_call (DELETE_EXPR, addr, ! cxx_sizeof_nowarn (type), LOOKUP_NORMAL, NULL_TREE); /* Call the complete object destructor. */ *************** build_delete (type, addr, auto_delete, f *** 3226,3232 **** { /* Make sure we have access to the member op delete, even though we'll actually be calling it from the destructor. */ ! build_op_delete_call (DELETE_EXPR, addr, c_sizeof_nowarn (type), LOOKUP_NORMAL, NULL_TREE); } --- 3191,3197 ---- { /* Make sure we have access to the member op delete, even though we'll actually be calling it from the destructor. */ ! build_op_delete_call (DELETE_EXPR, addr, cxx_sizeof_nowarn (type), LOOKUP_NORMAL, NULL_TREE); } *************** build_delete (type, addr, auto_delete, f *** 3250,3314 **** } } ! /* At the end of a destructor, call the destructors for our base classes ! and members. ! Called from finish_destructor_body. */ void ! perform_base_cleanups () { tree binfos; int i, n_baseclasses; tree member; tree expr; - tree member_destructions = NULL; - tree vbase_destructions = NULL; - - for (member = TYPE_FIELDS (current_class_type); member; - member = TREE_CHAIN (member)) - { - if (TREE_CODE (member) != FIELD_DECL) - continue; - if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (member))) - { - tree this_member = (build_component_ref - (current_class_ref, member, - NULL_TREE, 0)); - tree this_type = TREE_TYPE (member); - expr = build_delete (this_type, this_member, - sfk_complete_destructor, - LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL, - 0); - if (!member_destructions) - member_destructions = expr; - else - member_destructions = build (COMPOUND_EXPR, - TREE_TYPE (member_destructions), - expr, - member_destructions); - } - } - if (member_destructions) - finish_expr_stmt (member_destructions); - - binfos = BINFO_BASETYPES (TYPE_BINFO (current_class_type)); - n_baseclasses = CLASSTYPE_N_BASECLASSES (current_class_type); - - /* Take care of the remaining baseclasses. */ - for (i = n_baseclasses - 1; i >= 0; i--) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)) - || TREE_VIA_VIRTUAL (base_binfo)) - continue; - - expr = build_scoped_method_call (current_class_ref, base_binfo, - base_dtor_identifier, - NULL_TREE); - - finish_expr_stmt (expr); - } /* Run destructors for all virtual baseclasses. */ if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) --- 3215,3232 ---- } } ! /* At the beginning of a destructor, push cleanups that will call the ! destructors for our base classes and members. ! Called from begin_destructor_body. */ void ! push_base_cleanups () { tree binfos; int i, n_baseclasses; tree member; tree expr; /* Run destructors for all virtual baseclasses. */ if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) *************** perform_base_cleanups () *** 3330,3364 **** if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (base_type)) { ! tree base_ptr_type = build_pointer_type (base_type); ! expr = current_class_ptr; ! ! /* Convert to the basetype here, as we know the layout is ! fixed. What is more, if we let build_method_call do it, ! it will use the vtable, which may have been clobbered ! by the deletion of our primary base. */ ! ! expr = build1 (NOP_EXPR, base_ptr_type, expr); ! expr = build (PLUS_EXPR, base_ptr_type, expr, ! BINFO_OFFSET (vbase)); ! expr = build_indirect_ref (expr, NULL); ! expr = build_method_call (expr, base_dtor_identifier, ! NULL_TREE, vbase, ! LOOKUP_NORMAL); expr = build (COND_EXPR, void_type_node, cond, expr, void_zero_node); ! if (!vbase_destructions) ! vbase_destructions = expr; ! else ! vbase_destructions = build (COMPOUND_EXPR, ! TREE_TYPE (vbase_destructions), ! expr, ! vbase_destructions); } } } ! if (vbase_destructions) ! finish_expr_stmt (vbase_destructions); } /* For type TYPE, delete the virtual baseclass objects of DECL. */ --- 3248,3303 ---- if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (base_type)) { ! expr = build_special_member_call (current_class_ref, ! base_dtor_identifier, ! NULL_TREE, ! vbase, ! (LOOKUP_NORMAL ! | LOOKUP_NONVIRTUAL)); expr = build (COND_EXPR, void_type_node, cond, expr, void_zero_node); ! finish_decl_cleanup (NULL_TREE, expr); } } } ! ! binfos = BINFO_BASETYPES (TYPE_BINFO (current_class_type)); ! n_baseclasses = CLASSTYPE_N_BASECLASSES (current_class_type); ! ! /* Take care of the remaining baseclasses. */ ! for (i = 0; i < n_baseclasses; i++) ! { ! tree base_binfo = TREE_VEC_ELT (binfos, i); ! if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)) ! || TREE_VIA_VIRTUAL (base_binfo)) ! continue; ! ! expr = build_special_member_call (current_class_ref, ! base_dtor_identifier, ! NULL_TREE, base_binfo, ! LOOKUP_NORMAL | LOOKUP_NONVIRTUAL); ! finish_decl_cleanup (NULL_TREE, expr); ! } ! ! for (member = TYPE_FIELDS (current_class_type); member; ! member = TREE_CHAIN (member)) ! { ! if (TREE_CODE (member) != FIELD_DECL || DECL_ARTIFICIAL (member)) ! continue; ! if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (member))) ! { ! tree this_member = (build_class_member_access_expr ! (current_class_ref, member, ! /*access_path=*/NULL_TREE, ! /*preserve_reference=*/false)); ! tree this_type = TREE_TYPE (member); ! expr = build_delete (this_type, this_member, ! sfk_complete_destructor, ! LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL, ! 0); ! finish_decl_cleanup (NULL_TREE, expr); ! } ! } } /* For type TYPE, delete the virtual baseclass objects of DECL. */ *************** build_vec_delete (base, maxindex, auto_d *** 3419,3433 **** base = stabilize_reference (base); - /* Since we can use base many times, save_expr it. */ - if (TREE_SIDE_EFFECTS (base)) - base = save_expr (base); - if (TREE_CODE (type) == POINTER_TYPE) { /* Step back one from start of vector, and read dimension. */ tree cookie_addr; type = strip_array_types (TREE_TYPE (type)); cookie_addr = build (MINUS_EXPR, build_pointer_type (sizetype), --- 3358,3370 ---- base = stabilize_reference (base); if (TREE_CODE (type) == POINTER_TYPE) { /* Step back one from start of vector, and read dimension. */ tree cookie_addr; + if (TREE_SIDE_EFFECTS (base)) + base = save_expr (base); type = strip_array_types (TREE_TYPE (type)); cookie_addr = build (MINUS_EXPR, build_pointer_type (sizetype), *************** build_vec_delete (base, maxindex, auto_d *** 3441,3446 **** --- 3378,3385 ---- maxindex = array_type_nelts_total (type); type = strip_array_types (type); base = build_unary_op (ADDR_EXPR, base, 1); + if (TREE_SIDE_EFFECTS (base)) + base = save_expr (base); } else { diff -Nrc3pad gcc-3.2.3/gcc/cp/lang-options.h gcc-3.3/gcc/cp/lang-options.h *** gcc-3.2.3/gcc/cp/lang-options.h 2001-12-15 20:06:12.000000000 +0000 --- gcc-3.3/gcc/cp/lang-options.h 2003-04-29 14:31:52.000000000 +0000 *************** DEFINE_LANG_NAME ("C++") *** 72,81 **** N_("Export functions even if they can be inlined") }, { "-fimplicit-templates", "" }, { "-fno-implicit-templates", ! N_("Only emit explicit template instatiations") }, { "-fimplicit-inline-templates", "" }, { "-fno-implicit-inline-templates", ! N_("Only emit explicit instatiations of inline templates") }, { "-finit-priority", "" }, { "-fno-init-priority", "" }, { "-fmemoize-lookups", "" }, --- 72,81 ---- N_("Export functions even if they can be inlined") }, { "-fimplicit-templates", "" }, { "-fno-implicit-templates", ! N_("Only emit explicit template instantiations") }, { "-fimplicit-inline-templates", "" }, { "-fno-implicit-inline-templates", ! N_("Only emit explicit instantiations of inline templates") }, { "-finit-priority", "" }, { "-fno-init-priority", "" }, { "-fmemoize-lookups", "" }, diff -Nrc3pad gcc-3.2.3/gcc/cp/lang-specs.h gcc-3.3/gcc/cp/lang-specs.h *** gcc-3.2.3/gcc/cp/lang-specs.h 2002-07-30 20:42:14.000000000 +0000 --- gcc-3.3/gcc/cp/lang-specs.h 2003-03-02 10:17:14.000000000 +0000 *************** Boston, MA 02111-1307, USA. */ *** 33,59 **** {".c++", "@c++", 0}, {".C", "@c++", 0}, {"@c++", ! /* cc1plus has an integrated ISO C preprocessor. We should invoke ! the external preprocessor if -save-temps is given. */ ! "%{E|M|MM:cpp0 -lang-c++ %{!no-gcc:-D__GNUG__=%v1}\ ! %{!Wno-deprecated:-D__DEPRECATED}\ ! %{!fno-exceptions:-D__EXCEPTIONS}\ ! %{ansi:-D__STRICT_ANSI__ -trigraphs -$} %(cpp_options)}\ %{!E:%{!M:%{!MM:\ ! %{save-temps|no-integrated-cpp:cpp0 -lang-c++ \ ! %{!no-gcc:-D__GNUG__=%v1}\ ! %{!Wno-deprecated:-D__DEPRECATED}\ ! %{!fno-exceptions:-D__EXCEPTIONS}\ ! %{ansi:-D__STRICT_ANSI__ -trigraphs -$}\ ! %(cpp_options) %{save-temps:%b.ii} %{!save-temps:%g.ii} \n}\ cc1plus %{save-temps|no-integrated-cpp:-fpreprocessed %{save-temps:%b.ii} %{!save-temps:%g.ii}}\ ! %{!save-temps:%{!no-integrated-cpp:%(cpp_unique_options)\ ! %{!no-gcc:-D__GNUG__=%v1} \ ! %{!Wno-deprecated:-D__DEPRECATED}\ ! %{!fno-exceptions:-D__EXCEPTIONS}\ ! %{ansi:-D__STRICT_ANSI__}}}\ ! %{ansi:-trigraphs -$}\ ! %(cc1_options) %2 %{+e1*}\ %{!fsyntax-only:%(invoke_as)}}}}", CPLUSPLUS_CPP_SPEC}, {".ii", "@c++-cpp-output", 0}, --- 33,46 ---- {".c++", "@c++", 0}, {".C", "@c++", 0}, {"@c++", ! "%{E|M|MM:cc1plus -E %{!no-gcc:-D__GNUG__=%v1}\ ! %(cpp_options) %2 %(cpp_debug_options)}\ %{!E:%{!M:%{!MM:\ ! %{save-temps|no-integrated-cpp:cc1plus -E %{!no-gcc:-D__GNUG__=%v1}\ ! %(cpp_options) %2 %{save-temps:%b.ii} %{!save-temps:%g.ii} \n}\ cc1plus %{save-temps|no-integrated-cpp:-fpreprocessed %{save-temps:%b.ii} %{!save-temps:%g.ii}}\ ! %{!save-temps:%{!no-integrated-cpp:%(cpp_unique_options) %{!no-gcc:-D__GNUG__=%v1}}}\ ! %(cc1_options) %2 %{+e1*}\ %{!fsyntax-only:%(invoke_as)}}}}", CPLUSPLUS_CPP_SPEC}, {".ii", "@c++-cpp-output", 0}, diff -Nrc3pad gcc-3.2.3/gcc/cp/lex.c gcc-3.3/gcc/cp/lex.c *** gcc-3.2.3/gcc/cp/lex.c 2002-10-21 18:38:39.000000000 +0000 --- gcc-3.3/gcc/cp/lex.c 2003-02-13 07:17:11.000000000 +0000 *************** Boston, MA 02111-1307, USA. */ *** 23,38 **** /* This file is the lexical analyzer for GNU C++. */ - /* Cause the `yydebug' variable to be defined. */ - #define YYDEBUG 1 - #include "config.h" #include "system.h" #include "input.h" #include "tree.h" #include "cp-tree.h" #include "cpplib.h" - #include "c-lex.h" #include "lex.h" #include "parse.h" #include "flags.h" --- 23,34 ---- *************** extern int yychar; /* the lookahead sy *** 85,95 **** extern YYSTYPE yylval; /* the semantic value of the */ /* lookahead symbol */ - /* These flags are used by c-lex.c. In C++, they're always off and on, - respectively. */ - int warn_traditional = 0; - int flag_digraphs = 1; - /* the declaration found for the last IDENTIFIER token read in. yylex must look this up to detect typedefs, which get token type tTYPENAME, so it is left around in case the identifier is not a --- 81,86 ---- *************** int interface_only; /* whether or not c *** 206,242 **** int interface_unknown; /* whether or not we know this class to behave according to #pragma interface. */ - /* Tree code classes. */ - - #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, - - static const char cplus_tree_code_type[] = { - 'x', - #include "cp-tree.def" - }; - #undef DEFTREECODE - - /* Table indexed by tree code giving number of expression - operands beyond the fixed part of the node structure. - Not used for types or decls. */ - - #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, - - static const int cplus_tree_code_length[] = { - 0, - #include "cp-tree.def" - }; - #undef DEFTREECODE - - /* Names of tree components. - Used for printing out the tree and error messages. */ - #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME, - - static const char *const cplus_tree_code_name[] = { - "@@dummy", - #include "cp-tree.def" - }; - #undef DEFTREECODE /* Initialization before switch parsing. */ void --- 197,202 ---- *************** init_operators () *** 303,309 **** : &operator_name_info[(int) CODE]); \ oni->identifier = identifier; \ oni->name = NAME; \ ! oni->mangled_name = MANGLING; #include "operators.def" #undef DEF_OPERATOR --- 263,270 ---- : &operator_name_info[(int) CODE]); \ oni->identifier = identifier; \ oni->name = NAME; \ ! oni->mangled_name = MANGLING; \ ! oni->arity = ARITY; #include "operators.def" #undef DEF_OPERATOR *************** struct resword *** 363,369 **** _true_. */ #define D_EXT 0x01 /* GCC extension */ #define D_ASM 0x02 /* in C99, but has a switch to turn it off */ - #define D_OPNAME 0x04 /* operator names */ CONSTRAINT(ridbits_fit, RID_LAST_MODIFIER < sizeof(unsigned long) * CHAR_BIT); --- 324,329 ---- *************** static const struct resword reswords[] = *** 397,419 **** { "__restrict__", RID_RESTRICT, 0 }, { "__signed", RID_SIGNED, 0 }, { "__signed__", RID_SIGNED, 0 }, { "__typeof", RID_TYPEOF, 0 }, { "__typeof__", RID_TYPEOF, 0 }, { "__volatile", RID_VOLATILE, 0 }, { "__volatile__", RID_VOLATILE, 0 }, { "asm", RID_ASM, D_ASM }, - { "and", RID_AND, D_OPNAME }, - { "and_eq", RID_AND_EQ, D_OPNAME }, { "auto", RID_AUTO, 0 }, - { "bitand", RID_BITAND, D_OPNAME }, - { "bitor", RID_BITOR, D_OPNAME }, { "bool", RID_BOOL, 0 }, { "break", RID_BREAK, 0 }, { "case", RID_CASE, 0 }, { "catch", RID_CATCH, 0 }, { "char", RID_CHAR, 0 }, { "class", RID_CLASS, 0 }, - { "compl", RID_COMPL, D_OPNAME }, { "const", RID_CONST, 0 }, { "const_cast", RID_CONSTCAST, 0 }, { "continue", RID_CONTINUE, 0 }, --- 357,375 ---- { "__restrict__", RID_RESTRICT, 0 }, { "__signed", RID_SIGNED, 0 }, { "__signed__", RID_SIGNED, 0 }, + { "__thread", RID_THREAD, 0 }, { "__typeof", RID_TYPEOF, 0 }, { "__typeof__", RID_TYPEOF, 0 }, { "__volatile", RID_VOLATILE, 0 }, { "__volatile__", RID_VOLATILE, 0 }, { "asm", RID_ASM, D_ASM }, { "auto", RID_AUTO, 0 }, { "bool", RID_BOOL, 0 }, { "break", RID_BREAK, 0 }, { "case", RID_CASE, 0 }, { "catch", RID_CATCH, 0 }, { "char", RID_CHAR, 0 }, { "class", RID_CLASS, 0 }, { "const", RID_CONST, 0 }, { "const_cast", RID_CONSTCAST, 0 }, { "continue", RID_CONTINUE, 0 }, *************** static const struct resword reswords[] = *** 439,449 **** { "mutable", RID_MUTABLE, 0 }, { "namespace", RID_NAMESPACE, 0 }, { "new", RID_NEW, 0 }, - { "not", RID_NOT, D_OPNAME }, - { "not_eq", RID_NOT_EQ, D_OPNAME }, { "operator", RID_OPERATOR, 0 }, - { "or", RID_OR, D_OPNAME }, - { "or_eq", RID_OR_EQ, D_OPNAME }, { "private", RID_PRIVATE, 0 }, { "protected", RID_PROTECTED, 0 }, { "public", RID_PUBLIC, 0 }, --- 395,401 ---- *************** static const struct resword reswords[] = *** 474,484 **** { "volatile", RID_VOLATILE, 0 }, { "wchar_t", RID_WCHAR, 0 }, { "while", RID_WHILE, 0 }, - { "xor", RID_XOR, D_OPNAME }, - { "xor_eq", RID_XOR_EQ, D_OPNAME }, }; - #define N_reswords (sizeof reswords / sizeof (struct resword)) /* Table mapping from RID_* constants to yacc token numbers. Unfortunately we have to have entries for all the keywords in all --- 426,433 ---- *************** const short rid_to_yy[RID_MAX] = *** 503,508 **** --- 452,458 ---- /* RID_BOUNDED */ 0, /* RID_UNBOUNDED */ 0, /* RID_COMPLEX */ TYPESPEC, + /* RID_THREAD */ SCSPEC, /* C++ */ /* RID_FRIEND */ SCSPEC, *************** const short rid_to_yy[RID_MAX] = *** 591,610 **** /* RID_REINTCAST */ REINTERPRET_CAST, /* RID_STATCAST */ STATIC_CAST, ! /* alternate spellings */ ! /* RID_AND */ ANDAND, ! /* RID_AND_EQ */ ASSIGN, ! /* RID_NOT */ '!', ! /* RID_NOT_EQ */ EQCOMPARE, ! /* RID_OR */ OROR, ! /* RID_OR_EQ */ ASSIGN, ! /* RID_XOR */ '^', ! /* RID_XOR_EQ */ ASSIGN, ! /* RID_BITAND */ '&', ! /* RID_BITOR */ '|', ! /* RID_COMPL */ '~', ! ! /* Objective C */ /* RID_ID */ 0, /* RID_AT_ENCODE */ 0, /* RID_AT_END */ 0, --- 541,547 ---- /* RID_REINTCAST */ REINTERPRET_CAST, /* RID_STATCAST */ STATIC_CAST, ! /* Objective-C */ /* RID_ID */ 0, /* RID_AT_ENCODE */ 0, /* RID_AT_END */ 0, *************** init_reswords () *** 625,639 **** { unsigned int i; tree id; ! int mask = ((flag_operator_names ? 0 : D_OPNAME) ! | (flag_no_asm ? D_ASM : 0) | (flag_no_gnu_keywords ? D_EXT : 0)); /* It is not necessary to register ridpointers as a GC root, because all the trees it points to are permanently interned in the get_identifier hash anyway. */ ridpointers = (tree *) xcalloc ((int) RID_MAX, sizeof (tree)); ! for (i = 0; i < N_reswords; i++) { id = get_identifier (reswords[i].word); C_RID_CODE (id) = reswords[i].rid; --- 562,575 ---- { unsigned int i; tree id; ! int mask = ((flag_no_asm ? D_ASM : 0) | (flag_no_gnu_keywords ? D_EXT : 0)); /* It is not necessary to register ridpointers as a GC root, because all the trees it points to are permanently interned in the get_identifier hash anyway. */ ridpointers = (tree *) xcalloc ((int) RID_MAX, sizeof (tree)); ! for (i = 0; i < ARRAY_SIZE (reswords); i++) { id = get_identifier (reswords[i].word); C_RID_CODE (id) = reswords[i].rid; *************** const char * *** 668,694 **** cxx_init (filename) const char *filename; { - decl_printable_name = lang_printable_name; input_filename = ""; init_reswords (); init_spew (); init_tree (); - init_cplus_expand (); init_cp_semantics (); - - add_c_tree_codes (); - - memcpy (tree_code_type + (int) LAST_C_TREE_CODE, - cplus_tree_code_type, - (int)LAST_CPLUS_TREE_CODE - (int)LAST_C_TREE_CODE); - memcpy (tree_code_length + (int) LAST_C_TREE_CODE, - cplus_tree_code_length, - (LAST_CPLUS_TREE_CODE - (int)LAST_C_TREE_CODE) * sizeof (int)); - memcpy (tree_code_name + (int) LAST_C_TREE_CODE, - cplus_tree_code_name, - (LAST_CPLUS_TREE_CODE - (int)LAST_C_TREE_CODE) * sizeof (char *)); - init_operators (); init_method (); init_error (); --- 604,615 ---- *************** cxx_init (filename) *** 715,727 **** /* Create the built-in __null node. */ null_node = build_int_2 (0, 0); ! TREE_TYPE (null_node) = type_for_size (POINTER_SIZE, 0); ridpointers[RID_NULL] = null_node; token_count = init_cpp_parse (); interface_unknown = 1; filename = c_common_init (filename); init_cp_pragma (); --- 636,650 ---- /* Create the built-in __null node. */ null_node = build_int_2 (0, 0); ! TREE_TYPE (null_node) = c_common_type_for_size (POINTER_SIZE, 0); ridpointers[RID_NULL] = null_node; token_count = init_cpp_parse (); interface_unknown = 1; filename = c_common_init (filename); + if (filename == NULL) + return NULL; init_cp_pragma (); *************** static int *reduce_count; *** 806,813 **** int *token_count; #if 0 ! #define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0])) ! #define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0])) #endif #ifdef GATHER_STATISTICS --- 729,736 ---- int *token_count; #if 0 ! #define REDUCE_LENGTH ARRAY_SIZE (yyr2) ! #define TOKEN_LENGTH (256 + ARRAY_SIZE (yytname)) #endif #ifdef GATHER_STATISTICS *************** print_parse_statistics () *** 885,906 **** #endif } - /* Sets the value of the 'yydebug' variable to VALUE. - This is a function so we don't have to have YYDEBUG defined - in order to build the compiler. */ - - void - cxx_set_yydebug (value) - int value; - { - #if YYDEBUG != 0 - extern int yydebug; - yydebug = value; - #else - warning ("YYDEBUG not defined"); - #endif - } - /* Helper function to load global variables with interface information. */ --- 808,813 ---- *************** do_pending_lang_change () *** 1167,1173 **** pop_lang_context (); } ! /* Return true if d is in a global scope. */ static int is_global (d) --- 1074,1080 ---- pop_lang_context (); } ! /* Return true if d is in a global scope. */ static int is_global (d) *************** is_global (d) *** 1188,1193 **** --- 1095,1134 ---- } } + /* Issue an error message indicating that the lookup of NAME (an + IDENTIFIER_NODE) failed. */ + + void + unqualified_name_lookup_error (tree name) + { + if (IDENTIFIER_OPNAME_P (name)) + { + if (name != ansi_opname (ERROR_MARK)) + error ("`%D' not defined", name); + } + else if (current_function_decl == 0) + error ("`%D' was not declared in this scope", name); + else + { + if (IDENTIFIER_NAMESPACE_VALUE (name) != error_mark_node + || IDENTIFIER_ERROR_LOCUS (name) != current_function_decl) + { + static int undeclared_variable_notice; + + error ("`%D' undeclared (first use this function)", name); + + if (! undeclared_variable_notice) + { + error ("(Each undeclared identifier is reported only once for each function it appears in.)"); + undeclared_variable_notice = 1; + } + } + /* Prevent repeated error messages. */ + SET_IDENTIFIER_NAMESPACE_VALUE (name, error_mark_node); + SET_IDENTIFIER_ERROR_LOCUS (name, current_function_decl); + } + } + tree do_identifier (token, parsing, args) register tree token; *************** do_identifier (token, parsing, args) *** 1197,1202 **** --- 1138,1144 ---- register tree id; int lexing = (parsing == 1 || parsing == 3); + timevar_push (TV_NAME_LOOKUP); if (! lexing) id = lookup_name (token, 0); else *************** do_identifier (token, parsing, args) *** 1227,1312 **** being used as a declarator. So we call it again to get the error message. */ id = lookup_name (token, 0); ! return error_mark_node; } if (!id || (TREE_CODE (id) == FUNCTION_DECL && DECL_ANTICIPATED (id))) { if (current_template_parms) ! return build_min_nt (LOOKUP_EXPR, token); ! else if (IDENTIFIER_OPNAME_P (token)) ! { ! if (token != ansi_opname (ERROR_MARK)) ! error ("`%D' not defined", token); ! id = error_mark_node; ! } ! else if (current_function_decl == 0) ! { ! error ("`%D' was not declared in this scope", token); ! id = error_mark_node; ! } else { ! if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node ! || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl) ! { ! static int undeclared_variable_notice; ! ! error ("`%D' undeclared (first use this function)", token); ! ! if (! undeclared_variable_notice) ! { ! error ("(Each undeclared identifier is reported only once for each function it appears in.)"); ! undeclared_variable_notice = 1; ! } ! } ! id = error_mark_node; ! /* Prevent repeated error messages. */ ! SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node); ! SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl); } } ! if (TREE_CODE (id) == VAR_DECL && DECL_DEAD_FOR_LOCAL (id)) ! { ! tree shadowed = DECL_SHADOWED_FOR_VAR (id); ! while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL ! && DECL_DEAD_FOR_LOCAL (shadowed)) ! shadowed = DECL_SHADOWED_FOR_VAR (shadowed); ! if (!shadowed) ! shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (id)); ! if (shadowed) ! { ! if (!DECL_ERROR_REPORTED (id)) ! { ! warning ("name lookup of `%s' changed", ! IDENTIFIER_POINTER (token)); ! cp_warning_at (" matches this `%D' under ISO standard rules", ! shadowed); ! cp_warning_at (" matches this `%D' under old rules", id); ! DECL_ERROR_REPORTED (id) = 1; ! } ! id = shadowed; ! } ! else if (!DECL_ERROR_REPORTED (id)) ! { ! DECL_ERROR_REPORTED (id) = 1; ! if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (id))) ! { ! error ("name lookup of `%s' changed for new ISO `for' scoping", ! IDENTIFIER_POINTER (token)); ! cp_error_at (" cannot use obsolete binding at `%D' because it has a destructor", id); ! id = error_mark_node; ! } ! else ! { ! pedwarn ("name lookup of `%s' changed for new ISO `for' scoping", ! IDENTIFIER_POINTER (token)); ! cp_pedwarn_at (" using obsolete binding at `%D'", id); ! } ! } ! } /* TREE_USED is set in `hack_identifier'. */ if (TREE_CODE (id) == CONST_DECL) { --- 1169,1195 ---- being used as a declarator. So we call it again to get the error message. */ id = lookup_name (token, 0); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); } if (!id || (TREE_CODE (id) == FUNCTION_DECL && DECL_ANTICIPATED (id))) { if (current_template_parms) ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ! build_min_nt (LOOKUP_EXPR, token)); ! else if (IDENTIFIER_TYPENAME_P (token)) ! /* A templated conversion operator might exist. */ ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, token); else { ! unqualified_name_lookup_error (token); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); } } ! id = check_for_out_of_scope_variable (id); ! /* TREE_USED is set in `hack_identifier'. */ if (TREE_CODE (id) == CONST_DECL) { *************** do_identifier (token, parsing, args) *** 1337,1364 **** || TREE_CODE (id) == USING_DECL)) id = build_min_nt (LOOKUP_EXPR, token); ! return id; } tree ! do_scoped_id (token, parsing) tree token; ! int parsing; { ! tree id; ! /* during parsing, this is ::name. Otherwise, it is black magic. */ ! if (parsing) ! { ! id = make_node (CPLUS_BINDING); ! if (!qualified_lookup_using_namespace (token, global_namespace, id, 0)) ! id = NULL_TREE; ! else ! id = BINDING_VALUE (id); ! } ! else ! id = IDENTIFIER_GLOBAL_VALUE (token); ! if (parsing && yychar == YYEMPTY) ! yychar = yylex (); if (!id || (TREE_CODE (id) == FUNCTION_DECL && DECL_ANTICIPATED (id))) { --- 1220,1234 ---- || TREE_CODE (id) == USING_DECL)) id = build_min_nt (LOOKUP_EXPR, token); ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, id); } tree ! do_scoped_id (token, id) tree token; ! tree id; { ! timevar_push (TV_NAME_LOOKUP); if (!id || (TREE_CODE (id) == FUNCTION_DECL && DECL_ANTICIPATED (id))) { *************** do_scoped_id (token, parsing) *** 1366,1372 **** { id = build_min_nt (LOOKUP_EXPR, token); LOOKUP_EXPR_GLOBAL (id) = 1; ! return id; } if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node) error ("`::%D' undeclared (first use here)", token); --- 1236,1242 ---- { id = build_min_nt (LOOKUP_EXPR, token); LOOKUP_EXPR_GLOBAL (id) = 1; ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, id); } if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node) error ("`::%D' undeclared (first use here)", token); *************** do_scoped_id (token, parsing) *** 1397,1407 **** { id = build_min_nt (LOOKUP_EXPR, token); LOOKUP_EXPR_GLOBAL (id) = 1; ! return id; } /* else just use the decl */ } ! return convert_from_reference (id); } tree --- 1267,1277 ---- { id = build_min_nt (LOOKUP_EXPR, token); LOOKUP_EXPR_GLOBAL (id) = 1; ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, id); } /* else just use the decl */ } ! POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, convert_from_reference (id)); } tree *************** retrofit_lang_decl (t) *** 1495,1500 **** --- 1365,1376 ---- ld = (struct lang_decl *) ggc_alloc_cleared (size); + ld->decl_flags.can_be_full = CAN_HAVE_FULL_LANG_DECL_P (t) ? 1 : 0; + ld->decl_flags.u1sel = TREE_CODE (t) == NAMESPACE_DECL ? 1 : 0; + ld->decl_flags.u2sel = 0; + if (ld->decl_flags.can_be_full) + ld->u.f.u3sel = TREE_CODE (t) == FUNCTION_DECL ? 1 : 0; + DECL_LANG_SPECIFIC (t) = ld; if (current_lang_name == lang_name_cplusplus) SET_DECL_LANGUAGE (t, lang_cplusplus); *************** retrofit_lang_decl (t) *** 1511,1517 **** } void ! copy_lang_decl (node) tree node; { int size; --- 1387,1393 ---- } void ! cxx_dup_lang_specific_decl (node) tree node; { int size; *************** copy_decl (decl) *** 1543,1549 **** tree copy; copy = copy_node (decl); ! copy_lang_decl (copy); return copy; } --- 1419,1425 ---- tree copy; copy = copy_node (decl); ! cxx_dup_lang_specific_decl (copy); return copy; } *************** copy_lang_type (node) *** 1559,1565 **** if (! TYPE_LANG_SPECIFIC (node)) return; ! size = sizeof (struct lang_type); lt = (struct lang_type *) ggc_alloc (size); memcpy (lt, TYPE_LANG_SPECIFIC (node), size); TYPE_LANG_SPECIFIC (node) = lt; --- 1435,1444 ---- if (! TYPE_LANG_SPECIFIC (node)) return; ! if (TYPE_LANG_SPECIFIC (node)->u.h.is_lang_type_class) ! size = sizeof (struct lang_type); ! else ! size = sizeof (struct lang_type_ptrmem); lt = (struct lang_type *) ggc_alloc (size); memcpy (lt, TYPE_LANG_SPECIFIC (node), size); TYPE_LANG_SPECIFIC (node) = lt; *************** copy_type (type) *** 1584,1590 **** } tree ! cp_make_lang_type (code) enum tree_code code; { register tree t = make_node (code); --- 1463,1469 ---- } tree ! cxx_make_type (code) enum tree_code code; { register tree t = make_node (code); *************** cp_make_lang_type (code) *** 1599,1604 **** --- 1478,1484 ---- ggc_alloc_cleared (sizeof (struct lang_type))); TYPE_LANG_SPECIFIC (t) = pi; + pi->u.c.h.is_lang_type_class = 1; #ifdef GATHER_STATISTICS tree_node_counts[(int)lang_type] += 1; *************** tree *** 1639,1645 **** make_aggr_type (code) enum tree_code code; { ! tree t = cp_make_lang_type (code); if (IS_AGGR_TYPE_CODE (code)) SET_IS_AGGR_TYPE (t, 1); --- 1519,1525 ---- make_aggr_type (code) enum tree_code code; { ! tree t = cxx_make_type (code); if (IS_AGGR_TYPE_CODE (code)) SET_IS_AGGR_TYPE (t, 1); *************** make_aggr_type (code) *** 1647,1666 **** return t; } - void - compiler_error VPARAMS ((const char *msg, ...)) - { - char buf[1024]; - - VA_OPEN (ap, msg); - VA_FIXEDARG (ap, const char *, msg); - - vsprintf (buf, msg, ap); - VA_CLOSE (ap); - - error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf); - } - /* Return the type-qualifier corresponding to the identifier given by RID. */ --- 1527,1532 ---- diff -Nrc3pad gcc-3.2.3/gcc/cp/lex.h gcc-3.3/gcc/cp/lex.h *** gcc-3.2.3/gcc/cp/lex.h 2001-05-26 01:31:45.000000000 +0000 --- gcc-3.3/gcc/cp/lex.h 2002-06-04 07:10:11.000000000 +0000 *************** typedef unsigned long RID_BIT_TYPE; /* a *** 68,82 **** yylex must look this up to detect typedefs, which get token type TYPENAME, so it is left around in case the identifier is not a typedef but is used in a context which makes it a reference to a variable. */ ! extern tree lastiddecl; /* Back-door communication channel to the lexer. */ extern int looking_for_typename; extern int looking_for_template; /* Tell the lexer where to look for names. */ ! extern tree got_scope; ! extern tree got_object; /* Pending language change. Positive is push count, negative is pop count. */ --- 68,82 ---- yylex must look this up to detect typedefs, which get token type TYPENAME, so it is left around in case the identifier is not a typedef but is used in a context which makes it a reference to a variable. */ ! extern GTY(()) tree lastiddecl; /* Back-door communication channel to the lexer. */ extern int looking_for_typename; extern int looking_for_template; /* Tell the lexer where to look for names. */ ! extern GTY(()) tree got_scope; ! extern GTY(()) tree got_object; /* Pending language change. Positive is push count, negative is pop count. */ diff -Nrc3pad gcc-3.2.3/gcc/cp/Make-lang.in gcc-3.3/gcc/cp/Make-lang.in *** gcc-3.2.3/gcc/cp/Make-lang.in 2003-01-28 21:53:12.000000000 +0000 --- gcc-3.3/gcc/cp/Make-lang.in 2003-02-13 07:17:09.000000000 +0000 *************** *** 40,56 **** # Actual names to use when installing a native compiler. CXX_INSTALL_NAME = `echo c++|sed '$(program_transform_name)'` GXX_INSTALL_NAME = `echo g++|sed '$(program_transform_name)'` - DEMANGLER_INSTALL_NAME = `echo c++filt|sed '$(program_transform_name)'` CXX_TARGET_INSTALL_NAME = $(target_alias)-`echo c++|sed '$(program_transform_name)'` GXX_TARGET_INSTALL_NAME = $(target_alias)-`echo g++|sed '$(program_transform_name)'` # Actual names to use when installing a cross-compiler. CXX_CROSS_NAME = `echo c++|sed '$(program_transform_cross_name)'` GXX_CROSS_NAME = `echo g++|sed '$(program_transform_cross_name)'` - DEMANGLER_CROSS_NAME = `echo c++filt|sed '$(program_transform_cross_name)'` - - # The name to use for the demangler program. - DEMANGLER_PROG = c++filt$(exeext) # # Define the names for selecting c++ in LANGUAGES. --- 40,51 ---- *************** g++-cross$(exeext): g++$(exeext) *** 81,102 **** -rm -f g++-cross$(exeext) cp g++$(exeext) g++-cross$(exeext) - # The demangler. - cxxmain.o: $(srcdir)/../libiberty/cplus-dem.c $(DEMANGLE_H) $(CONFIG_H) - rm -f cxxmain.c - $(LN_S) $(srcdir)/../libiberty/cplus-dem.c cxxmain.c - $(CC) -c -DMAIN $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ - -DVERSION=\"$(version)\" cxxmain.c - - # Apparently OpenVM needs the -o to be at the beginning of the link line. - $(DEMANGLER_PROG): cxxmain.o underscore.o $(LIBDEPS) - $(CC) -o $@ $(ALL_CFLAGS) $(LDFLAGS) \ - cxxmain.o underscore.o $(LIBS) - # The compiler itself. # Shared with C front end: CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \ ! $(CXX_TARGET_OBJS) # Language-specific object files. CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \ --- 76,85 ---- -rm -f g++-cross$(exeext) cp g++$(exeext) g++-cross$(exeext) # The compiler itself. # Shared with C front end: CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \ ! c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o # Language-specific object files. CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \ *************** $(srcdir)/cp/parse.c: $(srcdir)/cp/parse *** 131,143 **** false ; \ fi # # Build hooks: c++.all.build: g++$(exeext) ! c++.all.cross: g++-cross$(exeext) $(DEMANGLER_PROG) c++.start.encap: g++$(exeext) ! c++.rest.encap: $(DEMANGLER_PROG) c++.info: c++.dvi: --- 114,130 ---- false ; \ fi + gtype-cp.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h : s-gtype; @true + gt-cp-parse.h gt-cp-pt.h gt-cp-repo.h gt-cp-spew.h : s-gtype; @true + gt-cp-tree.h : s-gtype; @true + # # Build hooks: c++.all.build: g++$(exeext) ! c++.all.cross: g++-cross$(exeext) c++.start.encap: g++$(exeext) ! c++.rest.encap: c++.info: c++.dvi: *************** c++.install-common: installdirs *** 182,198 **** ( cd $(DESTDIR)$(bindir) && \ $(LN) $(CXX_INSTALL_NAME)$(exeext) $(CXX_TARGET_INSTALL_NAME)$(exeext) ); \ fi ; \ - if [ x$(DEMANGLER_PROG) != x ] && [ -x "$(DEMANGLER_PROG)" ]; then \ - if [ -f g++-cross$(exeext) ] ; then \ - rm -f $(DESTDIR)$(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext); \ - $(INSTALL_PROGRAM) $(DEMANGLER_PROG) $(DESTDIR)$(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext); \ - chmod a+x $(DESTDIR)$(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext); \ - else \ - rm -f $(DESTDIR)$(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext); \ - $(INSTALL_PROGRAM) $(DEMANGLER_PROG) $(DESTDIR)$(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext); \ - chmod a+x $(DESTDIR)$(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext); \ - fi ; \ - fi ; \ fi c++.install-info: --- 169,174 ---- *************** c++.uninstall: *** 215,222 **** -rm -rf $(DESTDIR)$(bindir)/$(CXX_CROSS_NAME)$(exeext) -rm -rf $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext) -rm -rf $(DESTDIR)$(bindir)/$(GXX_CROSS_NAME)$(exeext) - -rm -rf $(DESTDIR)$(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext) - -rm -rf $(DESTDIR)$(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext) -rm -rf $(DESTDIR)$(man1dir)/$(GXX_INSTALL_NAME)$(man1ext) -rm -rf $(DESTDIR)$(man1dir)/$(GXX_CROSS_NAME)$(man1ext) # --- 191,196 ---- *************** c++.uninstall: *** 225,231 **** # We just have to delete files specific to us. c++.mostlyclean: ! -rm -f cp/*$(objext) $(DEMANGLER_PROG) c++.clean: c++.distclean: -rm -f cp/config.status cp/Makefile --- 199,206 ---- # We just have to delete files specific to us. c++.mostlyclean: ! -rm -f cp/*$(objext) ! -rm -f cp/*$(coverageexts) c++.clean: c++.distclean: -rm -f cp/config.status cp/Makefile *************** CXX_TREE_H = $(TREE_H) cp/cp-tree.h c-co *** 252,304 **** function.h varray.h $(SYSTEM_H) $(CONFIG_H) $(TARGET_H) \ $(srcdir)/../include/hashtab.h $(srcdir)/../include/splay-tree.h ! cp/spew.o: cp/spew.c $(CXX_TREE_H) cp/parse.h flags.h cp/lex.h toplev.h ! cp/lex.o: cp/lex.c $(CXX_TREE_H) cp/parse.h flags.h cp/lex.h c-pragma.h \ ! toplev.h output.h mbchar.h $(GGC_H) input.h diagnostic.h cp/operators.def \ ! $(TM_P_H) cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) toplev.h langhooks.h $(LANGHOOKS_DEF_H) \ c-common.h cp/decl.o: cp/decl.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h stack.h \ ! output.h $(EXPR_H) except.h toplev.h hash.h $(GGC_H) $(RTL_H) \ ! cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h cp/decl2.o: cp/decl2.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \ ! output.h except.h toplev.h $(GGC_H) $(RTL_H) cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) flags.h toplev.h output.h $(TM_P_H) \ diagnostic.h cp/typeck.o: cp/typeck.c $(CXX_TREE_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \ diagnostic.h cp/class.o: cp/class.c $(CXX_TREE_H) flags.h toplev.h $(RTL_H) $(TARGET_H) cp/call.o: cp/call.c $(CXX_TREE_H) flags.h toplev.h $(RTL_H) $(EXPR_H) \ ! $(GGC_H) diagnostic.h cp/friend.o: cp/friend.c $(CXX_TREE_H) flags.h $(RTL_H) toplev.h $(EXPR_H) cp/init.o: cp/init.c $(CXX_TREE_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \ $(GGC_H) except.h cp/method.o: cp/method.c $(CXX_TREE_H) toplev.h $(GGC_H) $(RTL_H) $(EXPR_H) \ ! $(TM_P_H) cp/cvt.o: cp/cvt.c $(CXX_TREE_H) cp/decl.h flags.h toplev.h convert.h cp/search.o: cp/search.c $(CXX_TREE_H) stack.h flags.h toplev.h $(RTL_H) cp/tree.o: cp/tree.c $(CXX_TREE_H) flags.h toplev.h $(GGC_H) $(RTL_H) \ ! insn-config.h integrate.h tree-inline.h cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(SYSTEM_H) cp/rtti.o: cp/rtti.c $(CXX_TREE_H) flags.h toplev.h cp/except.o: cp/except.c $(CXX_TREE_H) flags.h $(RTL_H) except.h toplev.h \ ! cp/cfns.h $(EXPR_H) libfuncs.h cp/decl.h $(OBSTACK_H) cp/expr.o: cp/expr.c $(CXX_TREE_H) $(RTL_H) flags.h $(EXPR_H) toplev.h \ except.h $(TM_P_H) ! cp/pt.o: cp/pt.c $(CXX_TREE_H) cp/decl.h cp/parse.h cp/lex.h toplev.h \ ! $(GGC_H) $(RTL_H) except.h tree-inline.h ! cp/error.o: cp/error.c $(CXX_TREE_H) toplev.h diagnostic.h flags.h real.h ! cp/repo.o: cp/repo.c $(CXX_TREE_H) toplev.h $(GGC_H) diagnostic.h cp/semantics.o: cp/semantics.c $(CXX_TREE_H) cp/lex.h except.h toplev.h \ flags.h $(GGC_H) debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \ tree-inline.h cp/dump.o: cp/dump.c $(CXX_TREE_H) tree-dump.h cp/optimize.o: cp/optimize.c $(CXX_TREE_H) rtl.h integrate.h insn-config.h \ input.h $(PARAMS_H) debug.h tree-inline.h ! cp/mangle.o: cp/mangle.c $(CXX_TREE_H) toplev.h cp/parse.o: cp/parse.c $(CXX_TREE_H) flags.h cp/lex.h except.h output.h \ ! $(SYSTEM_H) toplev.h $(GGC_H) $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \ $(srcdir)/cp/parse.c $(OUTPUT_OPTION) # --- 227,284 ---- function.h varray.h $(SYSTEM_H) $(CONFIG_H) $(TARGET_H) \ $(srcdir)/../include/hashtab.h $(srcdir)/../include/splay-tree.h ! cp/spew.o: cp/spew.c $(CXX_TREE_H) $(srcdir)/cp/parse.h flags.h cp/lex.h \ ! toplev.h gt-cp-spew.h ! cp/lex.o: cp/lex.c $(CXX_TREE_H) $(srcdir)/cp/parse.h flags.h cp/lex.h \ ! c-pragma.h toplev.h output.h mbchar.h $(GGC_H) input.h diagnostic.h \ ! cp/operators.def $(TM_P_H) cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) toplev.h langhooks.h $(LANGHOOKS_DEF_H) \ c-common.h cp/decl.o: cp/decl.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h stack.h \ ! output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(GGC_H) $(RTL_H) \ ! cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h \ ! debug.h gt-cp-decl.h gtype-cp.h timevar.h cp/decl2.o: cp/decl2.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \ ! output.h except.h toplev.h $(GGC_H) $(RTL_H) c-common.h gt-cp-decl2.h \ ! timevar.h cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) flags.h toplev.h output.h $(TM_P_H) \ diagnostic.h cp/typeck.o: cp/typeck.c $(CXX_TREE_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \ diagnostic.h cp/class.o: cp/class.c $(CXX_TREE_H) flags.h toplev.h $(RTL_H) $(TARGET_H) cp/call.o: cp/call.c $(CXX_TREE_H) flags.h toplev.h $(RTL_H) $(EXPR_H) \ ! $(GGC_H) diagnostic.h gt-cp-call.h cp/friend.o: cp/friend.c $(CXX_TREE_H) flags.h $(RTL_H) toplev.h $(EXPR_H) cp/init.o: cp/init.c $(CXX_TREE_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \ $(GGC_H) except.h cp/method.o: cp/method.c $(CXX_TREE_H) toplev.h $(GGC_H) $(RTL_H) $(EXPR_H) \ ! $(TM_P_H) $(TARGET_H) cp/cvt.o: cp/cvt.c $(CXX_TREE_H) cp/decl.h flags.h toplev.h convert.h cp/search.o: cp/search.c $(CXX_TREE_H) stack.h flags.h toplev.h $(RTL_H) cp/tree.o: cp/tree.c $(CXX_TREE_H) flags.h toplev.h $(GGC_H) $(RTL_H) \ ! insn-config.h integrate.h tree-inline.h real.h gt-cp-tree.h $(TARGET_H) cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(SYSTEM_H) cp/rtti.o: cp/rtti.c $(CXX_TREE_H) flags.h toplev.h cp/except.o: cp/except.c $(CXX_TREE_H) flags.h $(RTL_H) except.h toplev.h \ ! cp/cfns.h $(EXPR_H) libfuncs.h tree-inline.h cp/expr.o: cp/expr.c $(CXX_TREE_H) $(RTL_H) flags.h $(EXPR_H) toplev.h \ except.h $(TM_P_H) ! cp/pt.o: cp/pt.c $(CXX_TREE_H) cp/decl.h $(srcdir)/cp/parse.h cp/lex.h \ ! toplev.h $(GGC_H) $(RTL_H) except.h tree-inline.h gt-cp-pt.h ! cp/error.o: cp/error.c $(CXX_TREE_H) toplev.h diagnostic.h flags.h real.h \ ! $(LANGHOOKS_DEF_H) ! cp/repo.o: cp/repo.c $(CXX_TREE_H) toplev.h $(GGC_H) diagnostic.h \ ! gt-cp-repo.h cp/semantics.o: cp/semantics.c $(CXX_TREE_H) cp/lex.h except.h toplev.h \ flags.h $(GGC_H) debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \ tree-inline.h cp/dump.o: cp/dump.c $(CXX_TREE_H) tree-dump.h cp/optimize.o: cp/optimize.c $(CXX_TREE_H) rtl.h integrate.h insn-config.h \ input.h $(PARAMS_H) debug.h tree-inline.h ! cp/mangle.o: cp/mangle.c $(CXX_TREE_H) toplev.h real.h cp/parse.o: cp/parse.c $(CXX_TREE_H) flags.h cp/lex.h except.h output.h \ ! cp/decl.h $(SYSTEM_H) toplev.h $(GGC_H) gt-cp-parse.h $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \ $(srcdir)/cp/parse.c $(OUTPUT_OPTION) # diff -Nrc3pad gcc-3.2.3/gcc/cp/mangle.c gcc-3.3/gcc/cp/mangle.c *** gcc-3.2.3/gcc/cp/mangle.c 2002-10-18 08:11:44.000000000 +0000 --- gcc-3.3/gcc/cp/mangle.c 2003-02-20 19:35:19.000000000 +0000 *************** *** 1,5 **** /* Name mangling for the 3.0 C++ ABI. ! Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. Written by Alex Samuel This file is part of GNU CC. --- 1,5 ---- /* Name mangling for the 3.0 C++ ABI. ! Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Written by Alex Samuel This file is part of GNU CC. *************** *** 51,56 **** --- 51,57 ---- #include "system.h" #include "tree.h" #include "cp-tree.h" + #include "real.h" #include "obstack.h" #include "toplev.h" #include "varray.h" *************** *** 74,88 **** # define MANGLE_TRACE_TREE(FN, NODE) #endif ! /* Non-zero if NODE is a class template-id. We can't rely on CLASSTYPE_USE_TEMPLATE here because of tricky bugs in the parser that hard to distinguish A from A, where A is the type as instantiated outside of the template, and A is the type used without parameters inside the template. */ ! #define CLASSTYPE_TEMPLATE_ID_P(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE) != NULL \ ! && CLASSTYPE_TEMPLATE_INFO (NODE) != NULL \ ! && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))) /* Things we only need one of. This module is not reentrant. */ static struct globals --- 75,90 ---- # define MANGLE_TRACE_TREE(FN, NODE) #endif ! /* Nonzero if NODE is a class template-id. We can't rely on CLASSTYPE_USE_TEMPLATE here because of tricky bugs in the parser that hard to distinguish A from A, where A is the type as instantiated outside of the template, and A is the type used without parameters inside the template. */ ! #define CLASSTYPE_TEMPLATE_ID_P(NODE) \ ! (TYPE_LANG_SPECIFIC (NODE) != NULL \ ! && (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM \ ! || (CLASSTYPE_TEMPLATE_INFO (NODE) != NULL \ ! && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))))) /* Things we only need one of. This module is not reentrant. */ static struct globals *************** static struct globals *** 97,102 **** --- 99,109 ---- /* The entity that is being mangled. */ tree entity; + /* We are mangling an internal symbol. It is important to keep those + involving template parmeters distinct by distinguishing their level + and, for non-type parms, their type. */ + bool internal_mangling_p; + /* True if the mangling will be different in a future version of the ABI. */ bool need_abi_warning; *************** static tree subst_identifiers[SUBID_MAX] *** 122,128 **** /* Single-letter codes for builtin integer types, defined in . These are indexed by integer_type_kind values. */ ! static char integer_type_codes[itk_none] = { 'c', /* itk_char */ --- 129,135 ---- /* Single-letter codes for builtin integer types, defined in . These are indexed by integer_type_kind values. */ ! static const char integer_type_codes[itk_none] = { 'c', /* itk_char */ *************** static void write_nested_name PARAMS ((t *** 159,164 **** --- 166,172 ---- static void write_prefix PARAMS ((tree)); static void write_template_prefix PARAMS ((tree)); static void write_unqualified_name PARAMS ((tree)); + static void write_conversion_operator_name (tree); static void write_source_name PARAMS ((tree)); static int hwint_to_ascii PARAMS ((unsigned HOST_WIDE_INT, unsigned int, char *, unsigned)); static void write_number PARAMS ((unsigned HOST_WIDE_INT, int, *************** static const char *mangle_decl_string PA *** 193,203 **** /* Control functions. */ ! static inline void start_mangling PARAMS ((tree)); ! static inline const char *finish_mangling PARAMS ((bool)); static tree mangle_special_for_type PARAMS ((tree, const char *)); ! /* Foreign language functions. */ static void write_java_integer_type_codes PARAMS ((tree)); --- 201,211 ---- /* Control functions. */ ! static inline void start_mangling (tree); ! static inline const char *finish_mangling (bool); static tree mangle_special_for_type PARAMS ((tree, const char *)); ! /* Foreign language functions. */ static void write_java_integer_type_codes PARAMS ((tree)); *************** static void write_java_integer_type_code *** 206,212 **** #define write_char(CHAR) \ obstack_1grow (&G.name_obstack, (CHAR)) ! /* Append a sized buffer to the end of the mangled representation. */ #define write_chars(CHAR, LEN) \ obstack_grow (&G.name_obstack, (CHAR), (LEN)) --- 214,220 ---- #define write_char(CHAR) \ obstack_1grow (&G.name_obstack, (CHAR)) ! /* Append a sized buffer to the end of the mangled representation. */ #define write_chars(CHAR, LEN) \ obstack_grow (&G.name_obstack, (CHAR), (LEN)) *************** static void write_java_integer_type_code *** 215,226 **** #define write_string(STRING) \ obstack_grow (&G.name_obstack, (STRING), strlen (STRING)) ! /* Return the position at which the next character will be appended to ! the mangled representation. */ ! #define mangled_position() \ ! obstack_object_size (&G.name_obstack) ! ! /* Non-zero if NODE1 and NODE2 are both TREE_LIST nodes and have the same purpose (context, which may be a type) and value (template decl). See write_template_prefix for more information on what this is used for. */ --- 223,229 ---- #define write_string(STRING) \ obstack_grow (&G.name_obstack, (STRING), strlen (STRING)) ! /* Nonzero if NODE1 and NODE2 are both TREE_LIST nodes and have the same purpose (context, which may be a type) and value (template decl). See write_template_prefix for more information on what this is used for. */ *************** static void write_java_integer_type_code *** 232,246 **** || TREE_PURPOSE (NODE1) == TREE_PURPOSE (NODE2)) \ && TREE_VALUE (NODE1) == TREE_VALUE (NODE2)) - /* Write out a signed quantity in base 10. */ - #define write_signed_number(NUMBER) \ - write_number ((NUMBER), /*unsigned_p=*/0, 10) - /* Write out an unsigned quantity in base 10. */ #define write_unsigned_number(NUMBER) \ write_number ((NUMBER), /*unsigned_p=*/1, 10) ! /* If DECL is a template instance, return non-zero and, if TEMPLATE_INFO is non-NULL, set *TEMPLATE_INFO to its template info. Otherwise return zero. */ --- 235,245 ---- || TREE_PURPOSE (NODE1) == TREE_PURPOSE (NODE2)) \ && TREE_VALUE (NODE1) == TREE_VALUE (NODE2)) /* Write out an unsigned quantity in base 10. */ #define write_unsigned_number(NUMBER) \ write_number ((NUMBER), /*unsigned_p=*/1, 10) ! /* If DECL is a template instance, return nonzero and, if TEMPLATE_INFO is non-NULL, set *TEMPLATE_INFO to its template info. Otherwise return zero. */ *************** decl_is_template_id (decl, template_info *** 260,266 **** if (template_info != NULL) /* For a templated TYPE_DECL, the template info is hanging off the type. */ ! *template_info = CLASSTYPE_TEMPLATE_INFO (type); return 1; } } --- 259,265 ---- if (template_info != NULL) /* For a templated TYPE_DECL, the template info is hanging off the type. */ ! *template_info = TYPE_TEMPLATE_INFO (type); return 1; } } *************** add_substitution (node) *** 380,386 **** dump_substitution_candidates (); } ! /* Helper function for find_substitution. Returns non-zero if NODE, which may be a decl or a CLASS_TYPE, is a template-id with template name of substitution_index[INDEX] in the ::std namespace. */ --- 379,385 ---- dump_substitution_candidates (); } ! /* Helper function for find_substitution. Returns nonzero if NODE, which may be a decl or a CLASS_TYPE, is a template-id with template name of substitution_index[INDEX] in the ::std namespace. */ *************** is_std_substitution (node, index) *** 408,419 **** return (DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl)) && TYPE_LANG_SPECIFIC (type) ! && CLASSTYPE_TEMPLATE_INFO (type) ! && (DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)) == subst_identifiers[index])); } ! /* Helper function for find_substitution. Returns non-zero if NODE, which may be a decl or a CLASS_TYPE, is the template-id ::std::identifier, where identifier is substitution_index[INDEX]. */ --- 407,418 ---- return (DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl)) && TYPE_LANG_SPECIFIC (type) ! && TYPE_TEMPLATE_INFO (type) ! && (DECL_NAME (TYPE_TI_TEMPLATE (type)) == subst_identifiers[index])); } ! /* Helper function for find_substitution. Returns nonzero if NODE, which may be a decl or a CLASS_TYPE, is the template-id ::std::identifier, where identifier is substitution_index[INDEX]. */ *************** is_std_substitution_char (node, index) *** 473,479 **** candidates for entities appearing earlier in the same mangling If a substitution is found, write its mangled representation and ! return non-zero. If none is found, just return zero. */ static int find_substitution (node) --- 472,478 ---- candidates for entities appearing earlier in the same mangling If a substitution is found, write its mangled representation and ! return nonzero. If none is found, just return zero. */ static int find_substitution (node) *************** find_substitution (node) *** 585,591 **** } /* Now check the list of available substitutions for this mangling ! operation. */ for (i = 0; i < size; ++i) { tree candidate = VARRAY_TREE (G.substitutions, i); --- 584,590 ---- } /* Now check the list of available substitutions for this mangling ! operation. */ for (i = 0; i < size; ++i) { tree candidate = VARRAY_TREE (G.substitutions, i); *************** write_encoding (decl) *** 657,663 **** tree fn_type; if (decl_is_template_id (decl, NULL)) ! fn_type = get_mostly_instantiated_function_type (decl, NULL, NULL); else fn_type = TREE_TYPE (decl); --- 656,662 ---- tree fn_type; if (decl_is_template_id (decl, NULL)) ! fn_type = get_mostly_instantiated_function_type (decl); else fn_type = TREE_TYPE (decl); *************** write_encoding (decl) *** 675,681 **** ::= ::= ! If IGNORE_LOCAL_SCOPE is non-zero, this production of is called from , which mangles the enclosing scope elsewhere and then uses this function to mangle just the part underneath the function scope. So don't use the --- 674,680 ---- ::= ::= ! If IGNORE_LOCAL_SCOPE is nonzero, this production of is called from , which mangles the enclosing scope elsewhere and then uses this function to mangle just the part underneath the function scope. So don't use the *************** write_nested_name (decl) *** 847,853 **** write_char ('E'); } ! /* ::= > ::= ::= # empty ::= */ --- 846,853 ---- write_char ('E'); } ! /* ::= ! ::= ::= ::= # empty ::= */ *************** write_prefix (node) *** 870,876 **** return; if (DECL_P (node)) - /* Node is a decl. */ { /* If this is a function decl, that means we've hit function scope, so this prefix must be for a local name. In this --- 870,875 ---- *************** write_prefix (node) *** 884,901 **** decl_is_template_id (decl, &template_info); } else - /* Node is a type. */ { decl = TYPE_NAME (node); if (CLASSTYPE_TEMPLATE_ID_P (node)) ! template_info = CLASSTYPE_TEMPLATE_INFO (node); } /* In G++ 3.2, the name of the template parameter was used. */ ! if (TREE_CODE (node) == TEMPLATE_TYPE_PARM) G.need_abi_warning = true; ! if (template_info != NULL) /* Templated. */ { write_template_prefix (decl); --- 883,904 ---- decl_is_template_id (decl, &template_info); } else { + /* Node is a type. */ decl = TYPE_NAME (node); if (CLASSTYPE_TEMPLATE_ID_P (node)) ! template_info = TYPE_TEMPLATE_INFO (node); } /* In G++ 3.2, the name of the template parameter was used. */ ! if (TREE_CODE (node) == TEMPLATE_TYPE_PARM ! && !abi_version_at_least (2)) G.need_abi_warning = true; ! if (TREE_CODE (node) == TEMPLATE_TYPE_PARM ! && abi_version_at_least (2)) ! write_template_param (node); ! else if (template_info != NULL) /* Templated. */ { write_template_prefix (decl); *************** write_prefix (node) *** 912,917 **** --- 915,921 ---- } /* ::=