diff options
Diffstat (limited to 'contrib/gcc/cp')
-rw-r--r-- | contrib/gcc/cp/ChangeLog | 708 | ||||
-rw-r--r-- | contrib/gcc/cp/Make-lang.in | 9 | ||||
-rw-r--r-- | contrib/gcc/cp/NEWS | 21 | ||||
-rw-r--r-- | contrib/gcc/cp/call.c | 69 | ||||
-rw-r--r-- | contrib/gcc/cp/class.c | 107 | ||||
-rw-r--r-- | contrib/gcc/cp/cp-tree.def | 4 | ||||
-rw-r--r-- | contrib/gcc/cp/cp-tree.h | 98 | ||||
-rw-r--r-- | contrib/gcc/cp/cvt.c | 7 | ||||
-rw-r--r-- | contrib/gcc/cp/decl.c | 746 | ||||
-rw-r--r-- | contrib/gcc/cp/decl2.c | 66 | ||||
-rw-r--r-- | contrib/gcc/cp/dump.c | 9 | ||||
-rw-r--r-- | contrib/gcc/cp/error.c | 14 | ||||
-rw-r--r-- | contrib/gcc/cp/friend.c | 2 | ||||
-rw-r--r-- | contrib/gcc/cp/g++spec.c | 15 | ||||
-rw-r--r-- | contrib/gcc/cp/init.c | 196 | ||||
-rw-r--r-- | contrib/gcc/cp/lang-specs.h | 10 | ||||
-rw-r--r-- | contrib/gcc/cp/lex.c | 10 | ||||
-rw-r--r-- | contrib/gcc/cp/mangle.c | 92 | ||||
-rw-r--r-- | contrib/gcc/cp/method.c | 185 | ||||
-rw-r--r-- | contrib/gcc/cp/parse.y | 67 | ||||
-rw-r--r-- | contrib/gcc/cp/pt.c | 484 | ||||
-rw-r--r-- | contrib/gcc/cp/search.c | 96 | ||||
-rw-r--r-- | contrib/gcc/cp/semantics.c | 84 | ||||
-rw-r--r-- | contrib/gcc/cp/spew.c | 5 | ||||
-rw-r--r-- | contrib/gcc/cp/tree.c | 95 | ||||
-rw-r--r-- | contrib/gcc/cp/typeck.c | 492 | ||||
-rw-r--r-- | contrib/gcc/cp/typeck2.c | 26 |
27 files changed, 2271 insertions, 1446 deletions
diff --git a/contrib/gcc/cp/ChangeLog b/contrib/gcc/cp/ChangeLog index 63c8747..b2b71e9 100644 --- a/contrib/gcc/cp/ChangeLog +++ b/contrib/gcc/cp/ChangeLog @@ -1,5 +1,709 @@ +2002-05-03 Jason Merrill <jason@redhat.com> + + * decl.c (BOOL_TYPE_SIZE): Move default to defaults.h. + +2002-05-02 Mark Mitchell <mark@codesourcery.com> + + * init.c (perform_base_cleanups): Correct order of base class + cleanups. + +2002-05-01 Mark Mitchell <mark@codesourcery.com> + + PR c++/6527 + * init.c (perform_base_cleanups): Emit cleanups in reverse order + of construction. + +2002-05-01 Gabriel Dos Reis <gdr@codesourcery.com> + + * error.c (dump_type): Be careful about implicit typenames. + +2002-04-30 Mark Mitchell <mark@codesourcery.com> + + ABI change, returning simple classes from functions. + * class.c (finish_struct_bits): Only mark TREE_ADDRESSABLE if + TYPE_HAS_TRIVIAL_INIT_REF is false or + TYPE_HAS_NONTRIVIAL_DESTRUCTOR is true. + +2002-04-30 Jason Merrill <jason@redhat.com> + + * decl.c (grokdeclarator): Don't override TYPE_NAME of an + anonymous class with a typedef if there are attributes. + +2002-04-29 Paul Eggert <eggert@twinsun.com> + + * parse.y (nomods_initdcl0): Replace $<ttype>3 with $<ttype>$. + +2002-04-29 Jakub Jelinek <jakub@redhat.com> + + PR c++/6477 + * decl.c (follow_tag_typedef): Check if TYPE_NAME (original) is + non-NULL first. + +2002-04-29 Mark Mitchell <mark@codesourcery.com> + + PR c++/6492 + * pt.c (tsubst_friend_class): If the friend has an explicit scope, + enter that scope before name lookup. + + PR c++/6486 + * method.c (do_build_copy_constructor): Avoid building + cv-qualified reference types. + +2002-04-29 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/5719 + * decl.c (grok_op_properties): Assignment ops don't have to return + by value. operator% should. + +2002-04-28 Franz Sirl <Franz.Sirl-kernel@lauterbach.com> + + PR c/6343 + * decl.c (duplicate_decls): Call merge_weak. + +2002-04-26 Mark Mitchell <mark@codesourcery.com> + + 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 <mark@codesourcery.com> + + * 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 <jason@redhat.com> + + PR c++/6331 + * method.c (do_build_copy_constructor): Use cp_build_qualified_type. + * typeck.c (build_modify_expr): Allow arrays to differ in cv-quals. + The pedwarn for array assignment is now unconditional. + * tree.c (build_cplus_array_type_1): Still process simple array types + normally in templates. + + PR c++/6395 + * decl.c (make_rtl_for_nonlocal_decl): Don't mess with #pragma i/i + stuff for comdats. + +2002-04-23 Jason Merrill <jason@redhat.com> + + 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 <jakub@redhat.com> + + * parse.y (check_class_key): Allow KEY to be union/enum/struct/class + node with attributes. + +2002-2-23 David O'Brien <obrien@FreeBSD.org> + + * g++spec.c (MATH_LIBRARY_PROFILE, LIBSTDCXX_PROFILE): Add. + Use MATH_LIBRARY_PROFILE and LIBSTDCXX_PROFILE if profile flag given. + +2002-04-23 Mark Mitchell <mark@codesourcery.com> + + PR c++/6256: + * pt.c (tsubst_friend_class): Handle templates with explicit + nested names. + + PR c++/6331: + * typeck.c (merge_types): Remember the cv-qualification of pointer + types when merging them. + +2002-04-18 Jason Merrill <jason@redhat.com> + + PR c++/5658 + * search.c (setup_class_bindings): A class template qualifies as a + type binding. + +2002-04-17 Jakub Jelinek <jakub@redhat.com> + + PR c++/6316 + * decl2.c (finish_file): Clear DECL_EXTERNAL in a separate loop + before expanding. + +2002-04-16 Mark Mitchell <mark@codesourcery.com> + + * init.c (begin_init_stmts): Remove commented out code. + (finish_init_stmts): Set STMT_EXPR_NO_SCOPE. + * semantics.c (begin_gobal_stmt_expr): Adjust call to + expand_start_stmt_expr. + +2002-04-15 Mark Mitchell <mark@codesourcery.com> + + * decl.c (register_dtor_fn): Pass the address of dso_handle, not + dso_handle itself, to __cxa_atexit. + +2002-04-14 Jakub Jelinek <jakub@redhat.com> + + * class.c (layout_virtual_bases): Do all dsize computation on trees. + +2002-04-12 Mark Mitchell <mark@codesourcery.com> + + PR c++/5373. + * semantics.c (finish_expr_stmt): Remember the type of the + expression before any conversions are performed. + + PR c++/5189. + * call.c (add_template_candidate_real): Do not treat member + templates as copy constructors. + + * 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-11 Andrew Haley <aph@redhat.com> + + * typeck.c (type_after_usual_arithmetic_conversions): + If two types have the same variant, return immediately. + When two floating-point operands are the same precision: + convert to float if one of the operands is float; + if neither operand is one of the standard types, return the type + of the first operand. + +2002-04-12 Richard Sandiford <rsandifo@redhat.com> + + * 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 <nathan@codesourcery.com> + + PR c++/5507 + * decl.c (make_typename_type): Remove implicit typenameness. + +2002-04-09 Jason Merrill <jason@redhat.com> + + PR optimization/6189 + * semantics.c (genrtl_start_function): Don't free + DECL_SAVED_FUNCTION_DATA for inline functions. + +2002-04-08 Paolo Carlini <pcarlini@unitus.it> + + * parse.y (namespace_qualifier, maybe_identifier, + begin_explicit_instantiation, end_explicit_instantiation, + apparent_template_type, .finish_template_type, + do_id, maybe_init, defarg_again, component_decl_1): + Add ending ';', in accordance with POSIX. + +2002-04-06 Mark Mitchell <mark@codesourcery.com> + + PR c++/5571 + * class.c (layout_class_type): Remember incomplete static + variables. + (finish_struct_1): Call complete_vars, not + hack_incomplete_structures. + * cp-tree.h (hack_incomplete_structures): Rename to ... + (complete_vars): ... this. + (struct saved_scope): Remove incomplete. + (namespace_scope_incomplete): Remove. + * decl.c (struct binding_level): Remove incomplete. + (incomplete_vars): New variable. + (mark_binding_level): Don't mark incomplete. + (print_binding_level): Don't print it. + (mark_saved_scope): Don't mark incomplete. + (pushdecl): Use maybe_register_incopmlete_var. + (cxx_init_decl_processing): Register incomplete_vars for GC. + (start_decl_1): Clarify error message. + (hack_incomplete_vars): Remove. + (maybe_register_incomplete_var): New function. + (complete_vars): Likewise. + +2002-04-06 Jason Merrill <jason@redhat.com> + + PR c++/4934 + * 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 <jason@redhat.com> + + 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 + cleanup for nrv. + + PR c++/5104 + * typeck.c (comptypes) [FUNCTION_TYPE]: Don't compare exception + specifiers. + [METHOD_TYPE]: Use same code as FUNCTION_TYPE. + +2002-04-03 Roger Sayle <roger@eyesopen.com> + + PR c++/5998: + * decl.c (duplicate_decls): Don't mess with assembler names when + redeclaring builtin functions as static. + +2002-04-01 Roger Sayle <roger@eyesopen.com> + + PR c++/5998: + * decl.c (duplicate_decls): Overwrite the RTL when (and only + 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-03-28 Roger Sayle <roger@eyesopen.com> + + PR c++/5998: + * decl.c (cxx_init_decl_processing): Re-enable built-in functions + in the g++ front-end. + (duplicate_decl): Allow redefinition of anticipated built-ins. + Fix inlining problem by over-writing the old DECL_RTL. + (lookup_namespace_name): Fail to find an identifier in the + specified namespace if its still anticipated. + (builtin_function_1): New function split out from builtin_function + to create a builtin in the current namespace with given context. + (builtin_function): Call builtin_function_1 to define the + appropriate builtins in both the std and global namespaces. + (select_decl): Don't test for anticipated decls here. + (unqualified_namespace_lookup): Instead ignore them whilst + searching through scopes and namespaces. + * decl2.c (do_nonmember_using_decl): If a using declaration + specifies an anticipated built-in function, mark it as no longer + anticipated in that scope. + (ambiguous_decl): Avoid resolving to an anticipated decl. + * lex.c (do_scoped_id): Fail to find an identifier in the global + namespace if its still anticipated. + +2002-03-29 Jakub Jelinek <jakub@redhat.com> + + 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 Mark Mitchell <mark@codesourcery.com> + + PR c++/4884 + * call.c (build_op_delete_call): Allow for the fact the placement + may be a COMPOUND_EXPR. + +2002-03-26 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/5682 + * cp-tree.h (BINFO_PRIMARY_P): Explain meaning better. + (dfs_skip_nonprimary_vbases_unmarkedp): Remove. + (dfs_skip_nonprimary_vbases_markedp): Remove. + * search.c (get_shared_vbase_if_not_primary): Remove. + (dfs_skip_nonprimary_vbases_unmarkedp): Remove. + (dfs_skip_nonprimary_vbases_markedp): Remove. + (dfs_unmarked_real_bases_queue_p): Just get the canonical binfo. + (dfs_marked_real_bases_queue_p): Likewise. + +2002-03-26 Mark Mitchell <mark@codesourcery.com> + + 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 <jakub@redhat.com> + + PR c++/6037 + * decl.c (start_enum): Don't set TREE_ADDRESSABLE on TREE_LIST node. + +2002-03-22 Jeff Knaggs <jknaggs@redhat.com> + + * 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 <aldyh@redhat.com> + + * tree.c (cp_cannot_inline_tree_fn): Same. + +2002-03-20 Jason Merrill <jason@redhat.com> + + PR c++/2136 + * init.c (build_delete): Check access for a member op delete here. + * decl2.c (delete_sanity): Not here. + +2002-03-19 Jason Merrill <jason@redhat.com> + + PR c++/5118 + * class.c (get_vfield_name): Use the constructor_name. + +2002-03-18 Eric Botcazou <ebotcazou@multimania.com> + + PR c++/3882 + * pt.c (tsubst_decl): Move __PRETTY_FUNCTION__ handling... + (tsubst_expr) [DECL_STMT]: ...here. And substitute the initializer + only after recording the declaration. + +2002-03-18 Ashif Harji <asharji@uwaterloo.ca> + + * lang-specs.h (compiler default_compilers): Add + -no-integrated-cpp flag to invoke an external cpp. + +2002-03-18 Jason Merrill <jason@redhat.com> + + PR c++/2039 + * init.c (resolve_offset_ref): Hand off to build_component_ref. + + PR c++/4222, c++/5995 + * call.c (build_over_call): Fix empty class logic. + + PR c++/3870 + * cp-tree.h (struct saved_scope): Add last_parms field. + * decl.c (maybe_push_to_top_level): Save last_function_parms. + (pop_from_top_level): Restore it. + + PR c++/4377 + * mangle.c (write_expression): Strip NOP_EXPRs sooner. Also strip + NON_LVALUE_EXPRs. + + PR c++/4003 + * pt.c (tsubst_friend_function): Use decl_namespace_context. + + PR c++/3948 -- C++ ABI change, followup to 2001-12-18 patch. + * class.c (finish_struct_bits): Also set TREE_ADDRESSABLE for a + type with a nontrivial destructor. + +2002-03-17 Jason Merrill <jason@redhat.com> + + PR c++/4460 + * 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 <rth@redhat.com> + + * init.c (build_new_1): Use size_binop instead of cp_build_binary_op. + +2002-03-15 Richard Henderson <rth@redhat.com> + + * decl.c (finish_function): Reapply accidentally reverted + 2002-02-28 patch. + +2002-03-15 Mark Mitchell <mark@codesourcery.com> + + * cp-tree.h (CLEANUP_DECL): Remove. + (CLEANUP_EXPR): Likewise. + * decl.c (destroy_local_var): Simplify. + (maybe_build_cleanup): Tidy. + * dump.c (cp_dump_tree): Remove handling of CLEANUP_STMT. + * semantics.c (cp_expand_stmt): Likewise. + * cp/tree.c (cp_statement_code_p): Likewise. + +2002-03-15 Richard Henderson <rth@redhat.com> + + * 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 <jason@redhat.com> + + PR c++/5857 + * decl.c (duplicate_decls): Use merge_types instead of common_type. + * typeck.c (common_type): Just hand off to + type_after_usual_arithmetic_conversions and + composite_pointer_type. + (merge_types): New fn. + (commonparms): Use it instead of common_type. + (type_after_usual_arithmetic_conversions): Also handle COMPLEX_TYPE. + (composite_pointer_type): Also handle attributes. + * cp-tree.h: Declare merge_types. + + * decl.c (make_rtl_for_nonlocal_decl): Also defer COMDAT + variables. + * decl2.c (maybe_make_one_only): Also mark the decl as needed. + +2002-03-14 Jakub Jelinek <jakub@redhat.com> + + PR c++/5908 + * call.c (build_over_call): Set TREE_NO_UNUSED_WARNING too. + * cvt.c (convert_to_void): Preserve TREE_NO_UNUSED_WARNING. + +2002-03-12 Richard Sandiford <rsandifo@redhat.com> + + * mangle.c (write_builtin_type): Handle 128-bit integers even if + they are not a standard integer type. + +2002-03-12 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/5659 + * decl.c (xref_tag): Don't set CLASSTYPE_DECLARED_CLASS here. + * decl2.c (handle_class_head): Set CLASSTYPE_DECLARED_CLASS for + definitions. + +2002-03-11 Nathan Sidwell <nathan@codesourcery.com> + + Revert 2001-03-26 Nathan Sidwell <nathan@codesourcery.com>, + DR209 is now not a defect. + * cp-tree.h (skip_type_access_control): Remove. + * decl.c (grokdeclarator): Do type access control for friend + declarations. + * semantics.c (decl_type_access_control): Don't reset + current_type_lookups. + (save_type_access_control): Always save the lookups. + (skip_type_access_control): Remove. + (finish_class_definition): Don't change type_lookups. + +2002-03-11 Nathan Sidwell <nathan@codesourcery.com> + + Revert 2000-12-01 Nathan Sidwell <nathan@codesourcery.com>, + It is incorrect. + * typeck.c (build_static_cast): Compare non-qualified types + with pointer to member conversions. + +2002-03-08 Craig Rodrigues <rodrigc@gcc.gnu.org> + + * cp-tree.h (CLEAR_BINFO_MARKED): Make both parts of + conditional return void. + +2002-03-02 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/775 + * decl.c (lookup_tag): Only reject enum/class mismatch, not + class/union mismatch. + * parse.y (check_class_key): New function. + (structsp): Call it. + +2002-03-01 Michael Matz <matz@suse.de> + + * typeck.c (cp_pointer_int_sum): Complete inner type which is + used later by size_in_bytes(). + +2002-03-01 Phil Edwards <pme@gcc.gnu.org> + + * cp-tree.h (build_init): Remove prototype. + +2002-03-01 Phil Edwards <pme@gcc.gnu.org> + + * cp-tree.h: Require __GNUC__ to be #defined. + (build_init): Add missing prototype. + +2002-02-28 Jason Merrill <jason@redhat.com> + + * search.c (lookup_base_r): Don't clear is_non_public just because + we found a friendly scope. + + * decl.c (finish_function): Only warn about missing return + statement with -Wreturn-type. + +2002-02-24 Craig Rodrigues <rodrigc@gcc.gnu.org> + + PR c++/4093 + * cp-tree.h (SET_BINFO_MARKED): Cast false part of condition + to void. + +2002-02-22 Jakub Jelinek <jakub@redhat.com> + + PR other/5746 + * semantics.c (finish_switch_cond): Don't call get_unwidened + if error_mark_node. + +2002-02-22 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/2645, DR 295 + * cp-tree.h (tsubst_flags_t): Add tf_ignore_bad_quals, + tf_keep_type_decl. + (make_typename_type): Use tsubst_flags_t. + * decl.c (make_typename_type): Adjust. Return non-artificial + TYPE_DECLs, if required. + (grokdeclarator): Simplify CVR qualification handling. Allow bad + qualifiers on typedef types. + * decl2.c (handle_class_head): Adjust make_typename_type call. + * parse.y (nested_name_specifier): Likewise. + (typename_sub0): Likewise. + (typename_sub1): Likewise. + * 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. + * tree.c (cp_build_qualified_type_real): Use tf_allow_bad_quals. + +2002-02-21 Aldy Hernandez <aldyh@redhat.com> + + * cp/decl.c (duplicate_decls): Merge always_inline attribute. + + * cp/tree.c (cp_cannot_inline_tree_fn): Do not inline at -O0 + unless DECL_ALWAYS_INLINE. + +2002-02-20 Jakub Jelinek <jakub@redhat.com> + + * typeck.c (cp_pointer_int_sum): Renamed from + pointer_int_sum, call pointer_int_sum. + +2002-02-20 Jakub Jelinek <jakub@redhat.com> + + * decl.c (duplicate_decls): Return 0 if issued error about + redeclaration. + +2002-02-19 Jason Merrill <jason@redhat.com> + + ABI change: Mangle `void (A::*)() const' as + M1AKFvvE, not MK1AFvvE. + * mangle.c (write_function_type): Write cv-quals for member + function type here. + (write_pointer_to_member_type): Not here. + +2002-02-18 Jason Merrill <jason@redhat.com> + + * pt.c (do_type_instantiation): Don't pedwarn if in_system_header. + (do_decl_instantiation): Likewise. + +2002-02-17 Craig Rodrigues <rodrigc@gcc.gnu.org> + + PR c++/5685 + * decl.c (duplicate_decls): Make warning unconditional + if duplicate default argument declarations are present. + +2002-02-17 Jakub Jelinek <jakub@redhat.com> + + * typeck.c (build_binary_op) [BIT_XOR_EXPR]: Remove explicit + shortening. + +2002-02-15 Nathan Sidwell <nathan@codesourcery.com> + + * decl.c (grokdeclarator): Set typedef_decl for all TYPE_DECLs, + remove incorrect comment. Move #if 0'd code to common path. Use + IMPLICIT_TYPENAME_P. Simplify & reformat ARRAY_TYPE duplication. + +2002-02-13 Jason Merrill <jason@redhat.com> + + * decl.c (builtin_function): Set TREE_THIS_VOLATILE on return fns. + (finish_function): Don't warn if current_function_returns_null. + + * typeck2.c (digest_init): Do handle values of vector type. + + * typeck2.c (digest_init, process_init_constructor): Treat vectors + like arrays. + +2002-02-11 Jason Merrill <jason@redhat.com> + + * parse.y (reserved_declspecs): Don't handle attributes. + (reserved_typespecquals): Handle them here. + * Make-lang.in (parse.c): Adjust expected conflicts. + +2002-02-08 Jakub Jelinek <jakub@redhat.com> + + * parse.y (primary, primary_no_id): Use compstmt_or_stmtexpr + instead of compstmt. + (compstmt_or_stmtexpr): Renamed from compstmt. + (compstmt): In addition to compstmt_or_stmtexpr clear last_expr_type. + +2002-02-07 Nathan Sidwell <nathan@codesourcery.com> + + Rename instantiate_type_flags to tsubst_flags_t & expand use. + * cp-tree.h (instantiate_type_flags): Rename to ... + (tsubst_flags_t): ... here. Rename itf_complain to tf_error, + add tf_warning flag. + (instantiate_type): Adjust prototype. + (tsubst, tsubst_expr, tsubst_copy, lookup_template_class, + do_type_instantiation, cp_build_qualified_type_real): Likewise. + cp_build_qualified_type: Adjust. + * class.c (instantiate_type): Adjust parameter. Rename itf_* to + tf_*. + * call.c (standard_conversion): Rename itf_* to tf_*. + (reference_binding): Likewise. + (convert_like_real): Likewise. + * cvt.c (cp_convert_to_pointer): Likewise. + (convert_to_reference): Likewise. + * decl.c (lookup_namespace_name): Use tf_* flags. + (make_typename_type): Likewise. + (grokdeclarator): Likewise. + * pt.c (convert_nontype_argument): Adjust COMPLAIN usage. + (coerce_template_template_parms, convert_template_argument, + coerce_template_parms, maybe_get_template_decl_from_type_decl, + lookup_template_class, tsubst_friend_function, tsubst_friend_class, + instantiate_class_template, tsubst_template_arg_vector, + tsubst_template_parms, tsubst_aggr_type, tsubst_default_argument, + tsubst_decl, tsubst_arg_types, tsubst_function_type, + tsubst_call_declarator_parms, tsubst, tsubst_copy, tsubst_expr, + instantiate_template, fn_type_unification, + resolve_overloaded_unification, verify_class_unification, + unify, get_bindings_real, do_type_instantiation, + regenerate_decl_from_template, instantiate_decl, + tsubst_initializer_list, tsubst_enum, + get_mostly_instantiated_function_type, + invalid_nontype_parm_type_p): Likewise. + * tree.c (cp_build_qualified_type_real): Likewise. + * typeck.c (build_binary_op): Rename itf_* to tf_*. + (build_ptrmemfunc): Likewise. + (convert_for_assignment): Likewise. + +2002-02-07 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/109 + * decl.c (grokdeclarator): Allow friend declarations from + dependent types. + * decl2.c (handle_class_head): Don't push into template parm contexts. + * pt.c (push_template_decl_real): Template parm contexts are never + being defined. + +2002-02-05 Alexandre Oliva <aoliva@redhat.com> + + * class.c: Include target.h. + (check_bitfield_decl): Disregard EMPTY_FIELD_BOUNDARY, + BITFIELDS_NBYTES_LIMITED and PCC_BITFIELD_TYPE_MATTERS for MS + bit-field layout. + * Make-lang.in: Adjust deps. + +2002-02-05 Jason Merrill <jason@redhat.com> + + * error.c (dump_type): Be more helpful about VECTOR_TYPE. + +2002-02-04 Jakub Jelinek <jakub@redhat.com> + + * semantics.c (begin_switch_stmt): Clear SWITCH_TYPE. + (finish_switch_cond): Set SWITCH_TYPE. + +2002-02-04 Richard Henderson <rth@redhat.com> + + * method.c (use_thunk): Always initialize the block tree. Reindent. + * semantics.c (expand_body): Emit thunks after function, not before. + +2002-02-04 Jason Merrill <jason@redhat.com> + + * decl.c (start_function): Call cplus_decl_attributes immediately + after grokdeclarator. + + * decl.c (start_function): Combine DECL_RESULT handling code. + +2002-02-03 Jason Merrill <jason@redhat.com> + + * xref.c: Remove. + * Make-lang.in (CXX_OBJS): Remove cp/xref.o + (cp/xref.o): Remove dependencies. + * class.c (finish_struct_1, check_methods): Don't call xref fns. + (finish_struct_1): Likewise. + * friend.c (make_friend_class): Likewise. + * lex.c (cxx_init, cxx_finish, extract_interface_info): Likewise. + * spew.c (read_process_identifier): Likewise. + 2002-02-01 Jason Merrill <jason@redhat.com> + PR c++/4872 + * decl.c (finish_function): Warn about a non-void function with + no return statement and no abnormal exit. + * cp-tree.h (struct cp_language_function): Add returns_abnormally. + (current_function_returns_abnormally): New macro. + * call.c (build_call): Set it. + + * typeck.c (build_component_ref): Always complain about offsetof + constructs on non-PODs. Only make it an error for members of + virtual bases. + * error.c (dump_scope): Don't add TFF_DECL_SPECIFIERS. (dump_function_decl): Always dump parms. @@ -1496,8 +2200,8 @@ Fri Sep 21 08:16:19 2001 J"orn Rennecke <amylaar@redhat.com> 2001-09-15 Gabriel Dos Reis <gdr@merlin.codesourcery.com> - * Make-lang.in (cp/error.o): Depend on real.h - * error.c: #include "real.h" + * Make-lang.in (cp/error.o): Depend on real.h + * error.c: #include "real.h" 2001-09-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> diff --git a/contrib/gcc/cp/Make-lang.in b/contrib/gcc/cp/Make-lang.in index 895b410..de4a372 100644 --- a/contrib/gcc/cp/Make-lang.in +++ b/contrib/gcc/cp/Make-lang.in @@ -102,7 +102,7 @@ CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \ CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \ cp/class.o cp/decl2.o cp/error.o cp/lex.o cp/parse.o cp/ptree.o cp/rtti.o \ cp/spew.o cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \ - cp/search.o cp/semantics.o cp/tree.o cp/xref.o cp/repo.o cp/dump.o \ + cp/search.o cp/semantics.o cp/tree.o cp/repo.o cp/dump.o \ cp/optimize.o cp/mangle.o cp/cp-lang.o # Use loose warnings for this front end. @@ -120,7 +120,7 @@ $(srcdir)/cp/cfns.h: $(srcdir)/cp/cfns.gperf $(srcdir)/cp/parse.h: $(srcdir)/cp/parse.c $(srcdir)/cp/parse.c: $(srcdir)/cp/parse.y - @echo "Expect 31 shift/reduce conflicts and 58 reduce/reduce conflicts." + @echo "Expect 33 shift/reduce conflicts and 58 reduce/reduce conflicts." cd $(srcdir)/cp && \ if $(BISON) $(BISONFLAGS) -d -o p$$$$.c parse.y; then \ grep '^#define[ ]*YYEMPTY' p$$$$.c >> p$$$$.h ; \ @@ -255,14 +255,14 @@ 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 + 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) +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) @@ -280,7 +280,6 @@ 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/xref.o: cp/xref.c $(CXX_TREE_H) input.h toplev.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 diff --git a/contrib/gcc/cp/NEWS b/contrib/gcc/cp/NEWS index a55b484..caee3fb 100644 --- a/contrib/gcc/cp/NEWS +++ b/contrib/gcc/cp/NEWS @@ -4,6 +4,10 @@ a workaround to allow std compliant code to work with the non-std compliant libstdc++-v2. libstdc++-v3 is std compliant. +* The C++ ABI has been fixed so that `void (A::*)() const' is mangled as + "M1AKFvvE", rather than "MK1AFvvE" as before. This change only affects + pointer to cv-qualified member function types. + * The C++ ABI has been changed to correctly handle this code: struct A { @@ -42,7 +46,22 @@ * The C++ ABI has been changed so that when a parameter is passed by value, any cleanup for that parameter is performed in the caller, as specified - by the ia64 C++ ABI, rather than the called function as before. + by the ia64 C++ ABI, rather than the called function as before. As a + result, classes with a non-trivial destructor but a trivial copy + constructor will be passed and returned by invisible reference, rather + than by bitwise copy as before. + +* G++ now supports the "named return value optimization": for code like + + A f () { + A a; + ... + return a; + } + + G++ will allocate 'a' in the return value slot, so that the return + becomes a no-op. For this to work, all return statements in the function + must return the same variable. *** Changes in GCC 3.0: diff --git a/contrib/gcc/cp/call.c b/contrib/gcc/cp/call.c index cf6f0b4..5527066 100644 --- a/contrib/gcc/cp/call.c +++ b/contrib/gcc/cp/call.c @@ -408,6 +408,9 @@ build_call (function, parms) nothrow = ((decl && TREE_NOTHROW (decl)) || TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (function)))); + if (decl && TREE_THIS_VOLATILE (decl)) + current_function_returns_abnormally = 1; + if (decl && TREE_DEPRECATED (decl)) warn_deprecated_use (decl); @@ -702,7 +705,7 @@ standard_conversion (to, from, expr) if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to)) && expr && type_unknown_p (expr)) { - expr = instantiate_type (to, expr, itf_none); + expr = instantiate_type (to, expr, tf_none); if (expr == error_mark_node) return NULL_TREE; from = TREE_TYPE (expr); @@ -792,9 +795,8 @@ standard_conversion (to, from, expr) { tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from)); tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to)); - tree binfo = lookup_base (tbase, fbase, ba_check, NULL); - if (binfo && !binfo_from_vbase (binfo) + if (DERIVED_FROM_P (fbase, tbase) && (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (TREE_TYPE (from)), TREE_TYPE (TREE_TYPE (to))))) @@ -840,9 +842,8 @@ standard_conversion (to, from, expr) tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to)); tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn))); tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn))); - tree binfo = lookup_base (tbase, fbase, ba_check, NULL); - if (!binfo || binfo_from_vbase (binfo) + if (!DERIVED_FROM_P (fbase, tbase) || !same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn)) || !compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)), TREE_CHAIN (TYPE_ARG_TYPES (tofn))) @@ -1105,7 +1106,7 @@ reference_binding (rto, rfrom, expr, flags) if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr)) { - expr = instantiate_type (to, expr, itf_none); + expr = instantiate_type (to, expr, tf_none); if (expr == error_mark_node) return NULL_TREE; from = TREE_TYPE (expr); @@ -2237,6 +2238,36 @@ add_template_candidate_real (candidates, tmpl, ctype, explicit_targs, if (fn == error_mark_node) return candidates; + /* In [class.copy]: + + A member function template is never instantiated to perform the + copy of a class object to an object of its class type. + + It's a little unclear what this means; the standard explicitly + does allow a template to be used to copy a class. For example, + in: + + struct A { + A(A&); + template <class T> A(const T&); + }; + const A f (); + void g () { A a (f ()); } + + the member template will be used to make the copy. The section + quoted above appears in the paragraph that forbids constructors + whose only parameter is (a possibly cv-qualified variant of) the + class type, and a logical interpretation is that the intent was + to forbid the instantiation of member templates which would then + have that form. */ + if (DECL_CONSTRUCTOR_P (fn) && list_length (arglist) == 2) + { + 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); @@ -3577,8 +3608,7 @@ builtin: match with the placement new is accepted. CODE is either DELETE_EXPR or VEC_DELETE_EXPR. - ADDR is the pointer to be deleted. For placement delete, it is also - used to determine what the corresponding new looked like. + ADDR is the pointer to be deleted. SIZE is the size of the memory block to be deleted. FLAGS are the usual overloading flags. PLACEMENT is the corresponding placement new call, or NULL_TREE. */ @@ -3623,15 +3653,22 @@ build_op_delete_call (code, addr, size, flags, placement) if (placement) { - /* placement is a CALL_EXPR around an ADDR_EXPR around a function. */ + 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. */ - argtypes = TREE_OPERAND (TREE_OPERAND (placement, 0), 0); + alloc_fn = get_callee_fndecl (call_expr); + my_friendly_assert (alloc_fn != NULL_TREE, 20020327); /* Then the second parm type. */ - argtypes = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (argtypes))); - + argtypes = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (alloc_fn))); /* Also the second argument. */ - args = TREE_CHAIN (TREE_OPERAND (placement, 1)); + args = TREE_CHAIN (TREE_OPERAND (call_expr, 1)); } else { @@ -3861,7 +3898,7 @@ convert_like_real (convs, expr, fn, argnum, inner) } case IDENTITY_CONV: if (type_unknown_p (expr)) - expr = instantiate_type (totype, expr, itf_complain); + expr = instantiate_type (totype, expr, tf_error | tf_warning); return expr; case AMBIG_CONV: /* Call build_user_type_conversion again for the error. */ @@ -4268,7 +4305,8 @@ build_over_call (cand, args, flags) 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))) + && !(is_empty_class (DECL_CONTEXT (fn)) + && TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))) { tree address; tree to = stabilize_reference @@ -4304,6 +4342,7 @@ build_over_call (cand, args, flags) 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); diff --git a/contrib/gcc/cp/class.c b/contrib/gcc/cp/class.c index aa83b8d..82360b0 100644 --- a/contrib/gcc/cp/class.c +++ b/contrib/gcc/cp/class.c @@ -33,6 +33,7 @@ Boston, MA 02111-1307, USA. */ #include "toplev.h" #include "ggc.h" #include "lex.h" +#include "target.h" #include "obstack.h" #define obstack_chunk_alloc xmalloc @@ -289,12 +290,9 @@ build_base_path (code, expr, binfo, nonnull) } fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); - if (fixed_type_p < 0) - /* Virtual base layout is not fixed, even in ctors and dtors. */ - fixed_type_p = 0; - if (!fixed_type_p && TREE_SIDE_EFFECTS (expr)) + 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) @@ -302,7 +300,7 @@ build_base_path (code, expr, binfo, nonnull) offset = BINFO_OFFSET (binfo); - if (v_binfo && !fixed_type_p) + if (v_binfo && fixed_type_p <= 0) { /* Going via virtual base V_BINFO. We need the static offset from V_BINFO to BINFO, and the dynamic offset from D_BINFO to @@ -323,7 +321,17 @@ build_base_path (code, expr, binfo, nonnull) size_diffop (offset, BINFO_OFFSET (v_binfo))); if (!integer_zerop (offset)) - offset = build (code, ptrdiff_type_node, v_offset, offset); + v_offset = build (code, ptrdiff_type_node, v_offset, offset); + + if (fixed_type_p < 0) + /* Negative fixed_type_p means this is a constructor or destructor; + virtual base layout is fixed in in-charge [cd]tors, but not in + base [cd]tors. */ + offset = build (COND_EXPR, ptrdiff_type_node, + build (EQ_EXPR, boolean_type_node, + current_in_charge_parm, integer_zero_node), + v_offset, + BINFO_OFFSET (binfo)); else offset = v_offset; } @@ -350,7 +358,7 @@ build_base_path (code, expr, binfo, nonnull) expr = build (COND_EXPR, target_type, null_test, build1 (NOP_EXPR, target_type, integer_zero_node), expr); - + return expr; } @@ -1842,17 +1850,11 @@ finish_struct_bits (t) } } - /* If this type has a copy constructor, force its mode to be BLKmode, and - force its TREE_ADDRESSABLE bit to be nonzero. This will cause it to - be passed by invisible reference and prevent it from being returned in - a register. - - Also do this if the class has BLKmode but can still be returned in - registers, since function_cannot_inline_p won't let us inline - functions returning such a type. This affects the HP-PA. */ - if (! TYPE_HAS_TRIVIAL_INIT_REF (t) - || (TYPE_MODE (t) == BLKmode && ! aggregate_value_p (t) - && CLASSTYPE_NON_AGGREGATE (t))) + /* If this type has a copy constructor or a destructor, force its mode to + be BLKmode, and force its TREE_ADDRESSABLE bit to be nonzero. This + will cause it to be passed by invisible reference and prevent it from + being returned in a register. */ + if (! TYPE_HAS_TRIVIAL_INIT_REF (t) || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)) { tree variants; DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode; @@ -3106,7 +3108,8 @@ check_bitfield_decl (field) DECL_SIZE (field) = convert (bitsizetype, w); DECL_BIT_FIELD (field) = 1; - if (integer_zerop (w)) + if (integer_zerop (w) + && ! (* targetm.ms_bitfield_layout_p) (DECL_FIELD_CONTEXT (field))) { #ifdef EMPTY_FIELD_BOUNDARY DECL_ALIGN (field) = MAX (DECL_ALIGN (field), @@ -3284,8 +3287,6 @@ check_field_decls (t, access_decls, empty_p, tree x = *field; tree type = TREE_TYPE (x); - GNU_xref_member (current_class_name, x); - next = &TREE_CHAIN (x); if (TREE_CODE (x) == FIELD_DECL) @@ -3925,8 +3926,6 @@ check_methods (t) for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) { - GNU_xref_member (current_class_name, x); - /* If this was an evil function, don't keep it in class. */ if (DECL_ASSEMBLER_NAME_SET_P (x) && IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (x))) @@ -4607,8 +4606,7 @@ layout_virtual_bases (t, offsets) tree t; splay_tree offsets; { - tree vbases; - unsigned HOST_WIDE_INT dsize; + tree vbases, dsize; unsigned HOST_WIDE_INT eoc; if (CLASSTYPE_N_BASECLASSES (t) == 0) @@ -4621,7 +4619,7 @@ layout_virtual_bases (t, offsets) #endif /* DSIZE is the size of the class without the virtual bases. */ - dsize = tree_low_cst (TYPE_SIZE (t), 1); + dsize = TYPE_SIZE (t); /* Make every class have alignment of at least one. */ TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), BITS_PER_UNIT); @@ -4643,7 +4641,7 @@ layout_virtual_bases (t, offsets) { /* This virtual base is not a primary base of any class in the hierarchy, so we have to add space for it. */ - tree basetype; + tree basetype, usize; unsigned int desired_align; basetype = BINFO_TYPE (vbase); @@ -4653,19 +4651,21 @@ layout_virtual_bases (t, offsets) /* Add padding so that we can put the virtual base class at an appropriately aligned offset. */ - dsize = CEIL (dsize, desired_align) * desired_align; + 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, - size_int (CEIL (dsize, BITS_PER_UNIT)), + convert (sizetype, usize), offsets, t); else { tree offset; - offset = ssize_int (CEIL (dsize, BITS_PER_UNIT)); + offset = convert (ssizetype, usize); offset = size_diffop (offset, convert (ssizetype, BINFO_OFFSET (vbase))); @@ -4675,8 +4675,9 @@ layout_virtual_bases (t, offsets) /* Every virtual baseclass takes a least a UNIT, so that we can take it's address and get something different for each base. */ - dsize += MAX (BITS_PER_UNIT, - tree_low_cst (CLASSTYPE_SIZE (basetype), 0)); + dsize = size_binop (PLUS_EXPR, dsize, + size_binop (MAX_EXPR, bitsize_unit_node, + CLASSTYPE_SIZE (basetype))); } /* Keep track of the offsets assigned to this virtual base. */ @@ -4698,13 +4699,12 @@ layout_virtual_bases (t, offsets) 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); - if (eoc * BITS_PER_UNIT > dsize) - dsize = eoc * BITS_PER_UNIT; + 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 = CEIL (dsize, TYPE_ALIGN (t)) * TYPE_ALIGN (t); - TYPE_SIZE (t) = bitsize_int (dsize); + 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)); @@ -4863,6 +4863,18 @@ layout_class_type (t, empty_p, vfuns_p, if (TREE_CODE (field) != FIELD_DECL) { place_field (rli, field); + /* If the static data member has incomplete type, keep track + of it so that it can be completed later. (The handling + of pending statics in finish_record_layout is + insufficient; consider: + + struct S1; + struct S2 { static S1 s1; }; + + At this point, finish_record_layout will be called, but + S1 is still incomplete.) */ + if (TREE_CODE (field) == VAR_DECL) + maybe_register_incomplete_var (field); continue; } @@ -5049,8 +5061,6 @@ finish_struct_1 (t) return; } - GNU_xref_decl (current_function_decl, t); - /* If this type was previously laid out as a forward reference, make sure we lay it out again. */ TYPE_SIZE (t) = NULL_TREE; @@ -5158,7 +5168,7 @@ finish_struct_1 (t) working on. */ for (x = TYPE_FIELDS (t); x; x = TREE_CHAIN (x)) if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x) - && TREE_TYPE (x) == t) + && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t)) DECL_MODE (x) = TYPE_MODE (t); /* Done with FIELDS...now decide whether to sort these for @@ -5207,7 +5217,7 @@ finish_struct_1 (t) && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1)) == NULL_TREE) warning ("`%#T' has virtual functions but non-virtual destructor", t); - hack_incomplete_structures (t); + complete_vars (t); if (warn_overloaded_virtual) warn_hidden (t); @@ -6047,14 +6057,14 @@ cannot resolve overloaded function `%D' based on conversion to type `%T'", tree instantiate_type (lhstype, rhs, flags) tree lhstype, rhs; - enum instantiate_type_flags flags; + tsubst_flags_t flags; { - int complain = (flags & itf_complain); - int strict = (flags & itf_no_attributes) + int complain = (flags & tf_error); + int strict = (flags & tf_no_attributes) ? COMPARE_NO_ATTRIBUTES : COMPARE_STRICT; - int allow_ptrmem = flags & itf_ptrmem_ok; + int allow_ptrmem = flags & tf_ptrmem_ok; - flags &= ~itf_ptrmem_ok; + flags &= ~tf_ptrmem_ok; if (TREE_CODE (lhstype) == UNKNOWN_TYPE) { @@ -6261,7 +6271,7 @@ instantiate_type (lhstype, rhs, flags) case ADDR_EXPR: { if (PTRMEM_OK_P (rhs)) - flags |= itf_ptrmem_ok; + flags |= tf_ptrmem_ok; return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags); } @@ -6299,7 +6309,8 @@ get_vfield_name (type) type = BINFO_TYPE (binfo); buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT) + TYPE_NAME_LENGTH (type) + 2); - sprintf (buf, VFIELD_NAME_FORMAT, TYPE_NAME_STRING (type)); + sprintf (buf, VFIELD_NAME_FORMAT, + IDENTIFIER_POINTER (constructor_name (type))); return get_identifier (buf); } diff --git a/contrib/gcc/cp/cp-tree.def b/contrib/gcc/cp/cp-tree.def index dbe990a..3854525 100644 --- a/contrib/gcc/cp/cp-tree.def +++ b/contrib/gcc/cp/cp-tree.def @@ -230,10 +230,6 @@ DEFTREECODE (SUBOBJECT, "subobject", 'e', 1) the cleanups associated with any SUBOBJECT_CLEANUPS need no longer be run. */ DEFTREECODE (CTOR_STMT, "ctor_stmt", 'e', 0) -/* A CLEANUP_STMT marks the point at which a declaration is fully - constructed. If, after this point, the CLEANUP_DECL goes out of - scope, the CLEANUP_EXPR must be run. */ -DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", 'e', 2) /* 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) diff --git a/contrib/gcc/cp/cp-tree.h b/contrib/gcc/cp/cp-tree.h index f7cddac..584491a 100644 --- a/contrib/gcc/cp/cp-tree.h +++ b/contrib/gcc/cp/cp-tree.h @@ -28,6 +28,10 @@ Boston, MA 02111-1307, USA. */ #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_?: @@ -318,8 +322,6 @@ typedef struct ptrmem_cst set_namespace_binding ((NODE), current_namespace, (VAL)) #define CLEANUP_P(NODE) TREE_LANG_FLAG_0 (TRY_BLOCK_CHECK (NODE)) -#define CLEANUP_DECL(NODE) TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 0) -#define CLEANUP_EXPR(NODE) TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 1) /* Returns nonzero iff TYPE1 and TYPE2 are the same type, in the usual sense of `same'. */ @@ -727,8 +729,8 @@ struct saved_scope tree x_previous_class_type; tree x_previous_class_values; tree x_saved_tree; - tree incomplete; tree lookups; + tree last_parms; HOST_WIDE_INT x_processing_template_decl; int x_processing_specialization; @@ -791,10 +793,6 @@ struct saved_scope #define previous_class_values scope_chain->x_previous_class_values -/* A list of the declarations with incomplete type at namespace scope. */ - -#define namespace_scope_incomplete scope_chain->incomplete - /* A list of private types mentioned, for deferred access checking. */ #define type_lookups scope_chain->lookups @@ -821,6 +819,7 @@ struct cp_language_function int returns_value; int returns_null; + int returns_abnormally; int in_function_try_handler; int x_expanding_p; @@ -883,6 +882,12 @@ struct cp_language_function #define current_function_returns_null cp_function_chain->returns_null +/* Set to 0 at beginning of a function definition, set to 1 if + a call to a noreturn function is seen. */ + +#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. */ @@ -925,10 +930,6 @@ extern int flag_no_gnu_keywords; extern int flag_operator_names; -/* For cross referencing. */ - -extern int flag_gnu_xref; - /* For environments where you can use GNU binutils (as, ld in particular). */ extern int flag_gnu_binutils; @@ -1583,11 +1584,11 @@ struct lang_type #define SET_BINFO_MARKED(NODE) \ (TREE_VIA_VIRTUAL(NODE) \ ? SET_CLASSTYPE_MARKED (BINFO_TYPE (NODE)) \ - : (TREE_LANG_FLAG_0 (NODE) = 1)) + : (void)(TREE_LANG_FLAG_0 (NODE) = 1)) #define CLEAR_BINFO_MARKED(NODE) \ (TREE_VIA_VIRTUAL (NODE) \ ? CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (NODE)) \ - : (TREE_LANG_FLAG_0 (NODE) = 0)) + : (void)(TREE_LANG_FLAG_0 (NODE) = 0)) /* Nonzero means that this class is on a path leading to a new vtable. */ #define BINFO_VTABLE_PATH_MARKED(NODE) \ @@ -1626,12 +1627,10 @@ struct lang_type #define SET_BINFO_PUSHDECLS_MARKED(NODE) SET_BINFO_VTABLE_PATH_MARKED (NODE) #define CLEAR_BINFO_PUSHDECLS_MARKED(NODE) CLEAR_BINFO_VTABLE_PATH_MARKED (NODE) -/* Nonzero if this BINFO is a primary base class. +/* Nonzero if this BINFO is a primary base class. Note, this can be + set for non-canononical virtual bases. For a virtual primary base + you might also need to check whether it is canonical. */ - In the TYPE_BINFO hierarchy, this flag is never set for a base - class of a non-primary virtual base. This flag is only valid for - paths (given by BINFO_INHERITANCE_CHAIN) that really exist in the - final object. */ #define BINFO_PRIMARY_P(NODE) \ (BINFO_PRIMARY_BASE_OF (NODE) != NULL_TREE) @@ -3060,13 +3059,19 @@ typedef enum linkage_kind { lk_external /* External linkage. */ } linkage_kind; -/* Bitmask flags to pass to instantiate_type. */ -typedef enum instantiate_type_flags { - itf_none = 0, /* nothing special */ - itf_complain = 1 << 0, /* complain about errors */ - itf_no_attributes = 1 << 1, /* ignore attributes on comparisons */ - itf_ptrmem_ok = 1 << 2, /* pointers to member ok (internal use) */ -} instantiate_type_flags; +/* Bitmask flags to control type substitution. */ +typedef enum tsubst_flags_t { + tf_none = 0, /* nothing special */ + tf_error = 1 << 0, /* give error messages */ + tf_warning = 1 << 1, /* give warnings too */ + tf_no_attributes = 1 << 2, /* ignore attributes on comparisons + (instantiate_type use) */ + 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 { @@ -3595,7 +3600,7 @@ extern void pop_nested_class PARAMS ((void)); extern int current_lang_depth PARAMS ((void)); extern void push_lang_context PARAMS ((tree)); extern void pop_lang_context PARAMS ((void)); -extern tree instantiate_type PARAMS ((tree, tree, enum instantiate_type_flags)); +extern tree instantiate_type PARAMS ((tree, tree, tsubst_flags_t)); extern void print_class_statistics PARAMS ((void)); extern void cxx_print_statistics PARAMS ((void)); extern void cxx_print_xnode PARAMS ((FILE *, tree, int)); @@ -3687,7 +3692,7 @@ 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, int)); +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)); @@ -3739,7 +3744,8 @@ extern void finish_function_body PARAMS ((tree)); extern tree finish_function PARAMS ((int)); extern tree start_method PARAMS ((tree, tree, tree)); extern tree finish_method PARAMS ((tree)); -extern void hack_incomplete_structures PARAMS ((tree)); +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)); @@ -3901,7 +3907,7 @@ 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 push_base_cleanups PARAMS ((void)); +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)); @@ -3969,9 +3975,9 @@ extern int maybe_clone_body PARAMS ((tree)); 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, int, tree)); -extern tree tsubst_expr PARAMS ((tree, tree, int, tree)); -extern tree tsubst_copy PARAMS ((tree, tree, int, tree)); +extern tree tsubst PARAMS ((tree, tree, tsubst_flags_t, tree)); +extern tree tsubst_expr PARAMS ((tree, tree, tsubst_flags_t, tree)); +extern tree tsubst_copy PARAMS ((tree, tree, tsubst_flags_t, tree)); extern void maybe_begin_member_template_processing PARAMS ((tree)); extern void maybe_end_member_template_processing PARAMS ((void)); extern tree finish_member_template_decl PARAMS ((tree)); @@ -3989,7 +3995,7 @@ extern tree current_template_args PARAMS ((void)); extern tree push_template_decl PARAMS ((tree)); extern tree push_template_decl_real PARAMS ((tree, int)); extern void redeclare_class_template PARAMS ((tree, tree)); -extern tree lookup_template_class PARAMS ((tree, tree, tree, tree, int, int)); +extern tree lookup_template_class PARAMS ((tree, tree, tree, tree, int, tsubst_flags_t)); extern tree lookup_template_function PARAMS ((tree, tree)); extern int uses_template_parms PARAMS ((tree)); extern tree instantiate_class_template PARAMS ((tree)); @@ -4000,7 +4006,7 @@ 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, int)); +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 ((tree)); @@ -4047,8 +4053,6 @@ extern int types_overlap_p PARAMS ((tree, tree)); extern tree get_vbase PARAMS ((tree, tree)); extern tree get_dynamic_cast_base_type PARAMS ((tree, tree)); extern void type_access_control PARAMS ((tree, tree)); -extern void skip_type_access_control PARAMS ((void)); -extern void reset_type_access_control PARAMS ((void)); extern int accessible_p PARAMS ((tree, tree)); extern tree lookup_field PARAMS ((tree, tree, int, int)); extern int lookup_fnfields_1 PARAMS ((tree, tree)); @@ -4084,8 +4088,6 @@ extern tree dfs_walk_real PARAMS ((tree, extern tree dfs_unmark PARAMS ((tree, void *)); extern tree markedp PARAMS ((tree, void *)); extern tree unmarkedp PARAMS ((tree, void *)); -extern tree dfs_skip_nonprimary_vbases_unmarkedp PARAMS ((tree, void *)); -extern tree dfs_skip_nonprimary_vbases_markedp PARAMS ((tree, void *)); extern tree dfs_unmarked_real_bases_queue_p PARAMS ((tree, void *)); extern tree dfs_marked_real_bases_queue_p PARAMS ((tree, void *)); extern tree dfs_skip_vbases PARAMS ((tree, void *)); @@ -4156,6 +4158,7 @@ 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)); @@ -4259,9 +4262,9 @@ 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, int)); +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), /*complain=*/1) + 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)); @@ -4340,6 +4343,7 @@ extern tree pfn_from_ptrmemfunc PARAMS ((tree)); extern tree type_after_usual_arithmetic_conversions PARAMS ((tree, tree)); extern tree composite_pointer_type PARAMS ((tree, tree, tree, tree, const char*)); +extern tree merge_types PARAMS ((tree, tree)); extern tree check_return_expr PARAMS ((tree)); #define cp_build_binary_op(code, arg1, arg2) \ build_binary_op(code, arg1, arg2, 1) @@ -4363,20 +4367,6 @@ extern void check_for_new_type PARAMS ((const char *, flagged_type_tree)); extern tree add_exception_specifier PARAMS ((tree, tree, int)); extern tree merge_exception_specifiers PARAMS ((tree, tree)); -/* in xref.c */ -extern void GNU_xref_begin PARAMS ((const char *)); -extern void GNU_xref_end PARAMS ((int)); -extern void GNU_xref_file PARAMS ((const char *)); -extern void GNU_xref_start_scope PARAMS ((HOST_WIDE_INT)); -extern void GNU_xref_end_scope PARAMS ((HOST_WIDE_INT, HOST_WIDE_INT, int, int)); -extern void GNU_xref_ref PARAMS ((tree, const char *)); -extern void GNU_xref_decl PARAMS ((tree, tree)); -extern void GNU_xref_call PARAMS ((tree, const char *)); -extern void GNU_xref_function PARAMS ((tree, tree)); -extern void GNU_xref_assign PARAMS ((tree)); -extern void GNU_xref_hier PARAMS ((tree, tree, int, int, int)); -extern void GNU_xref_member PARAMS ((tree, tree)); - /* in mangle.c */ extern void init_mangle PARAMS ((void)); extern void mangle_decl PARAMS ((tree)); diff --git a/contrib/gcc/cp/cvt.c b/contrib/gcc/cp/cvt.c index 6029e84..41cf21f 100644 --- a/contrib/gcc/cp/cvt.c +++ b/contrib/gcc/cp/cvt.c @@ -267,7 +267,7 @@ cp_convert_to_pointer (type, expr, force) } if (type_unknown_p (expr)) - return instantiate_type (type, expr, itf_complain); + return instantiate_type (type, expr, tf_error | tf_warning); error ("cannot convert `%E' from type `%T' to type `%T'", expr, intype, type); @@ -478,7 +478,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl) { expr = instantiate_type (type, expr, (flags & LOOKUP_COMPLAIN) - ? itf_complain : itf_none); + ? tf_error | tf_warning : tf_none); if (expr == error_mark_node) return error_mark_node; @@ -836,7 +836,7 @@ convert_to_void (expr, implicit) tree new_op1 = convert_to_void (op1, implicit); tree new_op2 = convert_to_void (op2, implicit); - expr = build (COND_EXPR, void_type_node, + expr = build (COND_EXPR, TREE_TYPE (new_op1), TREE_OPERAND (expr, 0), new_op1, new_op2); break; } @@ -852,6 +852,7 @@ convert_to_void (expr, implicit) tree t = build (COMPOUND_EXPR, TREE_TYPE (new_op1), TREE_OPERAND (expr, 0), new_op1); TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (expr); + TREE_NO_UNUSED_WARNING (t) = TREE_NO_UNUSED_WARNING (expr); expr = t; } diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c index a5d9c64..ebff32f 100644 --- a/contrib/gcc/cp/decl.c +++ b/contrib/gcc/cp/decl.c @@ -46,15 +46,11 @@ Boston, MA 02111-1307, USA. */ #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; -#ifndef BOOL_TYPE_SIZE -/* `bool' has size and alignment `1', on all platforms. */ -#define BOOL_TYPE_SIZE CHAR_TYPE_SIZE -#endif - static tree grokparms PARAMS ((tree)); static const char *redeclaration_error_message PARAMS ((tree, tree)); @@ -81,11 +77,14 @@ static tree grokfndecl PARAMS ((tree, tree, tree, tree, int, enum overload_flags, tree, tree, int, int, int, int, int, int, tree)); 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, @@ -395,10 +394,6 @@ struct binding_level /* The binding level which this one is contained in (inherits from). */ struct binding_level *level_chain; - /* List of decls in `names' that have incomplete - structure or union types. */ - tree incomplete; - /* List of VAR_DECLS saved from a previous for statement. These would be dead in ISO-conforming code, but might be referenced in ARM-era code. These are stored in a @@ -481,6 +476,12 @@ static struct binding_level *global_binding_level; static int keep_next_level_flag; +/* A TREE_LIST of VAR_DECLs. The TREE_PURPOSE is a RECORD_TYPE or + 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; @@ -842,7 +843,6 @@ pushlevel (tag_transparent) newlevel = make_binding_level (); push_binding_level (newlevel, tag_transparent, keep_next_level_flag); - GNU_xref_start_scope ((size_t) newlevel); keep_next_level_flag = 0; } @@ -1301,11 +1301,6 @@ poplevel (keep, reverse, functionbody) rather than the end. This hack is no longer used. */ my_friendly_assert (keep == 0 || keep == 1, 0); - GNU_xref_end_scope ((size_t) current_binding_level, - (size_t) current_binding_level->level_chain, - current_binding_level->parm_flag, - current_binding_level->keep); - if (current_binding_level->keep == 1) keep = 1; @@ -1727,11 +1722,6 @@ poplevel_class () shadowed = TREE_CHAIN (shadowed)) pop_binding (TREE_PURPOSE (shadowed), TREE_TYPE (shadowed)); - GNU_xref_end_scope ((size_t) class_binding_level, - (size_t) class_binding_level->level_chain, - class_binding_level->parm_flag, - class_binding_level->keep); - /* Now, pop out of the binding level which we created up in the `pushlevel_class' routine. */ #if defined(DEBUG_CP_BINDING_LEVELS) @@ -1965,7 +1955,6 @@ mark_binding_level (arg) ggc_mark_tree (lvl->shadowed_labels); ggc_mark_tree (lvl->blocks); ggc_mark_tree (lvl->this_class); - ggc_mark_tree (lvl->incomplete); ggc_mark_tree (lvl->dead_vars_from_for); } } @@ -2003,8 +1992,6 @@ print_binding_level (lvl) int i = 0, len; fprintf (stderr, " blocks="); fprintf (stderr, HOST_PTR_PRINTF, lvl->blocks); - fprintf (stderr, " n_incomplete=%d parm_flag=%d keep=%d", - list_length (lvl->incomplete), lvl->parm_flag, lvl->keep); if (lvl->tag_transparent) fprintf (stderr, " tag-transparent"); if (lvl->more_cleanups_ok) @@ -2405,7 +2392,6 @@ mark_saved_scope (arg) 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->incomplete); ggc_mark_tree (t->lookups); mark_stmt_tree (&t->x_stmt_tree); @@ -2511,6 +2497,7 @@ maybe_push_to_top_level (pseudo) s->bindings = b; s->need_pop_function_context = need_pop; s->function_decl = current_function_decl; + s->last_parms = last_function_parms; scope_chain = s; current_function_decl = NULL_TREE; @@ -2552,6 +2539,7 @@ pop_from_top_level () if (s->need_pop_function_context) pop_function_context_from (NULL_TREE); current_function_decl = s->function_decl; + last_function_parms = s->last_parms; free (s); } @@ -3153,6 +3141,10 @@ duplicate_decls (newdecl, olddecl) { if (TREE_CODE (newdecl) != FUNCTION_DECL) { + /* Avoid warnings redeclaring anticipated built-ins. */ + if (DECL_ANTICIPATED (olddecl)) + return 0; + /* If you declare a built-in or predefined function name as static, the old definition is overridden, but optionally warn this was a bad choice of name. */ @@ -3180,7 +3172,10 @@ duplicate_decls (newdecl, olddecl) } else if (!types_match) { - if ((DECL_EXTERN_C_P (newdecl) + /* Avoid warnings redeclaring anticipated built-ins. */ + if (DECL_ANTICIPATED (olddecl)) + ; /* Do nothing yet. */ + else if ((DECL_EXTERN_C_P (newdecl) && DECL_EXTERN_C_P (olddecl)) || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) @@ -3201,6 +3196,9 @@ duplicate_decls (newdecl, olddecl) else /* Discard the old built-in function. */ return 0; + + /* Replace the old RTL to avoid problems with inlining. */ + SET_DECL_RTL (olddecl, DECL_RTL (newdecl)); } if (DECL_THIS_STATIC (newdecl) && !DECL_THIS_STATIC (olddecl)) @@ -3215,9 +3213,6 @@ duplicate_decls (newdecl, olddecl) will be banished. */ SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl)); SET_DECL_RTL (olddecl, DECL_RTL (newdecl)); - COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl); - SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (newdecl), - newdecl); } } else if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) @@ -3355,6 +3350,7 @@ duplicate_decls (newdecl, olddecl) && namespace_bindings_p ()) ? "`%#D' previously defined here" : "`%#D' previously declared here", olddecl); + return 0; } else if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_INITIAL (olddecl) != NULL_TREE @@ -3400,13 +3396,10 @@ duplicate_decls (newdecl, olddecl) if (1 == simple_cst_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2))) { - if (pedantic) - { - pedwarn ("default argument given for parameter %d of `%#D'", - i, newdecl); - cp_pedwarn_at ("after previous specification in `%#D'", - olddecl); - } + pedwarn ("default argument given for parameter %d of `%#D'", + i, newdecl); + cp_pedwarn_at ("after previous specification in `%#D'", + olddecl); } else { @@ -3429,6 +3422,18 @@ duplicate_decls (newdecl, olddecl) } } + /* Do not merge an implicit typedef with an explicit one. In: + + class A; + ... + typedef class A A __attribute__ ((foo)); + + the attribute should apply only to the typedef. */ + if (TREE_CODE (olddecl) == TYPE_DECL + && (DECL_IMPLICIT_TYPEDEF_P (olddecl) + || DECL_IMPLICIT_TYPEDEF_P (newdecl))) + return 0; + /* If new decl is `static' and an `extern' was seen previously, warn about it. */ warn_extern_redeclared_static (newdecl, olddecl); @@ -3495,6 +3500,7 @@ duplicate_decls (newdecl, olddecl) except for any that we copy here from the old type. */ DECL_ATTRIBUTES (newdecl) = (*targetm.merge_decl_attributes) (olddecl, newdecl); + decl_attributes (&newdecl, DECL_ATTRIBUTES (newdecl), 0); if (TREE_CODE (newdecl) == TEMPLATE_DECL) { @@ -3526,16 +3532,16 @@ duplicate_decls (newdecl, olddecl) tree newtype; /* Merge the data types specified in the two decls. */ - newtype = common_type (TREE_TYPE (newdecl), TREE_TYPE (olddecl)); + newtype = merge_types (TREE_TYPE (newdecl), TREE_TYPE (olddecl)); - /* If common_type produces a non-typedef type, just use the old type. */ + /* If merge_types produces a non-typedef type, just use the old type. */ if (TREE_CODE (newdecl) == TYPE_DECL && newtype == DECL_ORIGINAL_TYPE (newdecl)) newtype = oldtype; if (TREE_CODE (newdecl) == VAR_DECL) DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl); - /* Do this after calling `common_type' so that default + /* Do this after calling `merge_types' so that default parameters don't confuse us. */ else if (TREE_CODE (newdecl) == FUNCTION_DECL && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (newdecl)) @@ -3599,15 +3605,23 @@ duplicate_decls (newdecl, olddecl) if (DECL_SECTION_NAME (newdecl) == NULL_TREE) DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl); - /* Keep the old rtl since we can safely use it. */ - COPY_DECL_RTL (olddecl, newdecl); - if (TREE_CODE (newdecl) == FUNCTION_DECL) { DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl) |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl); DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl); + /* Keep the old RTL. */ + COPY_DECL_RTL (olddecl, newdecl); + } + else if (TREE_CODE (newdecl) == VAR_DECL + && (DECL_SIZE (olddecl) || !DECL_SIZE (newdecl))) + { + /* Keep the old RTL. We cannot keep the old RTL if the old + declaration was for an incomplete object and the new + declaration is not since many attributes of the RTL will + change. */ + COPY_DECL_RTL (olddecl, newdecl); } } /* If cannot merge, then use the new type and qualifiers, @@ -3626,7 +3640,8 @@ duplicate_decls (newdecl, olddecl) } /* Merge the storage class information. */ - DECL_WEAK (newdecl) |= DECL_WEAK (olddecl); + merge_weak (newdecl, olddecl); + DECL_ONE_ONLY (newdecl) |= DECL_ONE_ONLY (olddecl); DECL_DEFER_OUTPUT (newdecl) |= DECL_DEFER_OUTPUT (olddecl); TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl); @@ -4242,22 +4257,8 @@ pushdecl (x) if (TREE_CODE (x) == FUNCTION_DECL) check_default_args (x); - /* Keep count of variables in this level with incomplete type. */ - if (TREE_CODE (x) == VAR_DECL - && TREE_TYPE (x) != error_mark_node - && ((!COMPLETE_TYPE_P (TREE_TYPE (x)) - && PROMOTES_TO_AGGR_TYPE (TREE_TYPE (x), ARRAY_TYPE)) - /* RTTI TD entries are created while defining the type_info. */ - || (TYPE_LANG_SPECIFIC (TREE_TYPE (x)) - && TYPE_BEING_DEFINED (TREE_TYPE (x))))) - { - if (namespace_bindings_p ()) - namespace_scope_incomplete - = tree_cons (NULL_TREE, x, namespace_scope_incomplete); - else - current_binding_level->incomplete - = tree_cons (NULL_TREE, x, current_binding_level->incomplete); - } + if (TREE_CODE (x) == VAR_DECL) + maybe_register_incomplete_var (x); } if (need_new_binding) @@ -5301,6 +5302,47 @@ storetags (tags) current_binding_level->tags = tags; } +/* Return the type that should be used when TYPE's name is preceded + by a tag such as 'struct' or 'union', or null if the name cannot + be used in this way. + + For example, when processing the third line of: + + struct A; + typedef struct A A; + struct A; + + lookup of A will find the typedef. Given A's typedef, this function + will return the type associated with "struct A". For the tag to be + anything other than TYPE, TYPE must be a typedef whose original type + has the same name and context as TYPE itself. + + It is not valid for a typedef of an anonymous type to be used with + an explicit tag: + + typedef struct { ... } B; + struct B; + + Return null for this case. */ + +static tree +follow_tag_typedef (type) + tree type; +{ + tree original; + + original = original_type (type); + if (! TYPE_NAME (original)) + return NULL_TREE; + if (TYPE_IDENTIFIER (original) == TYPE_IDENTIFIER (type) + && (CP_DECL_CONTEXT (TYPE_NAME (original)) + == CP_DECL_CONTEXT (TYPE_NAME (type))) + && !(CLASS_TYPE_P (original) && TYPE_WAS_ANONYMOUS (original))) + return original; + else + return NULL_TREE; +} + /* Given NAME, an IDENTIFIER_NODE, return the structure (or union or enum) definition for that name. Searches binding levels from BINDING_LEVEL up to the global level. @@ -5352,18 +5394,23 @@ lookup_tag (form, name, binding_level, thislevel_only) else old = BINDING_TYPE (old); - /* If it has an original type, it is a typedef, and we - should not return it. */ - if (old && DECL_ORIGINAL_TYPE (TYPE_NAME (old))) - old = NULL_TREE; - if (old && TREE_CODE (old) != form - && !(form != ENUMERAL_TYPE && TREE_CODE (old) == TEMPLATE_DECL)) + if (old) { - error ("`%#D' redeclared as %C", old, form); - return NULL_TREE; + /* We've found something at this binding level. If it is + a typedef, extract the tag it refers to. Lookup fails + 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 (old) - return old; if (thislevel_only || tail == global_namespace) return NULL_TREE; } @@ -5373,14 +5420,12 @@ lookup_tag (form, name, binding_level, thislevel_only) if (TREE_PURPOSE (tail) == name) { enum tree_code code = TREE_CODE (TREE_VALUE (tail)); - /* Should tighten this up; it'll probably permit - UNION_TYPE and a struct template, for example. */ + if (code != form - && !(form != ENUMERAL_TYPE && code == TEMPLATE_DECL)) + && (form == ENUMERAL_TYPE || code == ENUMERAL_TYPE)) { /* Definition isn't the kind we were looking for. */ - error ("`%#D' redeclared as %C", TREE_VALUE (tail), - form); + error ("`%#D' redeclared as %C", TREE_VALUE (tail), form); return NULL_TREE; } return TREE_VALUE (tail); @@ -5502,7 +5547,7 @@ lookup_namespace_name (namespace, name) /*in_decl=*/NULL_TREE, /*context=*/NULL_TREE, /*entering_scope=*/0, - /*complain=*/1); + tf_error | tf_warning); else if (DECL_FUNCTION_TEMPLATE_P (val) || TREE_CODE (val) == OVERLOAD) val = lookup_template_function (val, @@ -5518,7 +5563,12 @@ lookup_namespace_name (namespace, name) /* If we have a single function from a using decl, pull it out. */ if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val)) val = OVL_FUNCTION (val); - return val; + + /* Ignore built-in functions that haven't been prototyped yet. */ + if (!val || !DECL_P(val) + || !DECL_LANG_SPECIFIC(val) + || !DECL_ANTICIPATED (val)) + return val; } error ("`%D' undeclared in namespace `%D'", name, namespace); @@ -5621,12 +5671,15 @@ build_typename_type (context, name, fullname, base_type) /* Resolve `typename CONTEXT::NAME'. Returns an appropriate type, unless an error occurs, in which case error_mark_node is returned. - If COMPLAIN zero, don't complain about any errors that occur. */ + If we locate a non-artificial TYPE_DECL and TF_KEEP_TYPE_DECL is + set, we return that, rather than the _TYPE it corresponds to, in + other cases we look through the type decl. If TF_ERROR is set, + complain about errors, otherwise be quiet. */ tree make_typename_type (context, name, complain) tree context, name; - int complain; + tsubst_flags_t complain; { tree fullname; @@ -5665,7 +5718,7 @@ make_typename_type (context, name, complain) { /* We can get here from typename_sub0 in the explicit_template_type expansion. Just fail. */ - if (complain) + if (complain & tf_error) error ("no class template named `%#T' in `%#T'", name, context); return error_mark_node; @@ -5681,7 +5734,7 @@ make_typename_type (context, name, complain) tmpl = lookup_field (context, name, 0, 0); if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl)) { - if (complain) + if (complain & tf_error) error ("no class template named `%#T' in `%#T'", name, context); return error_mark_node; @@ -5691,7 +5744,7 @@ make_typename_type (context, name, complain) TREE_OPERAND (fullname, 1), NULL_TREE, context, /*entering_scope=*/0, - /*complain=*/1); + tf_error | tf_warning); } else { @@ -5699,14 +5752,29 @@ make_typename_type (context, name, complain) if (!IS_AGGR_TYPE (context)) { - if (complain) + if (complain & tf_error) error ("no type named `%#T' in `%#T'", name, context); return error_mark_node; } t = lookup_field (context, name, 0, 1); if (t) - return TREE_TYPE (t); + { + if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl)) + t = TREE_TYPE (t); + if (IMPLICIT_TYPENAME_P (t)) + { + /* Lookup found an implicit typename that we had + injected into the current scope. Doing things + properly would have located the exact same type, + so there is no error here. We must remove the + implicitness so that we do not warn about it. */ + t = copy_node (t); + TREE_TYPE (t) = NULL_TREE; + } + + return t; + } } } @@ -5714,7 +5782,7 @@ make_typename_type (context, name, complain) there now or its never going to be. */ if (!uses_template_parms (context)) { - if (complain) + if (complain & tf_error) error ("no type named `%#T' in `%#T'", name, context); return error_mark_node; } @@ -5725,7 +5793,9 @@ make_typename_type (context, name, complain) /* Resolve `CONTEXT::template NAME'. Returns an appropriate type, unless an error occurs, in which case error_mark_node is returned. - If COMPLAIN zero, don't complain about any errors that occur. */ + If we locate a TYPE_DECL, we return that, rather than the _TYPE it + corresponds to. If COMPLAIN zero, don't complain about any errors + that occur. */ tree make_unbound_class_template (context, name, complain) @@ -5788,14 +5858,6 @@ select_decl (binding, flags) tree val; val = BINDING_VALUE (binding); - /* When we implicitly declare some builtin entity, we mark it - DECL_ANTICIPATED, so that we know to ignore it until it is - really declared. */ - if (val && DECL_P (val) - && DECL_LANG_SPECIFIC (val) - && DECL_ANTICIPATED (val)) - return NULL_TREE; - if (LOOKUP_NAMESPACES_ONLY (flags)) { /* We are not interested in types. */ @@ -5845,9 +5907,21 @@ unqualified_namespace_lookup (name, flags, spacesp) *spacesp = tree_cons (scope, NULL_TREE, *spacesp); val = binding_for_name (name, scope); - /* Initialize binding for this context. */ - BINDING_VALUE (b) = BINDING_VALUE (val); - BINDING_TYPE (b) = BINDING_TYPE (val); + /* 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; @@ -6437,12 +6511,6 @@ cxx_init_decl_processing () flag_inline_functions = 0; } - /* In C++, we never create builtin functions whose name does not - begin with `__'. Users should be using headers to get prototypes - in C++. It would be nice if we could warn when `-fbuiltin' is - used explicitly, but we do not have that information. */ - flag_no_builtin = 1; - /* Initially, C. */ current_lang_name = lang_name_c; @@ -6640,6 +6708,7 @@ cxx_init_decl_processing () 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 @@ -6707,10 +6776,9 @@ cp_make_fname_decl (id, type_dep) return decl; } -/* Entry point for the benefit of c_common_nodes_and_builtins. - - Make a definition for a builtin function named NAME and whose data type - is TYPE. TYPE should be a function type with argument types. +/* Make a definition for a builtin function named NAME in the current + namespace, whose data type is TYPE and whose context is CONTEXT. + TYPE should be a function type with argument types. CLASS and CODE tell later passes how to compile calls to this function. See tree.h for possible values. @@ -6718,10 +6786,11 @@ cp_make_fname_decl (id, type_dep) 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) +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; @@ -6729,19 +6798,13 @@ builtin_function (name, type, code, class, 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; - my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392); + /* The return builtins leave the current function. */ + if (code == BUILT_IN_RETURN || code == BUILT_IN_EH_RETURN) + TREE_THIS_VOLATILE (decl) = 1; - /* All builtins that don't begin with an `_' should go in the `std' - namespace. */ - if (name[0] != '_') - { - push_namespace (std_identifier); - DECL_CONTEXT (decl) = std_node; - } pushdecl (decl); - if (name[0] != '_') - pop_namespace (); /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME, we cannot change DECL_ASSEMBLER_NAME until we have installed this @@ -6761,6 +6824,39 @@ builtin_function (name, type, code, class, libname) return decl; } +/* Entry point for the benefit of c_common_nodes_and_builtins. + + Make a defintion for a builtin function named NAME and whose data type + is TYPE. TYPE should be a function type with argument types. This + function places the anticipated declaration in the global namespace + and additionally in the std namespace if appropriate. + + CLASS and CODE tell later passes how to compile calls to this function. + 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 function. Not called directly. */ @@ -7258,6 +7354,10 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) /* Set attributes here so if duplicate decl, will have proper attributes. */ cplus_decl_attributes (&decl, attributes, 0); + /* If #pragma weak was used, mark the decl weak now. */ + if (current_binding_level == global_binding_level) + maybe_apply_pragma_weak (decl); + if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl) && DECL_UNINLINABLE (decl) @@ -7390,7 +7490,7 @@ start_decl_1 (decl) if ((! processing_template_decl || ! uses_template_parms (type)) && !COMPLETE_TYPE_P (complete_type (type))) { - error ("aggregate `%#D' has incomplete type and cannot be initialized", + error ("aggregate `%#D' has incomplete type and cannot be defined", decl); /* Change the type so that assemble_variable will give DECL an rtl we can live with: (mem (const_int 0)). */ @@ -7868,8 +7968,9 @@ make_rtl_for_nonlocal_decl (decl, init, asmspec) && toplev && !TREE_PUBLIC (decl)) { - /* Fool with the linkage according to #pragma interface. */ - if (!interface_unknown) + /* Fool with the linkage of static consts according to #pragma + interface. */ + if (!interface_unknown && !TREE_PUBLIC (decl)) { TREE_PUBLIC (decl) = 1; DECL_EXTERNAL (decl) = interface_only; @@ -7877,6 +7978,9 @@ make_rtl_for_nonlocal_decl (decl, init, asmspec) defer_p = 1; } + /* Likewise for template instantiations. */ + else if (DECL_COMDAT (decl)) + defer_p = 1; /* If we're deferring the variable, we only need to make RTL if there's an ASMSPEC. Otherwise, we'll lazily create it later when @@ -8029,8 +8133,7 @@ destroy_local_var (decl) cleanup = maybe_build_cleanup (decl); /* Record the cleanup required for this declaration. */ - if (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node - && cleanup) + if (DECL_SIZE (decl) && cleanup) finish_decl_cleanup (decl, cleanup); } @@ -8064,8 +8167,10 @@ cp_finish_decl (decl, init, asmspec_tree, flags) } /* If a name was specified, get the string. */ + if (current_binding_level == global_binding_level) + asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree); if (asmspec_tree) - asmspec = TREE_STRING_POINTER (asmspec_tree); + asmspec = TREE_STRING_POINTER (asmspec_tree); if (init && TREE_CODE (init) == NAMESPACE_DECL) { @@ -8130,7 +8235,6 @@ cp_finish_decl (decl, init, asmspec_tree, flags) set_identifier_type_value (DECL_NAME (decl), type); CLASSTYPE_GOT_SEMICOLON (type) = 1; } - GNU_xref_decl (current_function_decl, decl); /* If we have installed this as the canonical typedef for this type, and that type has not been defined yet, delay emitting @@ -8171,8 +8275,6 @@ cp_finish_decl (decl, init, asmspec_tree, flags) init = check_initializer (decl, init); maybe_deduce_size_from_array_init (decl, init); - GNU_xref_decl (current_function_decl, decl); - /* Add this declaration to the statement-tree. This needs to happen after the call to check_initializer so that the DECL_STMT for a reference temp is added before the DECL_STMT for the reference itself. */ @@ -8506,7 +8608,9 @@ register_dtor_fn (decl) cleanup = build_unary_op (ADDR_EXPR, cleanup, 0); if (flag_use_cxa_atexit) { - args = tree_cons (NULL_TREE, get_dso_handle_node (), NULL_TREE); + args = tree_cons (NULL_TREE, + build_unary_op (ADDR_EXPR, get_dso_handle_node (), 0), + NULL_TREE); args = tree_cons (NULL_TREE, null_pointer_node, args); args = tree_cons (NULL_TREE, cleanup, args); } @@ -9617,15 +9721,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) tree spec; tree type = NULL_TREE; int longlong = 0; - int constp; - int restrictp; - int volatilep; int type_quals; int virtualp, explicitp, friendp, inlinep, staticp; int explicit_int = 0; int explicit_char = 0; int defaulted_int = 0; int extern_langp = 0; + tree dependant_name = NULL_TREE; tree typedef_decl = NULL_TREE; const char *name; @@ -9867,11 +9969,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) else if (TREE_CODE (cname) == TEMPLATE_TYPE_PARM || TREE_CODE (cname) == BOUND_TEMPLATE_TEMPLATE_PARM) { - error ("`%T::%D' is not a valid declarator", cname, - TREE_OPERAND (decl, 1)); - error (" perhaps you want `typename %T::%D' to make it a type", - cname, TREE_OPERAND (decl, 1)); - return void_type_node; + /* This might be declaring a member of a template + parm to be a friend. */ + ctype = cname; + dependant_name = TREE_OPERAND (decl, 1); } else if (ctype == NULL_TREE) ctype = cname; @@ -10083,7 +10184,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) } } } - /* C++ aggregate types. */ else if (TREE_CODE (id) == TYPE_DECL) { if (type) @@ -10093,6 +10193,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) { type = TREE_TYPE (id); TREE_VALUE (spec) = type; + typedef_decl = id; } goto found; } @@ -10107,10 +10208,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) else { type = TREE_TYPE (t); -#if 0 - /* See the code below that used this. */ - decl_attr = DECL_ATTRIBUTES (id); -#endif typedef_decl = t; } } @@ -10121,6 +10218,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) found: ; } +#if 0 + /* See the code below that used this. */ + if (typedef_decl) + decl_attr = DECL_ATTRIBUTES (typedef_decl); +#endif typedef_type = type; /* No type at all: default to `int', and set DEFAULTED_INT @@ -10167,7 +10269,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) type = integer_type_node; } - if (type && TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type)) + if (type && IMPLICIT_TYPENAME_P (type)) { /* The implicit typename extension is deprecated and will be removed. Warn about its use now. */ @@ -10324,26 +10426,24 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) type = build_complex_type (type); } - if (sfk == sfk_conversion - && (RIDBIT_SETP (RID_CONST, specbits) - || RIDBIT_SETP (RID_VOLATILE, specbits) - || RIDBIT_SETP (RID_RESTRICT, specbits))) + type_quals = TYPE_UNQUALIFIED; + if (RIDBIT_SETP (RID_CONST, specbits)) + type_quals |= TYPE_QUAL_CONST; + if (RIDBIT_SETP (RID_VOLATILE, specbits)) + type_quals |= TYPE_QUAL_VOLATILE; + if (RIDBIT_SETP (RID_RESTRICT, specbits)) + type_quals |= TYPE_QUAL_RESTRICT; + if (sfk == sfk_conversion && type_quals != TYPE_UNQUALIFIED) error ("qualifiers are not allowed on declaration of `operator %T'", ctor_return_type); - /* Set CONSTP if this declaration is `const', whether by - explicit specification or via a typedef. - Likewise for VOLATILEP. */ - - constp = !! RIDBIT_SETP (RID_CONST, specbits) + CP_TYPE_CONST_P (type); - restrictp = - !! RIDBIT_SETP (RID_RESTRICT, specbits) + CP_TYPE_RESTRICT_P (type); - volatilep = - !! RIDBIT_SETP (RID_VOLATILE, specbits) + CP_TYPE_VOLATILE_P (type); - type_quals = ((constp ? TYPE_QUAL_CONST : 0) - | (restrictp ? TYPE_QUAL_RESTRICT : 0) - | (volatilep ? TYPE_QUAL_VOLATILE : 0)); - type = cp_build_qualified_type (type, type_quals); + type_quals |= cp_type_quals (type); + type = cp_build_qualified_type_real + (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl) + ? tf_ignore_bad_quals : 0) | tf_error | tf_warning)); + /* We might have ignored or rejected some of the qualifiers. */ + type_quals = cp_type_quals (type); + staticp = 0; inlinep = !! RIDBIT_SETP (RID_INLINE, specbits); virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits); @@ -10363,6 +10463,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) friendp = RIDBIT_SETP (RID_FRIEND, specbits); RIDBIT_RESET (RID_FRIEND, specbits); + if (dependant_name && !friendp) + { + error ("`%T::%D' is not a valid declarator", ctype, dependant_name); + return void_type_node; + } + /* Warn if two storage classes are given. Default to `auto'. */ if (RIDBIT_ANY_SET (specbits)) @@ -10830,21 +10936,30 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) { register tree typemodlist; int erred = 0; - - constp = 0; - volatilep = 0; - restrictp = 0; + int constp = 0; + int volatilep = 0; + int restrictp = 0; + for (typemodlist = TREE_TYPE (declarator); typemodlist; typemodlist = TREE_CHAIN (typemodlist)) { tree qualifier = TREE_VALUE (typemodlist); if (qualifier == ridpointers[(int) RID_CONST]) - constp++; + { + constp++; + type_quals |= TYPE_QUAL_CONST; + } else if (qualifier == ridpointers[(int) RID_VOLATILE]) - volatilep++; + { + volatilep++; + type_quals |= TYPE_QUAL_VOLATILE; + } else if (qualifier == ridpointers[(int) RID_RESTRICT]) - restrictp++; + { + restrictp++; + type_quals |= TYPE_QUAL_RESTRICT; + } else if (!erred) { erred = 1; @@ -10857,20 +10972,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) pedwarn ("duplicate `volatile'"); if (restrictp > 1) pedwarn ("duplicate `restrict'"); - - type_quals = ((constp ? TYPE_QUAL_CONST : 0) - | (restrictp ? TYPE_QUAL_RESTRICT : 0) - | (volatilep ? TYPE_QUAL_VOLATILE : 0)); - if (TREE_CODE (declarator) == ADDR_EXPR - && (constp || volatilep)) - { - if (constp) - pedwarn ("discarding `const' applied to a reference"); - if (volatilep) - pedwarn ("discarding `volatile' applied to a reference"); - type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); - } type = cp_build_qualified_type (type, type_quals); + type_quals = cp_type_quals (type); } declarator = TREE_OPERAND (declarator, 0); ctype = NULL_TREE; @@ -10914,7 +11017,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) && uses_template_parms (current_class_type)) { tree args = current_template_args (); - type = tsubst (type, args, /*complain=*/1, NULL_TREE); + type = tsubst (type, args, tf_error | tf_warning, + NULL_TREE); } /* This pop_nested_class corresponds to the @@ -11113,7 +11217,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) else if (type_quals & TYPE_QUAL_CONST) { error ("const `%s' cannot be declared `mutable'", name); - RIDBIT_RESET (RID_MUTABLE, specbits); + RIDBIT_RESET (RID_MUTABLE, specbits); } } @@ -11166,6 +11270,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) && TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && TYPE_ANONYMOUS_P (type) + /* Don't do this if there are attributes. */ + && (!attrlist || !*attrlist) && cp_type_quals (type) == TYPE_UNQUALIFIED) { tree oldname = TYPE_NAME (type); @@ -11224,16 +11330,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) /* Detect the case of an array type of unspecified size which came, as such, direct from a typedef name. - We must copy the type, so that each identifier gets - a distinct type, so that each identifier's size can be - controlled separately by its own initializer. */ + We must copy the type, so that the array's domain can be + individually set by the object's initializer. */ - if (type != 0 && typedef_type != 0 - && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0 + if (type && typedef_type + && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type) && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type)) - { - type = build_cplus_array_type (TREE_TYPE (type), TYPE_DOMAIN (type)); - } + type = build_cplus_array_type (TREE_TYPE (type), NULL_TREE); /* Detect where we're using a typedef of function type to declare a function. last_function_parms will not be set, so we must create @@ -11300,9 +11403,7 @@ friend declaration requires class-key, i.e. `friend %#T'", /* Only try to do this stuff if we didn't already give up. */ if (type != integer_type_node) { - /* DR 209. The friendly class does not need to be accessible - in the scope of the class granting friendship. */ - skip_type_access_control (); + decl_type_access_control (TYPE_NAME (type)); /* A friendly class? */ if (current_class_type) @@ -11564,33 +11665,32 @@ friend declaration requires class-key, i.e. `friend %#T'", if (friendp) { /* Friends are treated specially. */ - tree t = NULL_TREE; - - /* DR 209. The friend does not need to be accessible at this - point. */ - skip_type_access_control (); - if (ctype == current_class_type) warning ("member functions are implicitly friends of their class"); - - if (decl && DECL_NAME (decl)) - { - if (template_class_depth (current_class_type) == 0) - { - decl = check_explicit_specialization - (declarator, decl, - template_count, 2 * (funcdef_flag != 0) + 4); - if (decl == error_mark_node) - return error_mark_node; - } - - t = do_friend (ctype, declarator, decl, - last_function_parms, *attrlist, flags, quals, - funcdef_flag); - } - if (t && funcdef_flag) - return t; - return void_type_node; + else + { + tree t = NULL_TREE; + if (decl && DECL_NAME (decl)) + { + if (template_class_depth (current_class_type) == 0) + { + decl + = check_explicit_specialization + (declarator, decl, + template_count, 2 * (funcdef_flag != 0) + 4); + if (decl == error_mark_node) + return error_mark_node; + } + + t = do_friend (ctype, declarator, decl, + last_function_parms, *attrlist, + flags, quals, funcdef_flag); + } + if (t && funcdef_flag) + return t; + + return void_type_node; + } } /* Structure field. It may not be a function, except for C++ */ @@ -12589,10 +12689,12 @@ grok_op_properties (decl, friendp) /* Effective C++ rule 23. */ if (warn_ecpp && arity == 2 + && !DECL_ASSIGNMENT_OPERATOR_P (decl) && (operator_code == PLUS_EXPR || operator_code == MINUS_EXPR || operator_code == TRUNC_DIV_EXPR - || operator_code == MULT_EXPR) + || operator_code == MULT_EXPR + || operator_code == TRUNC_MOD_EXPR) && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == REFERENCE_TYPE) warning ("`%D' should return by value", decl); @@ -12654,7 +12756,6 @@ xref_tag (code_type_node, name, globalize) enum tree_code code; register tree ref, t; struct binding_level *b = current_binding_level; - int got_type = 0; tree attributes = NULL_TREE; tree context = NULL_TREE; @@ -12691,7 +12792,6 @@ xref_tag (code_type_node, name, globalize) { t = name; name = TYPE_IDENTIFIER (t); - got_type = 1; } else t = IDENTIFIER_TYPE_VALUE (name); @@ -12736,18 +12836,20 @@ xref_tag (code_type_node, name, globalize) { 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 (t != TYPE_MAIN_VARIANT (t) - || (CLASS_TYPE_P (t) && TYPE_WAS_ANONYMOUS (t))) - pedwarn ("using typedef-name `%D' after `%s'", - TYPE_NAME (t), tag_name (tag_code)); + 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)); - - ref = t; + t, tag_name (tag_code)); } else ref = lookup_tag (code, name, b, 0); @@ -12868,19 +12970,6 @@ xref_tag (code_type_node, name, globalize) redeclare_class_template (ref, current_template_parms); } - /* Until the type is defined, tentatively accept whatever - structure tag the user hands us. */ - if (!COMPLETE_TYPE_P (ref) - && ref != current_class_type - /* Have to check this, in case we have contradictory tag info. */ - && IS_AGGR_TYPE_CODE (TREE_CODE (ref))) - { - if (tag_code == class_type) - CLASSTYPE_DECLARED_CLASS (ref) = 1; - else if (tag_code == record_type) - CLASSTYPE_DECLARED_CLASS (ref) = 0; - } - TYPE_ATTRIBUTES (ref) = attributes; return ref; @@ -12914,7 +13003,8 @@ xref_tag_from_type (old, id, globalize) void xref_basetypes (code_type_node, name, ref, binfo) tree code_type_node; - tree name, ref; + tree name ATTRIBUTE_UNUSED; + tree ref; tree binfo; { /* In the declaration `A : X, Y, ... Z' we mark all the types @@ -12985,8 +13075,6 @@ xref_basetypes (code_type_node, name, ref, binfo) continue; } - GNU_xref_hier (name, basetype, via_public, via_virtual, 0); - /* This code replaces similar code in layout_basetypes. We put the complete_type first for implicit `typename'. */ if (!COMPLETE_TYPE_P (basetype) @@ -13124,10 +13212,6 @@ start_enum (name) pushtag (name, enumtype, 0); } - if (current_class_type) - TREE_ADDRESSABLE (b->tags) = 1; - - GNU_xref_decl (current_function_decl, enumtype); return enumtype; } @@ -13373,10 +13457,7 @@ build_enumerator (name, value, enumtype) things like `S::i' later.) */ finish_member_declaration (decl); else - { - pushdecl (decl); - GNU_xref_decl (current_function_decl, decl); - } + pushdecl (decl); /* Add this enumeration constant to the list for this type. */ TYPE_VALUES (enumtype) = tree_cons (name, decl, TYPE_VALUES (enumtype)); @@ -13500,7 +13581,14 @@ start_function (declspecs, declarator, attrs, flags) decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, NULL); /* If the declarator is not suitable for a function definition, cause a syntax error. */ - if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL) return 0; + if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL) + return 0; + + cplus_decl_attributes (&decl1, attrs, 0); + + /* If #pragma weak was used, mark the decl weak now. */ + if (current_binding_level == global_binding_level) + maybe_apply_pragma_weak (decl1); fntype = TREE_TYPE (decl1); @@ -13614,19 +13702,16 @@ start_function (declspecs, declarator, attrs, flags) /* Build the return declaration for the function. */ restype = TREE_TYPE (fntype); - if (!processing_template_decl) + /* Promote the value to int before returning it. */ + if (c_promoting_integer_type_p (restype)) + restype = type_promotes_to (restype); + if (DECL_RESULT (decl1) == NULL_TREE) { - if (!DECL_RESULT (decl1)) - { - DECL_RESULT (decl1) - = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (restype)); - c_apply_type_quals_to_decl (cp_type_quals (restype), - DECL_RESULT (decl1)); - } + DECL_RESULT (decl1) + = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (restype)); + c_apply_type_quals_to_decl (cp_type_quals (restype), + DECL_RESULT (decl1)); } - else - /* Just use `void'. Nobody will ever look at this anyhow. */ - DECL_RESULT (decl1) = build_decl (RESULT_DECL, 0, void_type_node); /* Initialize RTL machinery. We cannot do this until CURRENT_FUNCTION_DECL and DECL_RESULT are set up. We do this @@ -13787,20 +13872,6 @@ start_function (declspecs, declarator, attrs, flags) pushlevel (0); current_binding_level->parm_flag = 1; - cplus_decl_attributes (&decl1, attrs, 0); - - /* Promote the value to int before returning it. */ - if (c_promoting_integer_type_p (restype)) - restype = type_promotes_to (restype); - - if (DECL_RESULT (decl1) == NULL_TREE) - { - DECL_RESULT (decl1) - = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (restype)); - TREE_READONLY (DECL_RESULT (decl1)) = CP_TYPE_CONST_P (restype); - TREE_THIS_VOLATILE (DECL_RESULT (decl1)) = CP_TYPE_VOLATILE_P (restype); - } - ++function_depth; if (DECL_DESTRUCTOR_P (decl1)) @@ -14006,10 +14077,6 @@ begin_destructor_body () 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 @@ -14020,6 +14087,9 @@ finish_destructor_body () { tree exprstmt; + /* 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)) { @@ -14247,6 +14317,19 @@ finish_function (flags) if (!processing_template_decl && calls_setjmp_p (fndecl)) DECL_UNINLINABLE (fndecl) = 1; + /* Complain if there's just no return statement. */ + if (warn_return_type + && !processing_template_decl + && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE + && !current_function_returns_value && !current_function_returns_null + /* Don't complain if we abort or throw. */ + && !current_function_returns_abnormally + && !DECL_NAME (DECL_RESULT (fndecl)) + /* Normally, with -Wreturn-type, flow will complain. Unless we're an + inline function, as we might never be compiled separately. */ + && DECL_INLINE (fndecl)) + warning ("no return statement in function returning non-void"); + /* Clear out memory we no longer need. */ free_after_parsing (cfun); /* Since we never call rest_of_compilation, we never clear @@ -14407,11 +14490,6 @@ finish_method (decl) DECL_CONTEXT (link) = NULL_TREE; } - GNU_xref_end_scope ((size_t) current_binding_level, - (size_t) current_binding_level->level_chain, - current_binding_level->parm_flag, - current_binding_level->keep); - poplevel (0, 0, 0); DECL_INITIAL (fndecl) = old_initial; @@ -14429,72 +14507,58 @@ finish_method (decl) return decl; } -/* Called when a new struct TYPE is defined. - If this structure or union completes the type of any previous - variable declaration, lay it out and output its rtl. */ + +/* VAR is a VAR_DECL. If its type is incomplete, remember VAR so that + we can lay it out later, when and if its type becomes complete. */ void -hack_incomplete_structures (type) - tree type; +maybe_register_incomplete_var (var) + tree var; { - tree *list; - struct binding_level *level; + my_friendly_assert (TREE_CODE (var) == VAR_DECL, 20020406); - if (!type) /* Don't do this for class templates. */ - return; - - if (namespace_bindings_p ()) + /* Keep track of variables with incomplete types. */ + if (!processing_template_decl && TREE_TYPE (var) != error_mark_node + && DECL_EXTERNAL (var)) { - level = 0; - list = &namespace_scope_incomplete; - } - else - { - level = innermost_nonclass_level (); - list = &level->incomplete; + tree inner_type = TREE_TYPE (var); + + while (TREE_CODE (inner_type) == ARRAY_TYPE) + inner_type = TREE_TYPE (inner_type); + inner_type = TYPE_MAIN_VARIANT (inner_type); + + if ((!COMPLETE_TYPE_P (inner_type) && CLASS_TYPE_P (inner_type)) + /* RTTI TD entries are created while defining the type_info. */ + || (TYPE_LANG_SPECIFIC (inner_type) + && TYPE_BEING_DEFINED (inner_type))) + incomplete_vars = tree_cons (inner_type, var, incomplete_vars); } +} - while (1) - { - while (*list) - { - tree decl = TREE_VALUE (*list); - if ((decl && TREE_TYPE (decl) == type) - || (TREE_TYPE (decl) - && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE - && TREE_TYPE (TREE_TYPE (decl)) == type)) - { - int toplevel = toplevel_bindings_p (); - if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE - && TREE_TYPE (TREE_TYPE (decl)) == type) - layout_type (TREE_TYPE (decl)); - layout_decl (decl, 0); - rest_of_decl_compilation (decl, NULL, toplevel, 0); - if (! toplevel) - { - tree cleanup; - expand_decl (decl); - cleanup = maybe_build_cleanup (decl); - expand_decl_init (decl); - if (! expand_decl_cleanup (decl, cleanup)) - error ("parser lost in parsing declaration of `%D'", - decl); - } - *list = TREE_CHAIN (*list); - } - else - list = &TREE_CHAIN (*list); - } +/* Called when a class type (given by TYPE) is defined. If there are + any existing VAR_DECLs whose type hsa been completed by this + declaration, update them now. */ + +void +complete_vars (type) + tree type; +{ + tree *list = &incomplete_vars; - /* Keep looking through artificial binding levels generated - for local variables. */ - if (level && level->keep == 2) + my_friendly_assert (CLASS_TYPE_P (type), 20020406); + while (*list) + { + if (same_type_p (type, TREE_PURPOSE (*list))) { - level = level->level_chain; - list = &level->incomplete; + tree var = TREE_VALUE (*list); + /* Complete the type of the variable. The VAR_DECL itself + will be laid out in expand_expr. */ + complete_type (TREE_TYPE (var)); + /* Remove this entry from the list. */ + *list = TREE_CHAIN (*list); } else - break; + list = &TREE_CHAIN (*list); } } @@ -14535,7 +14599,7 @@ maybe_build_cleanup (decl) return rval; } - return 0; + return NULL_TREE; } /* When a stmt has been parsed, this function is called. */ diff --git a/contrib/gcc/cp/decl2.c b/contrib/gcc/cp/decl2.c index 9b1c355..c419d55 100644 --- a/contrib/gcc/cp/decl2.c +++ b/contrib/gcc/cp/decl2.c @@ -1153,21 +1153,8 @@ delete_sanity (exp, size, doing_vec, use_global_delete) return build_vec_delete (t, maxindex, sfk_deleting_destructor, use_global_delete); else - { - if (IS_AGGR_TYPE (TREE_TYPE (type)) - && TYPE_GETS_REG_DELETE (TREE_TYPE (type))) - { - /* Only do access checking here; we'll be calling op delete - from the destructor. */ - tree tmp = build_op_delete_call (DELETE_EXPR, t, size_zero_node, - LOOKUP_NORMAL, NULL_TREE); - if (tmp == error_mark_node) - return error_mark_node; - } - - return build_delete (type, t, sfk_deleting_destructor, - LOOKUP_NORMAL, use_global_delete); - } + return build_delete (type, t, sfk_deleting_destructor, + LOOKUP_NORMAL, use_global_delete); } /* Report an error if the indicated template declaration is not the @@ -1702,8 +1689,6 @@ grokbitfield (declarator, declspecs, width) return void_type_node; } - GNU_xref_member (current_class_name, value); - if (TREE_STATIC (value)) { error ("static member `%D' cannot be a bit-field", value); @@ -2223,8 +2208,12 @@ maybe_make_one_only (decl) make_decl_one_only (decl); - if (TREE_CODE (decl) == VAR_DECL && DECL_LANG_SPECIFIC (decl)) - DECL_COMDAT (decl) = 1; + if (TREE_CODE (decl) == VAR_DECL) + { + DECL_COMDAT (decl) = 1; + /* Mark it needed so we don't forget to emit it. */ + TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) = 1; + } } /* Returns the virtual function with which the vtable for TYPE is @@ -3452,7 +3441,11 @@ finish_file () 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. */ + 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); @@ -3461,6 +3454,11 @@ finish_file () && 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. @@ -4198,6 +4196,11 @@ ambiguous_decl (name, old, new, flags) if (LOOKUP_TYPES_ONLY (flags)) val = NULL_TREE; break; + case FUNCTION_DECL: + /* Ignore built-in functions that are still anticipated. */ + if (LOOKUP_QUALIFIERS_ONLY (flags) || DECL_ANTICIPATED (val)) + val = NULL_TREE; + break; default: if (LOOKUP_QUALIFIERS_ONLY (flags)) val = NULL_TREE; @@ -4950,6 +4953,15 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype) 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. */ @@ -5221,7 +5233,7 @@ handle_class_head (aggr, scope, id, defn_p, new_type_p) { /* According to the suggested resolution of core issue 180, 'typename' is assumed after a class-key. */ - decl = make_typename_type (scope, id, 1); + decl = make_typename_type (scope, id, tf_error); if (decl != error_mark_node) decl = TYPE_MAIN_DECL (decl); else @@ -5260,10 +5272,18 @@ handle_class_head (aggr, scope, id, defn_p, new_type_p) is different to the current scope. */ tree context = CP_DECL_CONTEXT (decl); - *new_type_p = current != context; + *new_type_p = (current != context + && TREE_CODE (context) != TEMPLATE_TYPE_PARM + && TREE_CODE (context) != BOUND_TEMPLATE_TEMPLATE_PARM); if (*new_type_p) 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); } diff --git a/contrib/gcc/cp/dump.c b/contrib/gcc/cp/dump.c index 98c1fc4..6dd60ba 100644 --- a/contrib/gcc/cp/dump.c +++ b/contrib/gcc/cp/dump.c @@ -1,5 +1,5 @@ /* Tree-dumping functionality for intermediate representation. - Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Written by Mark Mitchell <mark@codesourcery.com> This file is part of GNU CC. @@ -390,13 +390,6 @@ cp_dump_tree (dump_info, t) dump_child ("decl", TREE_OPERAND (t, 2)); break; - case CLEANUP_STMT: - dump_stmt (di, t); - dump_child ("decl", CLEANUP_DECL (t)); - dump_child ("expr", CLEANUP_EXPR (t)); - dump_next_stmt (di, t); - break; - case CTOR_STMT: dump_stmt (di, t); if (CTOR_BEGIN_P (t)) diff --git a/contrib/gcc/cp/error.c b/contrib/gcc/cp/error.c index 594d4e4..aa075ee 100644 --- a/contrib/gcc/cp/error.c +++ b/contrib/gcc/cp/error.c @@ -382,7 +382,14 @@ dump_type (t, flags) case VECTOR_TYPE: output_add_string (scratch_buffer, "vector "); - dump_type (TREE_TYPE (t), flags); + { + /* The subtype of a VECTOR_TYPE is something like intQI_type_node, + 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; case INTEGER_TYPE: @@ -452,7 +459,8 @@ dump_type (t, flags) break; } case TYPENAME_TYPE: - output_add_string (scratch_buffer, "typename "); + if (IMPLICIT_TYPENAME_P (t)) + output_add_string (scratch_buffer, "typename "); dump_typename (t, flags); break; @@ -1727,7 +1735,7 @@ dump_expr (t, flags) break; case CONVERT_EXPR: - if (VOID_TYPE_P (TREE_TYPE (t))) + if (TREE_TYPE (t) && VOID_TYPE_P (TREE_TYPE (t))) { print_left_paren (scratch_buffer); dump_type (TREE_TYPE (t), flags); diff --git a/contrib/gcc/cp/friend.c b/contrib/gcc/cp/friend.c index 1d96701..441be67 100644 --- a/contrib/gcc/cp/friend.c +++ b/contrib/gcc/cp/friend.c @@ -252,8 +252,6 @@ make_friend_class (type, friend_type) return; } - GNU_xref_hier (type, friend_type, 0, 0, 1); - if (is_template_friend) friend_type = CLASSTYPE_TI_TEMPLATE (friend_type); diff --git a/contrib/gcc/cp/g++spec.c b/contrib/gcc/cp/g++spec.c index fbbe599..c0e5c73 100644 --- a/contrib/gcc/cp/g++spec.c +++ b/contrib/gcc/cp/g++spec.c @@ -32,10 +32,16 @@ Boston, MA 02111-1307, USA. */ #ifndef MATH_LIBRARY #define MATH_LIBRARY "-lm" #endif +#ifndef MATH_LIBRARY_PROFILE +#define MATH_LIBRARY_PROFILE "-lm" +#endif #ifndef LIBSTDCXX #define LIBSTDCXX "-lstdc++" #endif +#ifndef LIBSTDCXX_PROFILE +#define LIBSTDCXX_PROFILE "-lstdc++" +#endif void lang_specific_driver (in_argc, in_argv, in_added_libraries) @@ -45,6 +51,9 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries) { 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; @@ -137,6 +146,8 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries) } else if (strcmp (argv[i], "-lc") == 0) args[i] |= WITHLIBC; + else if (strcmp (argv[i], "-pg") == 0 || strcmp (argv[i], "-p") == 0) + saw_profile_flag++; else if (strcmp (argv[i], "-v") == 0) { saw_verbose_flag = 1; @@ -259,14 +270,14 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries) /* Add `-lstdc++' if we haven't already done so. */ if (library) { - arglist[j++] = LIBSTDCXX; + arglist[j++] = saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX; added_libraries++; } if (saw_math) arglist[j++] = saw_math; else if (library && need_math) { - arglist[j++] = MATH_LIBRARY; + arglist[j++] = saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY; added_libraries++; } if (saw_libc) diff --git a/contrib/gcc/cp/init.c b/contrib/gcc/cp/init.c index 017b894..4cb0dab 100644 --- a/contrib/gcc/cp/init.c +++ b/contrib/gcc/cp/init.c @@ -97,10 +97,6 @@ begin_init_stmts (stmt_expr_p, compound_stmt_p) if (building_stmt_tree ()) *compound_stmt_p = begin_compound_stmt (/*has_no_scope=*/1); - /* - else - *compound_stmt_p = genrtl_begin_compound_stmt (has_no_scope=1); - */ } /* Finish out the statement-expression begun by the previous call to @@ -116,7 +112,10 @@ finish_init_stmts (stmt_expr, compound_stmt) finish_compound_stmt (/*has_no_scope=*/1, compound_stmt); if (building_stmt_tree ()) - stmt_expr = finish_stmt_expr (stmt_expr); + { + stmt_expr = finish_stmt_expr (stmt_expr); + STMT_EXPR_NO_SCOPE (stmt_expr) = true; + } else stmt_expr = finish_global_stmt_expr (stmt_expr); @@ -1496,10 +1495,8 @@ build_member_call (type, name, parmlist) decl = maybe_dummy_object (type, &basetype_path); /* Convert 'this' to the specified type to disambiguate conversion - to the function's context. Apparently Standard C++ says that we - shouldn't do this. */ + to the function's context. */ if (decl == current_class_ref - && ! pedantic && ACCESSIBLY_UNIQUELY_DERIVED_P (type, current_class_type)) { tree olddecl = current_class_ptr; @@ -1819,9 +1816,7 @@ resolve_offset_ref (exp) if (TREE_CODE (member) == FIELD_DECL && (base == current_class_ref || is_dummy_object (base))) { - tree expr; - - basetype = DECL_CONTEXT (member); + tree binfo = TYPE_BINFO (current_class_type); /* Try to get to basetype from 'this'; if that doesn't work, nothing will. */ @@ -1829,30 +1824,15 @@ resolve_offset_ref (exp) /* 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)); - - /* Don't check access on the conversion; we might be after a member - promoted by an access- or using-declaration, and we have already - checked access for the member itself. */ - basetype = lookup_base (TREE_TYPE (base), basetype, ba_ignore, NULL); - expr = build_base_path (PLUS_EXPR, base, basetype, 1); - - if (expr == error_mark_node) - return error_mark_node; - - type = TREE_TYPE (member); - if (TREE_CODE (type) != REFERENCE_TYPE) { - int quals = cp_type_quals (type) | cp_type_quals (TREE_TYPE (expr)); - - if (DECL_MUTABLE_P (member)) - quals &= ~TYPE_QUAL_CONST; - - type = cp_build_qualified_type (type, quals); + 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); } - - expr = build (COMPONENT_REF, type, expr, member); - return convert_from_reference (expr); + + return build_component_ref (base, member, binfo, 1); } /* Ensure that we have an object. */ @@ -2206,6 +2186,7 @@ build_new_1 (exp) tree full_type; tree nelts = NULL_TREE; tree alloc_call, alloc_expr, alloc_node; + tree alloc_fn; tree cookie_expr, init_expr; int has_array = 0; enum tree_code code; @@ -2260,7 +2241,7 @@ build_new_1 (exp) size = size_in_bytes (true_type); if (has_array) - size = fold (cp_build_binary_op (MULT_EXPR, size, nelts)); + size = size_binop (MULT_EXPR, size, convert (sizetype, nelts)); if (TREE_CODE (true_type) == VOID_TYPE) { @@ -2288,7 +2269,7 @@ build_new_1 (exp) use_cookie = 0; /* When using placement new, users may not realize that they need the extra storage. We require that the operator called be - the global placement operator delete[]. */ + the global placement operator new[]. */ else if (placement && !TREE_CHAIN (placement) && same_type_p (TREE_TYPE (TREE_VALUE (placement)), ptr_type_node)) @@ -2346,13 +2327,14 @@ build_new_1 (exp) if (alloc_call == error_mark_node) return error_mark_node; - /* The ALLOC_CALL should be a CALL_EXPR, and the first operand - should be the address of a known FUNCTION_DECL. */ - my_friendly_assert (TREE_CODE (alloc_call) == CALL_EXPR, 20000521); - t = TREE_OPERAND (alloc_call, 0); - my_friendly_assert (TREE_CODE (t) == ADDR_EXPR, 20000521); - t = TREE_OPERAND (t, 0); - my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL, 20000521); + /* The ALLOC_CALL should be a CALL_EXPR -- or a COMPOUND_EXPR whose + right-hand-side is ultimately a CALL_EXPR -- and the first + operand should be the address of a known FUNCTION_DECL. */ + t = alloc_call; + while (TREE_CODE (t) == COMPOUND_EXPR) + t = TREE_OPERAND (t, 1); + alloc_fn = get_callee_fndecl (t); + my_friendly_assert (alloc_fn != NULL_TREE, 20020325); /* Now, check to see if this function is actually a placement allocation function. This can happen even when PLACEMENT is NULL because we might have something like: @@ -2364,7 +2346,8 @@ build_new_1 (exp) one argument, or there are variable arguments, then this is a placement allocation function. */ placement_allocation_fn_p - = (type_num_arguments (TREE_TYPE (t)) > 1 || varargs_function_p (t)); + = (type_num_arguments (TREE_TYPE (alloc_fn)) > 1 + || varargs_function_p (alloc_fn)); /* unless an allocation function is declared with an empty excep- tion-specification (_except.spec_), throw(), it indicates failure to @@ -2376,11 +2359,7 @@ build_new_1 (exp) So check for a null exception spec on the op new we just called. */ - /* The ADDR_EXPR. */ - t = TREE_OPERAND (alloc_call, 0); - /* The function. */ - t = TREE_OPERAND (t, 0); - nothrow = TYPE_NOTHROW_P (TREE_TYPE (t)); + nothrow = TYPE_NOTHROW_P (TREE_TYPE (alloc_fn)); check_new = (flag_check_new || nothrow) && ! use_java_new; alloc_expr = alloc_call; @@ -2473,13 +2452,22 @@ build_new_1 (exp) tree cleanup; int flags = (LOOKUP_NORMAL | (globally_qualified_p * LOOKUP_GLOBAL)); + tree delete_node; + + if (use_cookie) + /* Subtract the padding back out to get to the pointer returned + from operator new. */ + delete_node = fold (build (MINUS_EXPR, TREE_TYPE (alloc_node), + alloc_node, cookie_size)); + else + delete_node = alloc_node; /* The Standard is unclear here, but the right thing to do is to use the same method for finding deallocation functions that we use for finding allocation functions. */ flags |= LOOKUP_SPECULATIVELY; - cleanup = build_op_delete_call (dcode, alloc_node, size, flags, + cleanup = build_op_delete_call (dcode, delete_node, size, flags, (placement_allocation_fn_p ? alloc_call : NULL_TREE)); @@ -3200,6 +3188,14 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) /* Call the complete object destructor. */ auto_delete = sfk_complete_destructor; } + else if (auto_delete == sfk_deleting_destructor + && TYPE_GETS_REG_DELETE (type)) + { + /* 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); + } expr = build_dtor_call (build_indirect_ref (addr, NULL), auto_delete, flags); @@ -3221,18 +3217,65 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) } } -/* At the beginning of a destructor, push cleanups that will call the - destructors for our base classes and members. +/* At the end of a destructor, call the destructors for our base classes + and members. - Called from setup_vtbl_ptr. */ + Called from finish_destructor_body. */ void -push_base_cleanups () +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)) @@ -3271,47 +3314,18 @@ push_base_cleanups () LOOKUP_NORMAL); expr = build (COND_EXPR, void_type_node, cond, expr, void_zero_node); - finish_decl_cleanup (NULL_TREE, expr); + if (!vbase_destructions) + vbase_destructions = expr; + else + vbase_destructions = build (COMPOUND_EXPR, + TREE_TYPE (vbase_destructions), + expr, + vbase_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 = 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_scoped_method_call (current_class_ref, base_binfo, - base_dtor_identifier, - NULL_TREE); - - finish_decl_cleanup (NULL_TREE, expr); - } - - 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, DECL_NAME (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); - finish_decl_cleanup (NULL_TREE, expr); - } - } + if (vbase_destructions) + finish_expr_stmt (vbase_destructions); } /* For type TYPE, delete the virtual baseclass objects of DECL. */ diff --git a/contrib/gcc/cp/lang-specs.h b/contrib/gcc/cp/lang-specs.h index e48bf74..a8efd10 100644 --- a/contrib/gcc/cp/lang-specs.h +++ b/contrib/gcc/cp/lang-specs.h @@ -41,20 +41,20 @@ Boston, MA 02111-1307, USA. */ -D__GXX_ABI_VERSION=100\ %{ansi:-D__STRICT_ANSI__ -trigraphs -$} %(cpp_options)}\ %{!E:%{!M:%{!MM:\ - %{save-temps:cpp0 -lang-c++ \ + %{save-temps|no-integrated-cpp:cpp0 -lang-c++ \ %{!no-gcc:-D__GNUG__=%v1}\ %{!Wno-deprecated:-D__DEPRECATED}\ %{!fno-exceptions:-D__EXCEPTIONS}\ -D__GXX_ABI_VERSION=100\ %{ansi:-D__STRICT_ANSI__ -trigraphs -$}\ - %(cpp_options) %b.ii \n}\ - cc1plus %{save-temps:-fpreprocessed %b.ii}\ - %{!save-temps:%(cpp_unique_options)\ + %(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}\ -D__GXX_ABI_VERSION=100\ - %{ansi:-D__STRICT_ANSI__}}\ + %{ansi:-D__STRICT_ANSI__}}}\ %{ansi:-trigraphs -$}\ %(cc1_options) %2 %{+e1*}\ %{!fsyntax-only:%(invoke_as)}}}}", diff --git a/contrib/gcc/cp/lex.c b/contrib/gcc/cp/lex.c index 0287f70..61e34a8 100644 --- a/contrib/gcc/cp/lex.c +++ b/contrib/gcc/cp/lex.c @@ -263,8 +263,6 @@ cxx_init_options () void cxx_finish () { - if (flag_gnu_xref) - GNU_xref_end (errorcount + sorrycount); c_common_finish (); } @@ -733,8 +731,6 @@ cxx_init (filename) init_cp_pragma (); - if (flag_gnu_xref) - GNU_xref_begin (filename); init_repo (filename); return filename; @@ -931,9 +927,6 @@ extract_interface_info () interface_only = finfo->interface_only; interface_unknown = finfo->interface_unknown; - - /* This happens to be a convenient place to put this. */ - if (flag_gnu_xref) GNU_xref_file (input_filename); } /* Return nonzero if S is not considered part of an @@ -1372,7 +1365,8 @@ do_scoped_id (token, parsing) id = IDENTIFIER_GLOBAL_VALUE (token); if (parsing && yychar == YYEMPTY) yychar = yylex (); - if (! id) + if (!id || (TREE_CODE (id) == FUNCTION_DECL + && DECL_ANTICIPATED (id))) { if (processing_template_decl) { diff --git a/contrib/gcc/cp/mangle.c b/contrib/gcc/cp/mangle.c index 00e5143..2e79581 100644 --- a/contrib/gcc/cp/mangle.c +++ b/contrib/gcc/cp/mangle.c @@ -1353,6 +1353,11 @@ write_type (type) since both the qualified and uqualified types are substitution candidates. */ write_type (TYPE_MAIN_VARIANT (type)); + else if (TREE_CODE (type) == ARRAY_TYPE) + /* It is important not to use the TYPE_MAIN_VARIANT of TYPE here + so that the cv-qualification of the element type is available + in write_array_type. */ + write_array_type (type); else { /* See through any typedefs. */ @@ -1399,10 +1404,6 @@ write_type (type) write_nested_name (TYPE_STUB_DECL (type)); break; - case ARRAY_TYPE: - write_array_type (type); - break; - case POINTER_TYPE: /* A pointer-to-member variable is represented by a POINTER_TYPE to an OFFSET_TYPE, so check for this first. */ @@ -1469,19 +1470,23 @@ write_CV_qualifiers_for_type (type) "In cases where multiple order-insensitive qualifiers are present, they should be ordered 'K' (closest to the base type), - 'V', 'r', and 'U' (farthest from the base type) ..." */ + 'V', 'r', and 'U' (farthest from the base type) ..." - if (CP_TYPE_RESTRICT_P (type)) + Note that we do not use cp_type_quals below; given "const + int[3]", the "const" is emitted with the "int", not with the + array. */ + + if (TYPE_QUALS (type) & TYPE_QUAL_RESTRICT) { write_char ('r'); ++num_qualifiers; } - if (CP_TYPE_VOLATILE_P (type)) + if (TYPE_QUALS (type) & TYPE_QUAL_VOLATILE) { write_char ('V'); ++num_qualifiers; } - if (CP_TYPE_CONST_P (type)) + if (TYPE_QUALS (type) & TYPE_QUAL_CONST) { write_char ('K'); ++num_qualifiers; @@ -1506,8 +1511,8 @@ write_CV_qualifiers_for_type (type) ::= m # unsigned long ::= x # long long, __int64 ::= y # unsigned long long, __int64 - ::= n # __int128 [not supported] - ::= o # unsigned __int128 [not supported] + ::= n # __int128 + ::= o # unsigned __int128 ::= f # float ::= d # double ::= e # long double, __float80 @@ -1552,15 +1557,23 @@ write_builtin_type (type) write_char (integer_type_codes[itk]); break; } - + if (itk == itk_none) { tree t = type_for_mode (TYPE_MODE (type), TREE_UNSIGNED (type)); if (type == t) - /* Couldn't find this type. */ - abort (); - type = t; - goto iagain; + { + if (TYPE_PRECISION (type) == 128) + write_char (TREE_UNSIGNED (type) ? 'o' : 'n'); + else + /* Couldn't find this type. */ + abort (); + } + else + { + type = t; + goto iagain; + } } } break; @@ -1595,6 +1608,17 @@ write_function_type (type) { MANGLE_TRACE_TREE ("function-type", type); + /* For a pointer to member function, the function type may have + cv-qualifiers, indicating the quals for the artificial 'this' + parameter. */ + if (TREE_CODE (type) == METHOD_TYPE) + { + /* The first parameter must be a POINTER_TYPE pointing to the + `this' parameter. */ + tree this_type = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type))); + write_CV_qualifiers_for_type (this_type); + } + write_char ('F'); /* We don't track whether or not a type is `extern "C"'. Note that you can have an `extern "C"' function that does not have @@ -1769,6 +1793,16 @@ write_expression (expr) code = TREE_CODE (expr); } + /* Skip NOP_EXPRs. They can occur when (say) a pointer argument + is converted (via qualification conversions) to another + type. */ + while (TREE_CODE (expr) == NOP_EXPR + || TREE_CODE (expr) == NON_LVALUE_EXPR) + { + expr = TREE_OPERAND (expr, 0); + code = TREE_CODE (expr); + } + /* Handle template parameters. */ if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM @@ -1788,15 +1822,6 @@ write_expression (expr) { int i; - /* Skip NOP_EXPRs. They can occur when (say) a pointer argument - is converted (via qualification conversions) to another - type. */ - while (TREE_CODE (expr) == NOP_EXPR) - { - expr = TREE_OPERAND (expr, 0); - code = TREE_CODE (expr); - } - /* When we bind a variable or function to a non-type template argument with reference type, we create an ADDR_EXPR to show the fact that the entity's address has been taken. But, we @@ -2021,24 +2046,7 @@ write_pointer_to_member_type (type) tree type; { write_char ('M'); - /* For a pointer-to-function member, the class type may be - cv-qualified, but that won't be reflected in - TYPE_PTRMEM_CLASS_TYPE. So, we go fishing around in - TYPE_PTRMEM_POINTED_TO_TYPE instead. */ - if (TYPE_PTRMEMFUNC_P (type)) - { - tree fn_type; - tree this_type; - - fn_type = TYPE_PTRMEM_POINTED_TO_TYPE (type); - /* The first parameter must be a POINTER_TYPE pointing to the - `this' parameter. */ - this_type = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fn_type))); - write_type (this_type); - } - /* For a pointer-to-data member, things are simpler. */ - else - write_type (TYPE_PTRMEM_CLASS_TYPE (type)); + write_type (TYPE_PTRMEM_CLASS_TYPE (type)); write_type (TYPE_PTRMEM_POINTED_TO_TYPE (type)); } diff --git a/contrib/gcc/cp/method.c b/contrib/gcc/cp/method.c index b0cc63a..e4af0ab 100644 --- a/contrib/gcc/cp/method.c +++ b/contrib/gcc/cp/method.c @@ -392,6 +392,12 @@ use_thunk (thunk_fndecl, emit_p) push_to_top_level (); + /* The back-end expects DECL_INITIAL to contain a BLOCK, so we + create one. */ + DECL_INITIAL (thunk_fndecl) = make_node (BLOCK); + BLOCK_VARS (DECL_INITIAL (thunk_fndecl)) + = DECL_ARGUMENTS (thunk_fndecl); + #ifdef ASM_OUTPUT_MI_THUNK if (!vcall_offset) { @@ -411,88 +417,83 @@ use_thunk (thunk_fndecl, emit_p) } else #endif /* ASM_OUTPUT_MI_THUNK */ - { - /* If we don't have the necessary macro for efficient thunks, generate a - thunk function that just makes a call to the real function. - Unfortunately, this doesn't work for varargs. */ - - tree a, t; - - if (varargs_function_p (function)) - error ("generic thunk code fails for method `%#D' which uses `...'", - function); - - /* Set up clone argument trees for the thunk. */ - t = NULL_TREE; - for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a)) - { - tree x = copy_node (a); - TREE_CHAIN (x) = t; - DECL_CONTEXT (x) = thunk_fndecl; - t = x; - } - a = nreverse (t); - DECL_ARGUMENTS (thunk_fndecl) = a; - DECL_RESULT (thunk_fndecl) = NULL_TREE; - - start_function (NULL_TREE, thunk_fndecl, NULL_TREE, SF_PRE_PARSED); - /* We don't bother with a body block for thunks. */ - - /* Adjust the this pointer by the constant. */ - t = ssize_int (delta); - t = fold (build (PLUS_EXPR, TREE_TYPE (a), a, t)); - /* If there's a vcall offset, look up that value in the vtable and - adjust the `this' pointer again. */ - if (vcall_offset && !integer_zerop (vcall_offset)) - { - tree orig_this; - - t = save_expr (t); - orig_this = t; - /* The vptr is always at offset zero in the object. */ - t = build1 (NOP_EXPR, - build_pointer_type (build_pointer_type - (vtable_entry_type)), - t); - /* Form the vtable address. */ - t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t); - /* Find the entry with the vcall offset. */ - t = build (PLUS_EXPR, TREE_TYPE (t), t, vcall_offset); - /* Calculate the offset itself. */ - t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t); - /* Adjust the `this' pointer. */ - t = fold (build (PLUS_EXPR, - TREE_TYPE (orig_this), - orig_this, - t)); - } - - /* Build up the call to the real function. */ - t = tree_cons (NULL_TREE, t, NULL_TREE); - for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a)) - t = tree_cons (NULL_TREE, a, t); - t = nreverse (t); - t = build_call (function, t); - if (VOID_TYPE_P (TREE_TYPE (t))) - finish_expr_stmt (t); - else - finish_return_stmt (t); + { + /* If we don't have the necessary macro for efficient thunks, generate + a thunk function that just makes a call to the real function. + Unfortunately, this doesn't work for varargs. */ - /* The back-end expects DECL_INITIAL to contain a BLOCK, so we - create one. */ - DECL_INITIAL (thunk_fndecl) = make_node (BLOCK); - BLOCK_VARS (DECL_INITIAL (thunk_fndecl)) - = DECL_ARGUMENTS (thunk_fndecl); + tree a, t; - /* Since we want to emit the thunk, we explicitly mark its name as - referenced. */ - TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (thunk_fndecl)) = 1; + if (varargs_function_p (function)) + error ("generic thunk code fails for method `%#D' which uses `...'", + function); - /* But we don't want debugging information about it. */ - DECL_IGNORED_P (thunk_fndecl) = 1; + /* Set up clone argument trees for the thunk. */ + t = NULL_TREE; + for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a)) + { + tree x = copy_node (a); + TREE_CHAIN (x) = t; + DECL_CONTEXT (x) = thunk_fndecl; + t = x; + } + a = nreverse (t); + DECL_ARGUMENTS (thunk_fndecl) = a; + DECL_RESULT (thunk_fndecl) = NULL_TREE; - expand_body (finish_function (0)); - } + start_function (NULL_TREE, thunk_fndecl, NULL_TREE, SF_PRE_PARSED); + /* We don't bother with a body block for thunks. */ + + /* Adjust the this pointer by the constant. */ + t = ssize_int (delta); + t = fold (build (PLUS_EXPR, TREE_TYPE (a), a, t)); + + /* If there's a vcall offset, look up that value in the vtable and + adjust the `this' pointer again. */ + if (vcall_offset && !integer_zerop (vcall_offset)) + { + tree orig_this; + + t = save_expr (t); + orig_this = t; + /* The vptr is always at offset zero in the object. */ + t = build1 (NOP_EXPR, + build_pointer_type (build_pointer_type + (vtable_entry_type)), + t); + /* Form the vtable address. */ + t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t); + /* Find the entry with the vcall offset. */ + t = build (PLUS_EXPR, TREE_TYPE (t), t, vcall_offset); + /* Calculate the offset itself. */ + t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t); + /* Adjust the `this' pointer. */ + t = fold (build (PLUS_EXPR, + TREE_TYPE (orig_this), + orig_this, + t)); + } + + /* Build up the call to the real function. */ + t = tree_cons (NULL_TREE, t, NULL_TREE); + for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a)) + t = tree_cons (NULL_TREE, a, t); + t = nreverse (t); + t = build_call (function, t); + if (VOID_TYPE_P (TREE_TYPE (t))) + finish_expr_stmt (t); + else + finish_return_stmt (t); + + /* Since we want to emit the thunk, we explicitly mark its name as + referenced. */ + TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (thunk_fndecl)) = 1; + + /* But we don't want debugging information about it. */ + DECL_IGNORED_P (thunk_fndecl) = 1; + + expand_body (finish_function (0)); + } pop_from_top_level (); } @@ -561,6 +562,7 @@ do_build_copy_constructor (fndecl) { tree init; tree field = fields; + tree expr_type; if (TREE_CODE (field) != FIELD_DECL) continue; @@ -583,9 +585,15 @@ do_build_copy_constructor (fndecl) else continue; - init = build (COMPONENT_REF, - build_qualified_type (TREE_TYPE (field), cvquals), - init, field); + /* Compute the type of "init->field". If the copy-constructor + parameter is, for example, "const S&", and the type of + the field is "T", then the type will usually be "const + T". (There are no cv-qualified variants of reference + types.) */ + expr_type = TREE_TYPE (field); + if (TREE_CODE (expr_type) != REFERENCE_TYPE) + expr_type = cp_build_qualified_type (expr_type, cvquals); + init = build (COMPONENT_REF, expr_type, init, field); init = build_tree_list (NULL_TREE, init); member_init_list @@ -635,7 +643,7 @@ do_build_assign_ref (fndecl) tree expr = build_method_call (dst, ansi_assopname (NOP_EXPR), build_tree_list (NULL_TREE, src), - NULL, + binfo, LOOKUP_NORMAL | LOOKUP_NONVIRTUAL); finish_expr_stmt (expr); } @@ -769,8 +777,9 @@ synthesize_method (fndecl) /* Use EXTRACTOR to locate the relevant function called for each base & class field of TYPE. CLIENT allows additional information to be passed - to EXTRACTOR. Generates the union of all exceptions generated by - those functions. */ + to EXTRACTOR. Generates the union of all exceptions generated by those + functions. Note that we haven't updated TYPE_FIELDS and such of any + variants yet, so we need to look at the main one. */ static tree synthesize_exception_spec (type, extractor, client) @@ -782,7 +791,7 @@ synthesize_exception_spec (type, extractor, client) tree fields = TYPE_FIELDS (type); int i, n_bases = CLASSTYPE_N_BASECLASSES (type); tree binfos = TYPE_BINFO_BASETYPES (type); - + for (i = 0; i != n_bases; i++) { tree base = BINFO_TYPE (TREE_VEC_ELT (binfos, i)); @@ -961,7 +970,7 @@ implicitly_declare_fn (kind, type, const_p) case sfk_assignment_operator: { struct copy_data data; - tree argtype; + tree argtype = type; has_parm = 1; data.name = NULL; @@ -977,10 +986,10 @@ implicitly_declare_fn (kind, type, const_p) if (const_p) { data.quals = TYPE_QUAL_CONST; - type = build_qualified_type (type, TYPE_QUAL_CONST); + argtype = build_qualified_type (argtype, TYPE_QUAL_CONST); } - argtype = build_reference_type (type); + argtype = build_reference_type (argtype); args = build_tree_list (hash_tree_chain (argtype, NULL_TREE), get_identifier ("_ctor_arg")); args = tree_cons (NULL_TREE, args, void_list_node); diff --git a/contrib/gcc/cp/parse.y b/contrib/gcc/cp/parse.y index 7941a89..d1e3761 100644 --- a/contrib/gcc/cp/parse.y +++ b/contrib/gcc/cp/parse.y @@ -87,7 +87,8 @@ static tree parse_field PARAMS ((tree, tree, tree, tree)); static tree parse_bitfield0 PARAMS ((tree, tree, tree, tree, tree)); static tree parse_bitfield PARAMS ((tree, tree, tree)); static tree parse_method PARAMS ((tree, tree, tree)); -static void frob_specs PARAMS ((tree, tree)); +static void frob_specs PARAMS ((tree, tree)); +static void check_class_key PARAMS ((tree, tree)); /* Cons up an empty parameter list. */ static inline tree @@ -208,6 +209,19 @@ parse_method (declarator, specs_attrs, lookups) return d; } +static void +check_class_key (key, aggr) + tree key; + tree aggr; +{ + if (TREE_CODE (key) == TREE_LIST) + key = TREE_VALUE (key); + if ((key == union_type_node) != (TREE_CODE (aggr) == UNION_TYPE)) + pedwarn ("`%s' tag used in naming `%#T'", + key == union_type_node ? "union" + : key == record_type_node ? "struct" : "class", aggr); +} + void cp_parse_init () { @@ -584,6 +598,7 @@ namespace_qualifier: $$ = lastiddecl; got_scope = $$; } + ; any_id: unqualified_id @@ -633,6 +648,7 @@ maybe_identifier: { $$ = $1; } | /* empty */ { $$ = NULL_TREE; } + ; template_type_parm: aggr maybe_identifier @@ -1030,9 +1046,11 @@ explicit_instantiation: begin_explicit_instantiation: { begin_explicit_instantiation(); } + ; end_explicit_instantiation: { end_explicit_instantiation(); } + ; /* The TYPENAME expansions are to deal with use of a template class name as a template within the class itself, where the template decl is hidden by @@ -1053,6 +1071,7 @@ apparent_template_type: | identifier '<' template_arg_list_opt '>' .finish_template_type { $$ = $5; } + ; self_template_type: SELFNAME '<' template_arg_list_opt template_close_bracket @@ -1068,6 +1087,7 @@ self_template_type: $$ = finish_template_type ($<ttype>-3, $<ttype>-1, yychar == SCOPE); } + ; template_close_bracket: '>' @@ -1487,6 +1507,7 @@ do_id: else $$ = $<ttype>-1; } + ; template_id: PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket @@ -1592,7 +1613,7 @@ primary: pedwarn ("ISO C++ forbids braced-groups within expressions"); $<ttype>$ = begin_stmt_expr (); } - compstmt ')' + compstmt_or_stmtexpr ')' { $$ = finish_stmt_expr ($<ttype>2); } /* Koenig lookup support We could store lastiddecl in $1 to avoid another lookup, @@ -1717,7 +1738,7 @@ primary_no_id: YYERROR; } $<ttype>$ = expand_start_stmt_expr (); } - compstmt ')' + compstmt_or_stmtexpr ')' { if (pedantic) pedwarn ("ISO C++ forbids braced-groups within expressions"); $$ = expand_end_stmt_expr ($<ttype>2); } @@ -1895,10 +1916,6 @@ reserved_declspecs: warning ("`%s' is not at beginning of declaration", IDENTIFIER_POINTER ($2)); $$ = tree_cons (NULL_TREE, $2, $$); } - | reserved_declspecs attributes - { $$ = tree_cons ($2, NULL_TREE, $1); } - | attributes - { $$ = tree_cons ($1, NULL_TREE, NULL_TREE); } ; /* List of just storage classes and type modifiers. @@ -1966,6 +1983,10 @@ reserved_typespecquals: { $$ = build_tree_list (NULL_TREE, $1.t); } | reserved_typespecquals typespecqual_reserved { $$ = tree_cons (NULL_TREE, $2.t, $1); } + | reserved_typespecquals attributes + { $$ = tree_cons ($2, NULL_TREE, $1); } + | attributes %prec EMPTY + { $$ = tree_cons ($1, NULL_TREE, NULL_TREE); } ; /* A typespec (but not a type qualifier). @@ -2098,7 +2119,7 @@ notype_initdcl0: nomods_initdcl0: notype_declarator maybeasm { /* Set things up as initdcl0_innards expects. */ - $<ttype>3 = $2; + $<ttype>$ = $2; $2 = $1; $<ftype>1.t = NULL_TREE; $<ftype>1.lookups = NULL_TREE; } @@ -2173,6 +2194,7 @@ maybe_init: { $$ = NULL_TREE; } | '=' init { $$ = $2; } + ; /* If we are processing a template, we don't want to expand this initializer yet. */ @@ -2237,6 +2259,7 @@ defarg_again: { replace_defarg ($1, $2); } | DEFARG_MARKER error END_OF_SAVED_INPUT { replace_defarg ($1, error_mark_node); } + ; pending_defargs: /* empty */ %prec EMPTY @@ -2292,6 +2315,7 @@ structsp: xref_basetypes (current_aggr, $1.t, type, $2); } $1.t = begin_class_definition (TREE_TYPE ($1.t)); + check_class_key (current_aggr, $1.t); current_aggr = NULL_TREE; } opt.component_decl_list '}' maybe_attribute { @@ -2326,6 +2350,7 @@ structsp: { $$.t = TREE_TYPE ($1.t); $$.new_type_flag = $1.new_type_flag; + check_class_key (current_aggr, $$.t); } ; @@ -2666,6 +2691,7 @@ component_decl_1: { $$ = grokfield ($$, NULL_TREE, $4, $2, $3); } | using_decl { $$ = do_class_using_decl ($1); } + ; /* The case of exactly one component is handled directly by component_decl. */ /* ??? Huh? ^^^ */ @@ -3029,14 +3055,14 @@ nested_name_specifier: { $$ = $2; } | nested_name_specifier TEMPLATE explicit_template_type SCOPE { got_scope = $$ - = make_typename_type ($1, $3, /*complain=*/1); } + = make_typename_type ($1, $3, tf_error); } /* Error handling per Core 125. */ | nested_name_specifier IDENTIFIER SCOPE { got_scope = $$ - = make_typename_type ($1, $2, /*complain=*/1); } + = make_typename_type ($1, $2, tf_error); } | nested_name_specifier PTYPENAME SCOPE { got_scope = $$ - = make_typename_type ($1, $2, /*complain=*/1); } + = make_typename_type ($1, $2, tf_error); } ; /* Why the @#$%^& do type_name and notype_identifier need to be expanded @@ -3078,7 +3104,7 @@ typename_sub0: typename_sub1 identifier %prec EMPTY { if (TYPE_P ($1)) - $$ = make_typename_type ($1, $2, /*complain=*/1); + $$ = make_typename_type ($1, $2, tf_error); else if (TREE_CODE ($2) == IDENTIFIER_NODE) error ("`%T' is not a class or namespace", $2); else @@ -3091,9 +3117,9 @@ typename_sub0: | typename_sub1 template_type %prec EMPTY { $$ = TREE_TYPE ($2); } | typename_sub1 explicit_template_type %prec EMPTY - { $$ = make_typename_type ($1, $2, /*complain=*/1); } + { $$ = make_typename_type ($1, $2, tf_error); } | typename_sub1 TEMPLATE explicit_template_type %prec EMPTY - { $$ = make_typename_type ($1, $3, /*complain=*/1); } + { $$ = make_typename_type ($1, $3, tf_error); } ; typename_sub1: @@ -3107,7 +3133,7 @@ typename_sub1: | typename_sub1 typename_sub2 { if (TYPE_P ($1)) - $$ = make_typename_type ($1, $2, /*complain=*/1); + $$ = make_typename_type ($1, $2, tf_error); else if (TREE_CODE ($2) == IDENTIFIER_NODE) error ("`%T' is not a class or namespace", $2); else @@ -3119,10 +3145,10 @@ typename_sub1: } | typename_sub1 explicit_template_type SCOPE { got_scope = $$ - = make_typename_type ($1, $2, /*complain=*/1); } + = make_typename_type ($1, $2, tf_error); } | typename_sub1 TEMPLATE explicit_template_type SCOPE { got_scope = $$ - = make_typename_type ($1, $3, /*complain=*/1); } + = make_typename_type ($1, $3, tf_error); } ; /* This needs to return a TYPE_DECL for simple names so that we don't @@ -3324,7 +3350,7 @@ label_decl: } ; -compstmt: +compstmt_or_stmtexpr: save_lineno '{' { $<ttype>$ = begin_compound_stmt (0); } compstmtend @@ -3332,6 +3358,11 @@ compstmt: finish_compound_stmt (0, $<ttype>3); } ; +compstmt: + compstmt_or_stmtexpr + { last_expr_type = NULL_TREE; } + ; + simple_if: IF { $<ttype>$ = begin_if_stmt (); diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c index 5084f72..989cf1a 100644 --- a/contrib/gcc/cp/pt.c +++ b/contrib/gcc/cp/pt.c @@ -93,30 +93,32 @@ static htab_t local_specializations; type with the desired type. */ static int resolve_overloaded_unification PARAMS ((tree, tree, tree, tree, - unification_kind_t, int)); + unification_kind_t, int)); static int try_one_overload PARAMS ((tree, tree, tree, tree, tree, - unification_kind_t, int)); + unification_kind_t, int)); static int unify PARAMS ((tree, tree, tree, tree, int)); static void add_pending_template PARAMS ((tree)); static void reopen_tinst_level PARAMS ((tree)); static tree classtype_mangled_name PARAMS ((tree)); -static char *mangle_class_name_for_template PARAMS ((const char *, tree, tree)); +static char *mangle_class_name_for_template PARAMS ((const char *, + tree, tree)); static tree tsubst_initializer_list PARAMS ((tree, tree)); static int list_eq PARAMS ((tree, tree)); static tree get_class_bindings PARAMS ((tree, tree, tree)); -static tree coerce_template_parms PARAMS ((tree, tree, tree, int, int)); +static tree coerce_template_parms PARAMS ((tree, tree, tree, + tsubst_flags_t, int)); static void tsubst_enum PARAMS ((tree, tree, tree)); static tree add_to_template_args PARAMS ((tree, tree)); static tree add_outermost_template_args PARAMS ((tree, tree)); static int maybe_adjust_types_for_deduction PARAMS ((unification_kind_t, tree*, - tree*)); + tree*)); static int type_unification_real PARAMS ((tree, tree, tree, tree, - int, unification_kind_t, int, int)); + int, unification_kind_t, int, int)); static void note_template_header PARAMS ((int)); static tree maybe_fold_nontype_arg PARAMS ((tree)); static tree convert_nontype_argument PARAMS ((tree, tree)); -static tree convert_template_argument PARAMS ((tree, tree, tree, int, - int , tree)); +static tree convert_template_argument PARAMS ((tree, tree, tree, + tsubst_flags_t, int, tree)); static tree get_bindings_overload PARAMS ((tree, tree, tree)); static int for_each_template_parm PARAMS ((tree, tree_fn_t, void*)); static tree build_template_parm_index PARAMS ((int, int, int, tree, tree)); @@ -136,35 +138,36 @@ static tree get_bindings_real PARAMS ((tree, tree, tree, int, int, int)); static int template_decl_level PARAMS ((tree)); static tree maybe_get_template_decl_from_type_decl PARAMS ((tree)); static int check_cv_quals_for_unify PARAMS ((int, tree, tree)); -static tree tsubst_template_arg_vector PARAMS ((tree, tree, int)); -static tree tsubst_template_parms PARAMS ((tree, tree, int)); +static tree tsubst_template_arg_vector PARAMS ((tree, tree, tsubst_flags_t)); +static tree tsubst_template_parms PARAMS ((tree, tree, tsubst_flags_t)); static void regenerate_decl_from_template PARAMS ((tree, tree)); static tree most_specialized PARAMS ((tree, tree, tree)); static tree most_specialized_class PARAMS ((tree, tree)); static int template_class_depth_real PARAMS ((tree, int)); -static tree tsubst_aggr_type PARAMS ((tree, tree, int, tree, int)); -static tree tsubst_decl PARAMS ((tree, tree, tree)); -static tree tsubst_arg_types PARAMS ((tree, tree, int, tree)); -static tree tsubst_function_type PARAMS ((tree, tree, int, tree)); +static tree tsubst_aggr_type PARAMS ((tree, tree, tsubst_flags_t, tree, int)); +static tree tsubst_decl PARAMS ((tree, tree, tree, tsubst_flags_t)); +static tree tsubst_arg_types PARAMS ((tree, tree, tsubst_flags_t, tree)); +static tree tsubst_function_type PARAMS ((tree, tree, tsubst_flags_t, tree)); static void check_specialization_scope PARAMS ((void)); static tree process_partial_specialization PARAMS ((tree)); static void set_current_access_from_decl PARAMS ((tree)); static void check_default_tmpl_args PARAMS ((tree, tree, int, int)); -static tree tsubst_call_declarator_parms PARAMS ((tree, tree, int, tree)); +static tree tsubst_call_declarator_parms PARAMS ((tree, tree, + tsubst_flags_t, tree)); static tree get_template_base_recursive PARAMS ((tree, tree, - tree, tree, tree, int)); + tree, tree, tree, int)); static tree get_template_base PARAMS ((tree, tree, tree, tree)); static int verify_class_unification PARAMS ((tree, tree, tree)); static tree try_class_unification PARAMS ((tree, tree, tree, tree)); -static int coerce_template_template_parms PARAMS ((tree, tree, int, - tree, tree)); +static int coerce_template_template_parms PARAMS ((tree, tree, tsubst_flags_t, + tree, tree)); static tree determine_specialization PARAMS ((tree, tree, tree *, int)); static int template_args_equal PARAMS ((tree, tree)); static void tsubst_default_arguments PARAMS ((tree)); static tree for_each_template_parm_r PARAMS ((tree *, int *, void *)); static tree copy_default_args_to_explicit_spec_1 PARAMS ((tree, tree)); static void copy_default_args_to_explicit_spec PARAMS ((tree)); -static int invalid_nontype_parm_type_p PARAMS ((tree, int)); +static int invalid_nontype_parm_type_p PARAMS ((tree, tsubst_flags_t)); /* Called once to initialize pt.c. */ @@ -2571,7 +2574,9 @@ push_template_decl_real (decl, is_friend) if (!ctx || TREE_CODE (ctx) == FUNCTION_DECL - || TYPE_BEING_DEFINED (ctx) + || (TREE_CODE (ctx) != TEMPLATE_TYPE_PARM + && TREE_CODE (ctx) != BOUND_TEMPLATE_TEMPLATE_PARM + && TYPE_BEING_DEFINED (ctx)) || (is_friend && !DECL_TEMPLATE_INFO (decl))) { if (DECL_LANG_SPECIFIC (decl) @@ -3011,7 +3016,7 @@ convert_nontype_argument (type, expr) else fns = expr; - fn = instantiate_type (type_pointed_to, fns, itf_none); + fn = instantiate_type (type_pointed_to, fns, tf_none); if (fn == error_mark_node) return error_mark_node; @@ -3076,7 +3081,7 @@ convert_nontype_argument (type, expr) set (_over.over_). */ tree fn; - fn = instantiate_type (type_referred_to, expr, itf_none); + fn = instantiate_type (type_referred_to, expr, tf_none); if (fn == error_mark_node) return error_mark_node; @@ -3145,7 +3150,7 @@ convert_nontype_argument (type, expr) if (TREE_CODE (expr) != ADDR_EXPR) return error_mark_node; - expr = instantiate_type (type, expr, itf_none); + expr = instantiate_type (type, expr, tf_none); if (expr == error_mark_node) return error_mark_node; @@ -3186,7 +3191,7 @@ static int coerce_template_template_parms (parm_parms, arg_parms, complain, in_decl, outer_args) tree parm_parms, arg_parms; - int complain; + tsubst_flags_t complain; tree in_decl, outer_args; { int nparms, nargs, i; @@ -3255,17 +3260,17 @@ coerce_template_template_parms (parm_parms, arg_parms, complain, /* Convert the indicated template ARG as necessary to match the indicated template PARM. Returns the converted ARG, or - error_mark_node if the conversion was unsuccessful. Error messages - are issued if COMPLAIN is non-zero. This conversion is for the Ith - parameter in the parameter list. ARGS is the full set of template - arguments deduced so far. */ + error_mark_node if the conversion was unsuccessful. Error and + warning messages are issued under control of COMPLAIN. This + conversion is for the Ith parameter in the parameter list. ARGS is + the full set of template arguments deduced so far. */ static tree convert_template_argument (parm, arg, args, complain, i, in_decl) tree parm; tree arg; tree args; - int complain; + tsubst_flags_t complain; int i; tree in_decl; { @@ -3329,14 +3334,14 @@ convert_template_argument (parm, arg, args, complain, i, in_decl) arg = make_typename_type (TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1), - complain); + complain & tf_error); is_type = 1; } if (is_type != requires_type) { if (in_decl) { - if (complain) + if (complain & tf_error) { error ("type/value mismatch at argument %d in template parameter list for `%D'", i + 1, in_decl); @@ -3352,7 +3357,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl) } if (is_tmpl_type ^ requires_tmpl_type) { - if (in_decl && complain) + if (in_decl && (complain & tf_error)) { error ("type/value mismatch at argument %d in template parameter list for `%D'", i + 1, in_decl); @@ -3391,7 +3396,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl) } else { - if (in_decl && complain) + if (in_decl && (complain & tf_error)) { error ("type/value mismatch at argument %d in template parameter list for `%D'", i + 1, in_decl); @@ -3454,7 +3459,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl) if (val == NULL_TREE) val = error_mark_node; - else if (val == error_mark_node && complain) + else if (val == error_mark_node && (complain & tf_error)) error ("could not convert template argument `%E' to `%T'", arg, t); } @@ -3464,10 +3469,10 @@ convert_template_argument (parm, arg, args, complain, i, in_decl) /* Convert all template arguments to their appropriate types, and return a vector containing the innermost resulting template - arguments. If any error occurs, return error_mark_node, and, if - COMPLAIN is non-zero, issue an error message. Some error messages - are issued even if COMPLAIN is zero; for instance, if a template - argument is composed from a local class. + arguments. If any error occurs, return error_mark_node. Error and + warning messages are issued under control of COMPLAIN. Some error + messages are issued even if COMPLAIN is zero; for instance, if a + template argument is composed from a local class. If REQUIRE_ALL_ARGUMENTS is non-zero, all arguments must be provided in ARGLIST, or else trailing parameters must have default @@ -3480,7 +3485,7 @@ coerce_template_parms (parms, args, in_decl, require_all_arguments) tree parms, args; tree in_decl; - int complain; + tsubst_flags_t complain; int require_all_arguments; { int nparms, nargs, i, lost = 0; @@ -3497,7 +3502,7 @@ coerce_template_parms (parms, args, in_decl, && require_all_arguments && TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)) == NULL_TREE)) { - if (complain) + if (complain & tf_error) { error ("wrong number of template arguments (%d, should be %d)", nargs, nparms); @@ -3829,7 +3834,7 @@ maybe_get_template_decl_from_type_decl (decl) If ENTERING_SCOPE is non-zero, we are about to enter the scope of the class we are looking up. - If COMPLAIN is non-zero, issue error messages. + Issue error and warning messages under control of COMPLAIN. If the template class is really a local class in a template function, then the FUNCTION_CONTEXT is the function in which it is @@ -3841,7 +3846,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain) tree in_decl; tree context; int entering_scope; - int complain; + tsubst_flags_t complain; { tree template = NULL_TREE, parmlist; tree t; @@ -3899,7 +3904,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain) crash. Alternatively D1 might not be a template type at all. */ if (! template) { - if (complain) + if (complain & tf_error) error ("`%T' is not a template", d1); return error_mark_node; } @@ -3911,7 +3916,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain) && !DECL_TEMPLATE_PARM_P (template) && !PRIMARY_TEMPLATE_P (template))) { - if (complain) + if (complain & tf_error) { error ("non-template type `%T' used as a template", d1); if (in_decl) @@ -4109,7 +4114,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain) } context = tsubst (DECL_CONTEXT (template), arglist, - /*complain=*/0, in_decl); + complain, in_decl); if (!context) context = global_namespace; @@ -4216,7 +4221,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain) Create the partial instantiation. */ TREE_VEC_LENGTH (arglist)--; - found = tsubst (template, arglist, /*complain=*/0, NULL_TREE); + found = tsubst (template, arglist, complain, NULL_TREE); TREE_VEC_LENGTH (arglist)++; } } @@ -4583,20 +4588,20 @@ tsubst_friend_function (decl, args) tree template_id, arglist, fns; tree new_args; tree tmpl; - tree ns = CP_DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type)); + tree ns = decl_namespace_context (TYPE_MAIN_DECL (current_class_type)); /* Friend functions are looked up in the containing namespace scope. We must enter that scope, to avoid finding member functions of the current cless with same name. */ push_nested_namespace (ns); fns = tsubst_expr (DECL_TI_TEMPLATE (decl), args, - /*complain=*/1, NULL_TREE); + tf_error | tf_warning, NULL_TREE); pop_nested_namespace (ns); arglist = tsubst (DECL_TI_ARGS (decl), args, - /*complain=*/1, NULL_TREE); + tf_error | tf_warning, NULL_TREE); template_id = lookup_template_function (fns, arglist); - new_friend = tsubst (decl, args, /*complain=*/1, NULL_TREE); + new_friend = tsubst (decl, args, tf_error | tf_warning, NULL_TREE); tmpl = determine_specialization (template_id, new_friend, &new_args, /*need_member_template=*/0); @@ -4604,7 +4609,7 @@ tsubst_friend_function (decl, args) goto done; } - new_friend = tsubst (decl, args, /*complain=*/1, NULL_TREE); + new_friend = tsubst (decl, args, tf_error | tf_warning, NULL_TREE); /* The NEW_FRIEND will look like an instantiation, to the compiler, but is not an instantiation from the point of view of @@ -4791,16 +4796,27 @@ tsubst_friend_class (friend_tmpl, args) { tree friend_type; tree tmpl; + tree context; + + context = DECL_CONTEXT (friend_tmpl); + + if (context) + { + if (TREE_CODE (context) == NAMESPACE_DECL) + push_nested_namespace (context); + else + push_nested_class (context, 2); + } /* First, we look for a class template. */ tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/0); - + /* But, if we don't find one, it might be because we're in a situation like this: template <class T> struct S { - template <class U> + template <class U> friend struct S; }; @@ -4820,12 +4836,15 @@ tsubst_friend_class (friend_tmpl, args) of course. We only need the innermost template parameters because that is all that redeclare_class_template will look at. */ - tree parms - = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl), - args, /*complain=*/1); - if (!parms) - return error_mark_node; - redeclare_class_template (TREE_TYPE (tmpl), parms); + if (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (friend_tmpl)) + > TMPL_ARGS_DEPTH (args)) + { + tree parms; + parms = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl), + args, tf_error | tf_warning); + redeclare_class_template (TREE_TYPE (tmpl), parms); + } + friend_type = TREE_TYPE (tmpl); } else @@ -4833,7 +4852,7 @@ tsubst_friend_class (friend_tmpl, args) /* The friend template has not already been declared. In this case, the instantiation of the template class will cause the injection of this template into the global scope. */ - tmpl = tsubst (friend_tmpl, args, /*complain=*/1, NULL_TREE); + tmpl = tsubst (friend_tmpl, args, tf_error | tf_warning, NULL_TREE); /* The new TMPL is not an instantiation of anything, so we forget its origins. We don't reset CLASSTYPE_TI_TEMPLATE for @@ -4847,6 +4866,14 @@ tsubst_friend_class (friend_tmpl, args) friend_type = TREE_TYPE (pushdecl_top_level (tmpl)); } + if (context) + { + if (TREE_CODE (context) == NAMESPACE_DECL) + pop_nested_namespace (context); + else + pop_nested_class (); + } + return friend_type; } @@ -5060,8 +5087,7 @@ instantiate_class_template (type) pbase = TREE_VEC_ELT (pbases, i); /* Substitute to figure out the base class. */ - base = tsubst (BINFO_TYPE (pbase), args, - /*complain=*/1, NULL_TREE); + base = tsubst (BINFO_TYPE (pbase), args, tf_error, NULL_TREE); if (base == error_mark_node) continue; @@ -5115,7 +5141,7 @@ instantiate_class_template (type) tree name = TYPE_IDENTIFIER (tag); tree newtag; - newtag = tsubst (tag, args, /*complain=*/1, NULL_TREE); + newtag = tsubst (tag, args, tf_error, NULL_TREE); my_friendly_assert (newtag != error_mark_node, 20010206); if (TREE_CODE (newtag) != ENUMERAL_TYPE) { @@ -5153,14 +5179,14 @@ instantiate_class_template (type) lineno = DECL_SOURCE_LINE (t); input_filename = DECL_SOURCE_FILE (t); - r = tsubst (t, args, /*complain=*/1, NULL_TREE); + r = tsubst (t, args, tf_error | tf_warning, NULL_TREE); if (TREE_CODE (r) == VAR_DECL) { tree init; if (DECL_INITIALIZED_IN_CLASS_P (r)) init = tsubst_expr (DECL_INITIAL (t), args, - /*complain=*/1, NULL_TREE); + tf_error | tf_warning, NULL_TREE); else init = NULL_TREE; @@ -5188,7 +5214,7 @@ instantiate_class_template (type) for this instantiation. */ for (t = TYPE_METHODS (pattern); t; t = TREE_CHAIN (t)) { - tree r = tsubst (t, args, /*complain=*/1, NULL_TREE); + tree r = tsubst (t, args, tf_error, NULL_TREE); set_current_access_from_decl (r); grok_special_member_properties (r); finish_member_declaration (r); @@ -5223,8 +5249,8 @@ instantiate_class_template (type) if (TREE_CODE (friend_type) == TEMPLATE_DECL) new_friend_type = tsubst_friend_class (friend_type, args); else if (uses_template_parms (friend_type)) - new_friend_type = tsubst (friend_type, args, /*complain=*/1, - NULL_TREE); + new_friend_type = tsubst (friend_type, args, + tf_error | tf_warning, NULL_TREE); else { tree ns = decl_namespace_context (TYPE_MAIN_DECL (friend_type)); @@ -5348,7 +5374,7 @@ static tree tsubst_template_arg_vector (t, args, complain) tree t; tree args; - int complain; + tsubst_flags_t complain; { int len = TREE_VEC_LENGTH (t), need_new = 0, i; tree *elts = (tree *) alloca (len * sizeof (tree)); @@ -5394,7 +5420,7 @@ static tree tsubst_template_parms (parms, args, complain) tree parms; tree args; - int complain; + tsubst_flags_t complain; { tree r = NULL_TREE; tree* new_parms; @@ -5441,7 +5467,7 @@ static tree tsubst_aggr_type (t, args, complain, in_decl, entering_scope) tree t; tree args; - int complain; + tsubst_flags_t complain; tree in_decl; int entering_scope; { @@ -5489,8 +5515,7 @@ tsubst_aggr_type (t, args, complain, in_decl, entering_scope) r = lookup_template_class (t, argvec, in_decl, context, entering_scope, complain); - return cp_build_qualified_type_real (r, TYPE_QUALS (t), - complain); + return cp_build_qualified_type_real (r, TYPE_QUALS (t), complain); } else /* This is not a template type, so there's nothing to do. */ @@ -5525,7 +5550,8 @@ tsubst_default_argument (fn, type, arg) if (DECL_CLASS_SCOPE_P (fn)) pushclass (DECL_CONTEXT (fn), 2); - arg = tsubst_expr (arg, DECL_TI_ARGS (fn), /*complain=*/1, NULL_TREE); + arg = tsubst_expr (arg, DECL_TI_ARGS (fn), + tf_error | tf_warning, NULL_TREE); if (DECL_CLASS_SCOPE_P (fn)) popclass (); @@ -5563,19 +5589,23 @@ tsubst_default_arguments (fn) /* Substitute the ARGS into the T, which is a _DECL. TYPE is the (already computed) substitution of ARGS into TREE_TYPE (T), if - appropriate. Return the result of the substitution. */ + appropriate. Return the result of the substitution. Issue error + and warning messages under control of COMPLAIN. */ static tree -tsubst_decl (t, args, type) +tsubst_decl (t, args, type, complain) tree t; tree args; tree type; + tsubst_flags_t complain; { int saved_lineno; const char *saved_filename; tree r = NULL_TREE; tree in_decl = t; + my_friendly_assert (complain & tf_error, 20011214); + /* Set the filename and linenumber to improve error-reporting. */ saved_lineno = lineno; saved_filename = input_filename; @@ -5604,7 +5634,7 @@ tsubst_decl (t, args, type) tree full_args; full_args = tsubst_template_arg_vector (tmpl_args, args, - /*complain=*/1); + complain); /* tsubst_template_arg_vector doesn't copy the vector if nothing changed. But, *something* should have @@ -5630,7 +5660,7 @@ tsubst_decl (t, args, type) if (is_template_template_parm) { - tree new_decl = tsubst (decl, args, /*complain=*/1, in_decl); + tree new_decl = tsubst (decl, args, complain, in_decl); DECL_TEMPLATE_RESULT (r) = new_decl; TREE_TYPE (r) = TREE_TYPE (new_decl); break; @@ -5638,18 +5668,17 @@ tsubst_decl (t, args, type) DECL_CONTEXT (r) = tsubst_aggr_type (DECL_CONTEXT (t), args, - /*complain=*/1, in_decl, + complain, in_decl, /*entering_scope=*/1); DECL_VIRTUAL_CONTEXT (r) = tsubst_aggr_type (DECL_VIRTUAL_CONTEXT (t), args, - /*complain=*/1, in_decl, + complain, in_decl, /*entering_scope=*/1); DECL_TEMPLATE_INFO (r) = build_tree_list (t, args); if (TREE_CODE (decl) == TYPE_DECL) { - tree new_type = tsubst (TREE_TYPE (t), args, - /*complain=*/1, in_decl); + tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl); TREE_TYPE (r) = new_type; CLASSTYPE_TI_TEMPLATE (new_type) = r; DECL_TEMPLATE_RESULT (r) = TYPE_MAIN_DECL (new_type); @@ -5657,7 +5686,7 @@ tsubst_decl (t, args, type) } else { - tree new_decl = tsubst (decl, args, /*complain=*/1, in_decl); + tree new_decl = tsubst (decl, args, complain, in_decl); DECL_TEMPLATE_RESULT (r) = new_decl; DECL_TI_TEMPLATE (new_decl) = r; @@ -5674,7 +5703,7 @@ tsubst_decl (t, args, type) outermost level of parameters. */ DECL_TEMPLATE_PARMS (r) = tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args, - /*complain=*/1); + complain); if (PRIMARY_TEMPLATE_P (t)) DECL_PRIMARY_TEMPLATE (r) = r; @@ -5714,7 +5743,7 @@ tsubst_decl (t, args, type) argvec = tsubst_template_arg_vector (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (gen_tmpl)), - args, /*complain=*/1); + args, complain); /* Check to see if we already have this specialization. */ spec = retrieve_specialization (gen_tmpl, argvec); @@ -5791,7 +5820,7 @@ tsubst_decl (t, args, type) else member = 1; ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, - /*complain=*/1, t, + complain, t, /*entering_scope=*/1); } else @@ -5799,7 +5828,7 @@ tsubst_decl (t, args, type) member = 0; ctx = DECL_CONTEXT (t); } - type = tsubst (type, args, /*complain=*/1, in_decl); + type = tsubst (type, args, complain, in_decl); if (type == error_mark_node) return error_mark_node; @@ -5817,7 +5846,7 @@ tsubst_decl (t, args, type) DECL_CONTEXT (r) = ctx; DECL_VIRTUAL_CONTEXT (r) = tsubst_aggr_type (DECL_VIRTUAL_CONTEXT (t), args, - /*complain=*/1, t, + complain, t, /*entering_scope=*/1); if (member && DECL_CONV_FN_P (r)) @@ -5826,7 +5855,7 @@ tsubst_decl (t, args, type) DECL_NAME (r) = mangle_conv_op_name_for_type (TREE_TYPE (type)); DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args, - /*complain=*/1, t); + complain, t); DECL_RESULT (r) = NULL_TREE; TREE_STATIC (r) = 0; @@ -5842,7 +5871,7 @@ tsubst_decl (t, args, type) if (DECL_CLONED_FUNCTION (r)) { DECL_CLONED_FUNCTION (r) = tsubst (DECL_CLONED_FUNCTION (t), - args, /*complain=*/1, t); + args, complain, t); TREE_CHAIN (r) = TREE_CHAIN (DECL_CLONED_FUNCTION (r)); TREE_CHAIN (DECL_CLONED_FUNCTION (r)) = r; } @@ -5881,7 +5910,7 @@ tsubst_decl (t, args, type) { *friends = copy_node (*friends); TREE_VALUE (*friends) = tsubst (TREE_VALUE (*friends), - args, /*complain=*/1, + args, complain, in_decl); } @@ -5914,7 +5943,7 @@ tsubst_decl (t, args, type) DECL_INITIAL (r) = TREE_TYPE (r); else DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args, - /*complain=*/1, in_decl); + complain, in_decl); DECL_CONTEXT (r) = NULL_TREE; if (!DECL_TEMPLATE_PARM_P (r) && PROMOTE_PROTOTYPES @@ -5923,7 +5952,7 @@ tsubst_decl (t, args, type) DECL_ARG_TYPE (r) = integer_type_node; if (TREE_CHAIN (t)) TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args, - /*complain=*/1, TREE_CHAIN (t)); + complain, TREE_CHAIN (t)); } break; @@ -5936,7 +5965,7 @@ tsubst_decl (t, args, type) /* We don't have to set DECL_CONTEXT here; it is set by finish_member_declaration. */ DECL_INITIAL (r) = tsubst_expr (DECL_INITIAL (t), args, - /*complain=*/1, in_decl); + complain, in_decl); TREE_CHAIN (r) = NULL_TREE; if (VOID_TYPE_P (type)) cp_error_at ("instantiation of `%D' as type `%T'", r, type); @@ -5947,7 +5976,7 @@ tsubst_decl (t, args, type) { r = copy_node (t); DECL_INITIAL (r) - = tsubst_copy (DECL_INITIAL (t), args, /*complain=*/1, in_decl); + = tsubst_copy (DECL_INITIAL (t), args, complain, in_decl); TREE_CHAIN (r) = NULL_TREE; } break; @@ -5980,7 +6009,7 @@ tsubst_decl (t, args, type) if (TYPE_P (CP_DECL_CONTEXT (t))) ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, - /*complain=*/1, + complain, in_decl, /*entering_scope=*/1); else if (DECL_NAMESPACE_SCOPE_P (t)) ctx = DECL_CONTEXT (t); @@ -5996,7 +6025,7 @@ tsubst_decl (t, args, type) { tmpl = DECL_TI_TEMPLATE (t); gen_tmpl = most_general_template (tmpl); - argvec = tsubst (DECL_TI_ARGS (t), args, /*complain=*/1, in_decl); + argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl); spec = retrieve_specialization (gen_tmpl, argvec); } else @@ -6022,15 +6051,6 @@ tsubst_decl (t, args, type) SET_DECL_RTL (r, NULL_RTX); DECL_SIZE (r) = DECL_SIZE_UNIT (r) = 0; - /* For __PRETTY_FUNCTION__ we have to adjust the initializer. */ - if (DECL_PRETTY_FUNCTION_P (r)) - { - const char *const name = (*decl_printable_name) - (current_function_decl, 2); - DECL_INITIAL (r) = cp_fname_init (name); - TREE_TYPE (r) = TREE_TYPE (DECL_INITIAL (r)); - } - /* Even if the original location is out of scope, the newly substituted one is not. */ if (TREE_CODE (r) == VAR_DECL) @@ -6074,7 +6094,7 @@ static tree tsubst_arg_types (arg_types, args, complain, in_decl) tree arg_types; tree args; - int complain; + tsubst_flags_t complain; tree in_decl; { tree remaining_arg_types; @@ -6093,7 +6113,7 @@ tsubst_arg_types (arg_types, args, complain, in_decl) return error_mark_node; if (VOID_TYPE_P (type)) { - if (complain) + if (complain & tf_error) { error ("invalid parameter type `%T'", type); if (in_decl) @@ -6135,7 +6155,7 @@ static tree tsubst_function_type (t, args, complain, in_decl) tree t; tree args; - int complain; + tsubst_flags_t complain; tree in_decl; { tree return_type; @@ -6171,7 +6191,7 @@ tsubst_function_type (t, args, complain, in_decl) -- Attempting to create "pointer to member of T" when T is not a class type. */ - if (complain) + if (complain & tf_error) error ("creating pointer to member function of non-class type `%T'", r); return error_mark_node; @@ -6180,7 +6200,7 @@ tsubst_function_type (t, args, complain, in_decl) fntype = build_cplus_method_type (r, return_type, TREE_CHAIN (arg_types)); } - fntype = build_qualified_type (fntype, TYPE_QUALS (t)); + fntype = cp_build_qualified_type_real (fntype, TYPE_QUALS (t), complain); fntype = build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t)); return fntype; @@ -6192,7 +6212,7 @@ static tree tsubst_call_declarator_parms (parms, args, complain, in_decl) tree parms; tree args; - int complain; + tsubst_flags_t complain; tree in_decl; { tree new_parms; @@ -6226,15 +6246,15 @@ tsubst_call_declarator_parms (parms, args, complain, in_decl) /* Take the tree structure T and replace template parameters used therein with the argument vector ARGS. IN_DECL is an associated decl for diagnostics. If an error occurs, returns ERROR_MARK_NODE. - An appropriate error message is issued only if COMPLAIN is - non-zero. Note that we must be relatively non-tolerant of - extensions here, in order to preserve conformance; if we allow - substitutions that should not be allowed, we may allow argument - deductions that should not succeed, and therefore report ambiguous - overload situations where there are none. In theory, we could - allow the substitution, but indicate that it should have failed, - and allow our caller to make sure that the right thing happens, but - we don't try to do this yet. + Issue error and warning messages under control of COMPLAIN. Note + that we must be relatively non-tolerant of extensions here, in + order to preserve conformance; if we allow substitutions that + should not be allowed, we may allow argument deductions that should + not succeed, and therefore report ambiguous overload situations + where there are none. In theory, we could allow the substitution, + but indicate that it should have failed, and allow our caller to + make sure that the right thing happens, but we don't try to do this + yet. This function is used for dealing with types, decls and the like; for expressions, use tsubst_expr or tsubst_copy. */ @@ -6242,7 +6262,7 @@ tsubst_call_declarator_parms (parms, args, complain, in_decl) tree tsubst (t, args, complain, in_decl) tree t, args; - int complain; + tsubst_flags_t complain; tree in_decl; { tree type, r; @@ -6272,7 +6292,7 @@ tsubst (t, args, complain, in_decl) return error_mark_node; if (DECL_P (t)) - return tsubst_decl (t, args, type); + return tsubst_decl (t, args, type, complain); switch (TREE_CODE (t)) { @@ -6348,7 +6368,7 @@ tsubst (t, args, complain, in_decl) Attempting to create an array with a size that is zero or negative. */ - if (complain) + if (complain & tf_error) error ("creating array with size zero (`%E')", max); return error_mark_node; @@ -6398,7 +6418,7 @@ tsubst (t, args, complain, in_decl) my_friendly_assert (TYPE_P (arg), 0); return cp_build_qualified_type_real (arg, cp_type_quals (arg) | cp_type_quals (t), - complain); + complain | tf_ignore_bad_quals); } else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM) { @@ -6422,9 +6442,8 @@ tsubst (t, args, complain, in_decl) DECL_CONTEXT (arg), /*entering_scope=*/0, complain); - return cp_build_qualified_type_real (r, - TYPE_QUALS (t), - complain); + return cp_build_qualified_type_real + (r, TYPE_QUALS (t), complain); } else /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX. */ @@ -6451,8 +6470,10 @@ tsubst (t, args, complain, in_decl) if (cp_type_quals (t)) { r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl); - r = cp_build_qualified_type_real (r, cp_type_quals (t), - complain); + r = cp_build_qualified_type_real + (r, cp_type_quals (t), + complain | (TREE_CODE (t) == TEMPLATE_TYPE_PARM + ? tf_ignore_bad_quals : 0)); } else { @@ -6583,8 +6604,8 @@ tsubst (t, args, complain, in_decl) /* We keep track of the last time we issued this error message to avoid spewing a ton of messages during a single bad template instantiation. */ - if (complain && (last_line != lineno || - last_file != input_filename)) + if (complain & tf_error + && (last_line != lineno || last_file != input_filename)) { if (TREE_CODE (type) == VOID_TYPE) error ("forming reference to void"); @@ -6626,9 +6647,8 @@ tsubst (t, args, complain, in_decl) -- Attempting to create "pointer to member of T" when T is not a class type. */ - if (complain) - error ("creating pointer to member of non-class type `%T'", - r); + if (complain & tf_error) + error ("creating pointer to member of non-class type `%T'", r); return error_mark_node; } if (TREE_CODE (type) == REFERENCE_TYPE) @@ -6711,7 +6731,7 @@ tsubst (t, args, complain, in_decl) || TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == REFERENCE_TYPE) { - if (complain) + if (complain & tf_error) error ("creating array of `%T'", type); return error_mark_node; } @@ -6723,10 +6743,8 @@ tsubst (t, args, complain, in_decl) case PLUS_EXPR: case MINUS_EXPR: { - tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, - in_decl); - tree e2 = tsubst (TREE_OPERAND (t, 1), args, complain, - in_decl); + tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); + tree e2 = tsubst (TREE_OPERAND (t, 1), args, complain, in_decl); if (e1 == error_mark_node || e2 == error_mark_node) return error_mark_node; @@ -6737,8 +6755,7 @@ tsubst (t, args, complain, in_decl) case NEGATE_EXPR: case NOP_EXPR: { - tree e = tsubst (TREE_OPERAND (t, 0), args, complain, - in_decl); + tree e = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); if (e == error_mark_node) return error_mark_node; @@ -6757,7 +6774,7 @@ tsubst (t, args, complain, in_decl) if (!IS_AGGR_TYPE (ctx)) { - if (complain) + if (complain & tf_error) error ("`%T' is not a class, struct, or union type", ctx); return error_mark_node; @@ -6775,21 +6792,26 @@ tsubst (t, args, complain, in_decl) ctx = complete_type (ctx); if (!COMPLETE_TYPE_P (ctx)) { - if (complain) + if (complain & tf_error) incomplete_type_error (NULL_TREE, ctx); return error_mark_node; } } - f = make_typename_type (ctx, f, complain); + f = make_typename_type (ctx, f, + (complain & tf_error) | tf_keep_type_decl); if (f == error_mark_node) return f; - return cp_build_qualified_type_real (f, - cp_type_quals (f) - | cp_type_quals (t), - complain); + if (TREE_CODE (f) == TYPE_DECL) + { + complain |= tf_ignore_bad_quals; + f = TREE_TYPE (f); + } + + return cp_build_qualified_type_real + (f, cp_type_quals (f) | cp_type_quals (t), complain); } - + case UNBOUND_CLASS_TEMPLATE: { tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain, @@ -6804,8 +6826,7 @@ tsubst (t, args, complain, in_decl) case INDIRECT_REF: { - tree e = tsubst (TREE_OPERAND (t, 0), args, complain, - in_decl); + tree e = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); if (e == error_mark_node) return error_mark_node; return make_pointer_declarator (type, e); @@ -6813,8 +6834,7 @@ tsubst (t, args, complain, in_decl) case ADDR_EXPR: { - tree e = tsubst (TREE_OPERAND (t, 0), args, complain, - in_decl); + tree e = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); if (e == error_mark_node) return error_mark_node; return make_reference_declarator (type, e); @@ -6822,10 +6842,8 @@ tsubst (t, args, complain, in_decl) case ARRAY_REF: { - tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, - in_decl); - tree e2 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, - in_decl); + tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); + tree e2 = tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl); if (e1 == error_mark_node || e2 == error_mark_node) return error_mark_node; @@ -6834,8 +6852,7 @@ tsubst (t, args, complain, in_decl) case CALL_EXPR: { - tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, - in_decl); + tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); tree e2 = (tsubst_call_declarator_parms (CALL_DECLARATOR_PARMS (t), args, complain, in_decl)); tree e3 = tsubst (CALL_DECLARATOR_EXCEPTION_SPEC (t), args, @@ -6850,8 +6867,7 @@ tsubst (t, args, complain, in_decl) case SCOPE_REF: { - tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, - in_decl); + tree e1 = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); tree e2 = tsubst (TREE_OPERAND (t, 1), args, complain, in_decl); if (e1 == error_mark_node || e2 == error_mark_node) return error_mark_node; @@ -6861,8 +6877,7 @@ tsubst (t, args, complain, in_decl) case TYPEOF_TYPE: { - tree e1 = tsubst_expr (TYPE_FIELDS (t), args, complain, - in_decl); + tree e1 = tsubst_expr (TYPE_FIELDS (t), args, complain, in_decl); if (e1 == error_mark_node) return error_mark_node; @@ -6883,7 +6898,7 @@ tsubst (t, args, complain, in_decl) tree tsubst_copy (t, args, complain, in_decl) tree t, args; - int complain; + tsubst_flags_t complain; tree in_decl; { enum tree_code code; @@ -7102,8 +7117,7 @@ tsubst_copy (t, args, complain, in_decl) if (!processing_template_decl) { tree stmt_expr = begin_stmt_expr (); - tsubst_expr (STMT_EXPR_STMT (t), args, - complain, in_decl); + tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl); return finish_stmt_expr (stmt_expr); } @@ -7228,8 +7242,8 @@ tsubst_copy (t, args, complain, in_decl) case VA_ARG_EXPR: return build_x_va_arg (tsubst_copy (TREE_OPERAND (t, 0), args, complain, - in_decl), - tsubst (TREE_TYPE (t), args, complain, in_decl)); + in_decl), + tsubst (TREE_TYPE (t), args, complain, in_decl)); default: return t; @@ -7241,7 +7255,7 @@ tsubst_copy (t, args, complain, in_decl) tree tsubst_expr (t, args, complain, in_decl) tree t, args; - int complain; + tsubst_flags_t complain; tree in_decl; { tree stmt, tmp; @@ -7261,7 +7275,7 @@ tsubst_expr (t, args, complain, in_decl) prep_stmt (t); finish_named_return_value (TREE_OPERAND (t, 0), - tsubst_expr (TREE_OPERAND (t, 1), args, /*complain=*/1, in_decl)); + tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl)); break; case CTOR_INITIALIZER: @@ -7317,10 +7331,6 @@ tsubst_expr (t, args, complain, in_decl) { init = DECL_INITIAL (decl); decl = tsubst (decl, args, complain, in_decl); - if (DECL_PRETTY_FUNCTION_P (decl)) - init = DECL_INITIAL (decl); - else - init = tsubst_expr (init, args, complain, in_decl); if (decl != error_mark_node) { if (TREE_CODE (decl) != TYPE_DECL) @@ -7336,6 +7346,17 @@ tsubst_expr (t, args, complain, in_decl) if (TREE_CODE (decl) == VAR_DECL) DECL_TEMPLATE_INSTANTIATED (decl) = 1; maybe_push_decl (decl); + if (DECL_PRETTY_FUNCTION_P (decl)) + { + /* For __PRETTY_FUNCTION__ we have to adjust the + initializer. */ + const char *const name + = (*decl_printable_name) (current_function_decl, 2); + init = cp_fname_init (name); + TREE_TYPE (decl) = TREE_TYPE (init); + } + else + init = tsubst_expr (init, args, complain, in_decl); cp_finish_decl (decl, init, NULL_TREE, 0); } } @@ -7355,8 +7376,8 @@ tsubst_expr (t, args, complain, in_decl) stmt = begin_for_stmt (); tsubst_expr (FOR_INIT_STMT (t), args, complain, in_decl); finish_for_init_stmt (stmt); - finish_for_cond (tsubst_expr (FOR_COND (t), args, - complain, in_decl), + finish_for_cond (tsubst_expr (FOR_COND (t), + args, complain, in_decl), stmt); tmp = tsubst_expr (FOR_EXPR (t), args, complain, in_decl); finish_for_expr (tmp, stmt); @@ -7383,8 +7404,8 @@ tsubst_expr (t, args, complain, in_decl) stmt = begin_do_stmt (); tsubst_expr (DO_BODY (t), args, complain, in_decl); finish_do_body (stmt); - finish_do_stmt (tsubst_expr (DO_COND (t), args, - complain, in_decl), + finish_do_stmt (tsubst_expr (DO_COND (t), + args, complain, in_decl), stmt); } break; @@ -7636,7 +7657,7 @@ instantiate_template (tmpl, targ_ptr) /* substitute template parameters */ fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl), - targ_ptr, /*complain=*/1, gen_tmpl); + targ_ptr, tf_error, gen_tmpl); /* The DECL_TI_TEMPLATE should always be the immediate parent template, not the most general template. */ DECL_TI_TEMPLATE (fndecl) = tmpl; @@ -7733,12 +7754,12 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type, converted_args = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn), - explicit_targs, NULL_TREE, /*complain=*/0, + explicit_targs, NULL_TREE, tf_none, /*require_all_arguments=*/0)); if (converted_args == error_mark_node) return 1; - fntype = tsubst (fntype, converted_args, /*complain=*/0, NULL_TREE); + fntype = tsubst (fntype, converted_args, tf_none, NULL_TREE); if (fntype == error_mark_node) return 1; @@ -7779,7 +7800,7 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type, the corresponding deduced argument values. If the substitution results in an invalid type, as described above, type deduction fails. */ - if (tsubst (TREE_TYPE (fn), targs, /*complain=*/0, NULL_TREE) + if (tsubst (TREE_TYPE (fn), targs, tf_none, NULL_TREE) == error_mark_node) return 1; @@ -8115,8 +8136,7 @@ resolve_overloaded_unification (tparms, targs, parm, arg, strict, expl_subargs); if (subargs) { - elem = tsubst (TREE_TYPE (fn), subargs, /*complain=*/0, - NULL_TREE); + elem = tsubst (TREE_TYPE (fn), subargs, tf_none, NULL_TREE); if (TREE_CODE (elem) == METHOD_TYPE) elem = build_ptrmemfunc_type (build_pointer_type (elem)); good += try_one_overload (tparms, targs, tempargs, parm, elem, @@ -8254,7 +8274,7 @@ verify_class_unification (targs, parms, args) int i; int nparms = TREE_VEC_LENGTH (parms); tree new_parms = tsubst (parms, add_outermost_template_args (args, targs), - /*complain=*/0, NULL_TREE); + tf_none, NULL_TREE); if (new_parms == error_mark_node) return 1; @@ -8470,12 +8490,28 @@ check_cv_quals_for_unify (strict, arg, parm) tree arg; tree parm; { + int arg_quals = cp_type_quals (arg); + int parm_quals = cp_type_quals (parm); + + if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM) + { + /* If the cvr quals of parm will not unify with ARG, they'll be + ignored in instantiation, so we have to do the same here. */ + if (TREE_CODE (arg) == REFERENCE_TYPE + || TREE_CODE (arg) == FUNCTION_TYPE + || TREE_CODE (arg) == METHOD_TYPE) + parm_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); + if (!POINTER_TYPE_P (arg) && + TREE_CODE (arg) != TEMPLATE_TYPE_PARM) + parm_quals &= ~TYPE_QUAL_RESTRICT; + } + if (!(strict & (UNIFY_ALLOW_MORE_CV_QUAL | UNIFY_ALLOW_OUTER_MORE_CV_QUAL)) - && !at_least_as_qualified_p (arg, parm)) + && (arg_quals & parm_quals) != parm_quals) return 0; if (!(strict & (UNIFY_ALLOW_LESS_CV_QUAL | UNIFY_ALLOW_OUTER_LESS_CV_QUAL)) - && !at_least_as_qualified_p (parm, arg)) + && (parm_quals & arg_quals) != arg_quals) return 0; return 1; @@ -8678,11 +8714,8 @@ unify (tparms, targs, parm, arg, strict) /* Consider the case where ARG is `const volatile int' and PARM is `const T'. Then, T should be `volatile int'. */ - arg = - cp_build_qualified_type_real (arg, - cp_type_quals (arg) - & ~cp_type_quals (parm), - /*complain=*/0); + arg = cp_build_qualified_type_real + (arg, cp_type_quals (arg) & ~cp_type_quals (parm), tf_none); if (arg == error_mark_node) return 1; @@ -9152,13 +9185,11 @@ get_bindings_real (fn, decl, explicit_args, check_rettype, deduce, len) converted_args = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl), explicit_args, NULL_TREE, - /*complain=*/0, - /*require_all_arguments=*/0)); + tf_none, /*require_all_arguments=*/0)); if (converted_args == error_mark_node) return NULL_TREE; - decl_type = tsubst (decl_type, converted_args, /*complain=*/0, - NULL_TREE); + decl_type = tsubst (decl_type, converted_args, tf_none, NULL_TREE); if (decl_type == error_mark_node) return NULL_TREE; } @@ -9514,7 +9545,7 @@ do_decl_instantiation (declspecs, declarator, storage) ; else if (storage == ridpointers[(int) RID_EXTERN]) { - if (pedantic) + if (pedantic && !in_system_header) pedwarn ("ISO C++ forbids the use of `extern' on explicit instantiations"); extern_p = 1; } @@ -9553,7 +9584,7 @@ mark_class_instantiated (t, extern_p) void do_type_instantiation (t, storage, complain) tree t, storage; - int complain; + tsubst_flags_t complain; { int extern_p = 0; int nomem_p = 0; @@ -9577,7 +9608,7 @@ do_type_instantiation (t, storage, complain) if (!COMPLETE_TYPE_P (t)) { - if (complain) + if (complain & tf_error) error ("explicit instantiation of `%#T' before definition of template", t); return; @@ -9585,7 +9616,7 @@ do_type_instantiation (t, storage, complain) if (storage != NULL_TREE) { - if (pedantic) + if (pedantic && !in_system_header) pedwarn("ISO C++ forbids the use of `%s' on explicit instantiations", IDENTIFIER_POINTER (storage)); @@ -9609,7 +9640,7 @@ do_type_instantiation (t, storage, complain) No program shall both explicitly instantiate and explicitly specialize a template. */ - if (complain) + if (complain & tf_error) { error ("explicit instantiation of `%#T' after", t); cp_error_at ("explicit specialization here", t); @@ -9628,7 +9659,7 @@ do_type_instantiation (t, storage, complain) are we already got marked as an explicit instantiation because of the repo file. All these cases are OK. */ if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository - && complain) + && (complain & tf_error)) pedwarn ("duplicate explicit instantiation of `%#T'", t); /* If we've already instantiated the template, just return now. */ @@ -9748,14 +9779,14 @@ regenerate_decl_from_template (decl, tmpl) pushclass (DECL_CONTEXT (decl), 2); /* Do the substitution to get the new declaration. */ - new_decl = tsubst (code_pattern, args, /*complain=*/1, NULL_TREE); + new_decl = tsubst (code_pattern, args, tf_error, NULL_TREE); if (TREE_CODE (decl) == VAR_DECL) { /* Set up DECL_INITIAL, since tsubst doesn't. */ DECL_INITIAL (new_decl) = tsubst_expr (DECL_INITIAL (code_pattern), args, - /*complain=*/1, DECL_TI_TEMPLATE (decl)); + tf_error, DECL_TI_TEMPLATE (decl)); /* Pop the class context we pushed above. */ popclass (); } @@ -9942,6 +9973,27 @@ instantiate_decl (d, defer_ok) import_export_decl (d); } + if (!defer_ok) + { + /* Recheck the substitutions to obtain any warning messages + about ignoring cv qualifiers. */ + tree gen = DECL_TEMPLATE_RESULT (gen_tmpl); + tree type = TREE_TYPE (gen); + + if (TREE_CODE (gen) == FUNCTION_DECL) + { + tsubst (DECL_ARGUMENTS (gen), args, tf_error | tf_warning, d); + tsubst (TYPE_RAISES_EXCEPTIONS (type), args, + tf_error | tf_warning, d); + /* Don't simply tsubst the function type, as that will give + duplicate warnings about poor parameter qualifications. + The function arguments are the same as the decl_arguments + without the top level cv qualifiers. */ + type = TREE_TYPE (type); + } + tsubst (type, args, tf_error | tf_warning, d); + } + if (TREE_CODE (d) == VAR_DECL && DECL_INITIALIZED_IN_CLASS_P (d) && DECL_INITIAL (d) == NULL_TREE) /* We should have set up DECL_INITIAL in instantiate_class_template. */ @@ -10025,7 +10077,7 @@ instantiate_decl (d, defer_ok) /* Substitute into the body of the function. */ tsubst_expr (DECL_SAVED_TREE (code_pattern), args, - /*complain=*/1, tmpl); + tf_error | tf_warning, tmpl); /* We don't need the local specializations any more. */ htab_delete (local_specializations); @@ -10157,9 +10209,9 @@ tsubst_initializer_list (t, argvec) tree init; tree val; - decl = tsubst_copy (TREE_PURPOSE (t), argvec, /*complain=*/1, + decl = tsubst_copy (TREE_PURPOSE (t), argvec, tf_error | tf_warning, NULL_TREE); - init = tsubst_expr (TREE_VALUE (t), argvec, /*complain=*/1, + init = tsubst_expr (TREE_VALUE (t), argvec, tf_error | tf_warning, NULL_TREE); if (!init) @@ -10209,7 +10261,7 @@ tsubst_enum (tag, newtag, args) /* Note that in a template enum, the TREE_VALUE is the CONST_DECL, not the corresponding INTEGER_CST. */ value = tsubst_expr (DECL_INITIAL (TREE_VALUE (e)), - args, /*complain=*/1, + args, tf_error | tf_warning, NULL_TREE); /* Give this enumeration constant the correct access. */ @@ -10278,16 +10330,16 @@ get_mostly_instantiated_function_type (decl, contextp, tparmsp) /* Now, do the (partial) substitution to figure out the appropriate function type. */ - fn_type = tsubst (fn_type, partial_args, /*complain=*/1, NULL_TREE); + fn_type = tsubst (fn_type, partial_args, tf_error, NULL_TREE); if (DECL_STATIC_FUNCTION_P (decl)) - context = tsubst (context, partial_args, /*complain=*/1, NULL_TREE); + context = tsubst (context, partial_args, tf_error, NULL_TREE); /* Substitute into the template parameters to obtain the real innermost set of parameters. This step is important if the innermost set of template parameters contains value parameters whose types depend on outer template parameters. */ TREE_VEC_LENGTH (partial_args)--; - tparms = tsubst_template_parms (tparms, partial_args, /*complain=*/1); + tparms = tsubst_template_parms (tparms, partial_args, tf_error); } if (contextp) @@ -10320,13 +10372,13 @@ current_instantiation () } /* [temp.param] Check that template non-type parm TYPE is of an allowable - type. Return zero for ok, non-zero for disallowed. If COMPLAIN is - non-zero, then complain. */ + type. Return zero for ok, non-zero for disallowed. Issue error and + warning messages under control of COMPLAIN. */ static int invalid_nontype_parm_type_p (type, complain) tree type; - int complain; + tsubst_flags_t complain; { if (INTEGRAL_TYPE_P (type)) return 0; @@ -10341,7 +10393,7 @@ invalid_nontype_parm_type_p (type, complain) else if (TREE_CODE (type) == TYPENAME_TYPE) return 0; - if (complain) + if (complain & tf_error) error ("`%#T' is not a valid type for a template constant parameter", type); return 1; diff --git a/contrib/gcc/cp/search.c b/contrib/gcc/cp/search.c index 10ebc73..ab6e25d 100644 --- a/contrib/gcc/cp/search.c +++ b/contrib/gcc/cp/search.c @@ -127,7 +127,6 @@ static int protected_accessible_p PARAMS ((tree, tree, tree)); static int friend_accessible_p PARAMS ((tree, tree, tree)); static void setup_class_bindings PARAMS ((tree, int)); static int template_self_reference_p PARAMS ((tree, tree)); -static tree get_shared_vbase_if_not_primary PARAMS ((tree, void *)); static tree dfs_find_vbase_instance PARAMS ((tree, void *)); static tree dfs_get_pure_virtuals PARAMS ((tree, void *)); static tree dfs_build_inheritance_graph_order PARAMS ((tree, void *)); @@ -201,8 +200,9 @@ lookup_base_r (binfo, base, access, within_current_scope, && !within_current_scope && is_friend (BINFO_TYPE (binfo), current_scope ())) { + /* Do not clear is_non_public here. If A is a private base of B, A + is not allowed to convert a B* to an A*. */ within_current_scope = 1; - is_non_public = 0; } if (same_type_p (BINFO_TYPE (binfo), base)) @@ -1841,7 +1841,7 @@ check_final_overrider (overrider, basefn) return 0; } - /* Check throw specifier is subset. */ + /* Check throw specifier is at least as strict. */ if (!comp_except_specs (base_throw, over_throw, 0)) { cp_error_at ("looser throw specifier for `%#F'", overrider); @@ -1951,81 +1951,30 @@ look_for_overrides_r (type, fndecl) return look_for_overrides (type, fndecl); } -/* A queue function for dfs_walk that skips any nonprimary virtual - bases and any already marked bases. */ +/* A queue function to use with dfs_walk that only walks into + canonical bases. DATA should be the type of the complete object, + or a TREE_LIST whose TREE_PURPOSE is the type of the complete + object. By using this function as a queue function, you will walk + over exactly those BINFOs that actually exist in the complete + object, including those for virtual base classes. If you + SET_BINFO_MARKED for each binfo you process, you are further + guaranteed that you will walk into each virtual base class exactly + once. */ tree -dfs_skip_nonprimary_vbases_unmarkedp (binfo, data) - tree binfo; - void *data ATTRIBUTE_UNUSED; -{ - if (TREE_VIA_VIRTUAL (binfo) && !BINFO_PRIMARY_P (binfo)) - /* This is a non-primary virtual base. Skip it. */ - return NULL_TREE; - - return unmarkedp (binfo, NULL); -} - -/* A queue function for dfs_walk that skips any nonprimary virtual - bases and any unmarked bases. */ - -tree -dfs_skip_nonprimary_vbases_markedp (binfo, data) - tree binfo; - void *data ATTRIBUTE_UNUSED; -{ - if (TREE_VIA_VIRTUAL (binfo) && !BINFO_PRIMARY_P (binfo)) - /* This is a non-primary virtual base. Skip it. */ - return NULL_TREE; - - return markedp (binfo, NULL); -} - -/* If BINFO is a non-primary virtual baseclass (in the hierarchy - dominated by TYPE), and no primary copy appears anywhere in the - hierarchy, return the shared copy. If a primary copy appears - elsewhere, return NULL_TREE. Otherwise, return BINFO itself; it is - either a non-virtual base or a primary virtual base. */ - -static tree -get_shared_vbase_if_not_primary (binfo, data) +dfs_unmarked_real_bases_queue_p (binfo, data) tree binfo; void *data; { - if (TREE_VIA_VIRTUAL (binfo) && !BINFO_PRIMARY_P (binfo)) + if (TREE_VIA_VIRTUAL (binfo)) { tree type = (tree) data; if (TREE_CODE (type) == TREE_LIST) type = TREE_PURPOSE (type); - - /* This is a non-primary virtual base. If there is no primary - version, get the shared version. */ binfo = binfo_for_vbase (BINFO_TYPE (binfo), type); - if (BINFO_PRIMARY_P (binfo)) - return NULL_TREE; } - - return binfo; -} - -/* A queue function to use with dfs_walk that prevents travel into any - nonprimary virtual base, or its baseclasses. DATA should be the - type of the complete object, or a TREE_LIST whose TREE_PURPOSE is - the type of the complete object. By using this function as a queue - function, you will walk over exactly those BINFOs that actually - exist in the complete object, including those for virtual base - classes. If you SET_BINFO_MARKED for each binfo you process, you - are further guaranteed that you will walk into each virtual base - class exactly once. */ - -tree -dfs_unmarked_real_bases_queue_p (binfo, data) - tree binfo; - void *data; -{ - binfo = get_shared_vbase_if_not_primary (binfo, data); - return binfo ? unmarkedp (binfo, NULL) : NULL_TREE; + return unmarkedp (binfo, NULL); } /* Like dfs_unmarked_real_bases_queue_p but walks only into things @@ -2036,8 +1985,15 @@ dfs_marked_real_bases_queue_p (binfo, data) tree binfo; void *data; { - binfo = get_shared_vbase_if_not_primary (binfo, data); - return binfo ? markedp (binfo, NULL) : NULL_TREE; + if (TREE_VIA_VIRTUAL (binfo)) + { + tree type = (tree) data; + + if (TREE_CODE (type) == TREE_LIST) + type = TREE_PURPOSE (type); + binfo = binfo_for_vbase (BINFO_TYPE (binfo), type); + } + return markedp (binfo, NULL); } /* A queue function that skips all virtual bases (and their @@ -2436,14 +2392,14 @@ setup_class_bindings (name, type_binding_p) if (type_binding_p && (TREE_CODE (value_binding) == TYPE_DECL + || DECL_CLASS_TEMPLATE_P (value_binding) || (TREE_CODE (value_binding) == TREE_LIST && TREE_TYPE (value_binding) == error_mark_node && (TREE_CODE (TREE_VALUE (value_binding)) == TYPE_DECL)))) /* We found a type-binding, even when looking for a non-type binding. This means that we already processed this binding - above. */ - my_friendly_assert (type_binding_p, 19990401); + above. */; else if (value_binding) { if (TREE_CODE (value_binding) == TREE_LIST diff --git a/contrib/gcc/cp/semantics.c b/contrib/gcc/cp/semantics.c index 603326c..43d3074 100644 --- a/contrib/gcc/cp/semantics.c +++ b/contrib/gcc/cp/semantics.c @@ -205,6 +205,7 @@ finish_expr_stmt (expr) tree expr; { tree r = NULL_TREE; + tree expr_type = NULL_TREE;; if (expr != NULL_TREE) { @@ -215,6 +216,9 @@ finish_expr_stmt (expr) || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE)) expr = default_conversion (expr); + /* Remember the type of the expression. */ + expr_type = TREE_TYPE (expr); + if (stmts_are_full_exprs_p ()) expr = convert_to_void (expr, "statement"); @@ -225,7 +229,7 @@ finish_expr_stmt (expr) /* This was an expression-statement, so we save the type of the expression. */ - last_expr_type = expr ? TREE_TYPE (expr) : NULL_TREE; + last_expr_type = expr_type; return r; } @@ -500,7 +504,7 @@ tree begin_switch_stmt () { tree r; - r = build_stmt (SWITCH_STMT, NULL_TREE, NULL_TREE); + r = build_stmt (SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE); add_stmt (r); do_pushlevel (); return r; @@ -513,9 +517,9 @@ finish_switch_cond (cond, switch_stmt) tree cond; tree switch_stmt; { + tree orig_type = NULL; if (!processing_template_decl) { - tree type; tree index; /* Convert the condition to an integer or enumeration type. */ @@ -525,23 +529,27 @@ finish_switch_cond (cond, switch_stmt) error ("switch quantity not an integer"); cond = error_mark_node; } + orig_type = TREE_TYPE (cond); if (cond != error_mark_node) { cond = default_conversion (cond); cond = fold (build1 (CLEANUP_POINT_EXPR, TREE_TYPE (cond), cond)); } - type = TREE_TYPE (cond); - index = get_unwidened (cond, NULL_TREE); - /* We can't strip a conversion from a signed type to an unsigned, - because if we did, int_fits_type_p would do the wrong thing - when checking case values for being in range, - and it's too hard to do the right thing. */ - if (TREE_UNSIGNED (TREE_TYPE (cond)) - == TREE_UNSIGNED (TREE_TYPE (index))) - cond = index; + if (cond != error_mark_node) + { + index = get_unwidened (cond, NULL_TREE); + /* We can't strip a conversion from a signed type to an unsigned, + because if we did, int_fits_type_p would do the wrong thing + when checking case values for being in range, + and it's too hard to do the right thing. */ + if (TREE_UNSIGNED (TREE_TYPE (cond)) + == TREE_UNSIGNED (TREE_TYPE (index))) + cond = index; + } } FINISH_COND (cond, switch_stmt, SWITCH_COND (switch_stmt)); + SWITCH_TYPE (switch_stmt) = orig_type; push_switch (switch_stmt); } @@ -1205,7 +1213,7 @@ begin_global_stmt_expr () keep_next_level (1); - return (last_tree != NULL_TREE) ? last_tree : expand_start_stmt_expr(); + return last_tree ? last_tree : expand_start_stmt_expr(/*has_scope=*/1); } /* Finish the STMT_EXPR last begun with begin_global_stmt_expr. */ @@ -1498,32 +1506,13 @@ decl_type_access_control (decl) added to type_lookups after typed_declspecs saved the copy that ended up in current_type_lookups. */ type_lookups = current_type_lookups; - - current_type_lookups = NULL_TREE; } -/* Record the lookups, if we're doing deferred access control. */ - void save_type_access_control (lookups) tree lookups; { - if (type_lookups != error_mark_node) - { - my_friendly_assert (!current_type_lookups, 20010301); - current_type_lookups = lookups; - } - else - my_friendly_assert (!lookups || lookups == error_mark_node, 20010301); -} - -/* Set things up so that the next deferred access control will succeed. - This is needed for friend declarations see grokdeclarator for details. */ - -void -skip_type_access_control () -{ - type_lookups = NULL_TREE; + current_type_lookups = lookups; } /* Reset the deferred access control. */ @@ -1907,8 +1896,6 @@ finish_class_definition (t, attributes, semi, pop_scope_p) check_for_missing_semicolon (t); if (pop_scope_p) pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (t))); - if (current_function_decl) - type_lookups = error_mark_node; if (current_scope () == current_function_decl) do_pending_defargs (); @@ -2142,10 +2129,6 @@ cp_expand_stmt (t) { switch (TREE_CODE (t)) { - case CLEANUP_STMT: - genrtl_decl_cleanup (CLEANUP_DECL (t), CLEANUP_EXPR (t)); - break; - case CTOR_STMT: genrtl_ctor_stmt (t); break; @@ -2397,9 +2380,6 @@ expand_body (fn) if (DECL_EXTERNAL (fn)) return; - /* Emit any thunks that should be emitted at the same time as FN. */ - emit_associated_thunks (fn); - timevar_push (TV_INTEGRATION); /* Optimize the body of the function before expanding it. */ @@ -2452,6 +2432,9 @@ expand_body (fn) extract_interface_info (); timevar_pop (TV_EXPAND); + + /* Emit any thunks that should be emitted at the same time as FN. */ + emit_associated_thunks (fn); } /* Helper function for walk_tree, used by finish_function to override all @@ -2474,7 +2457,7 @@ nullify_returns_r (tp, walk_subtrees, data) RETURN_EXPR (*tp) = NULL_TREE; else if (TREE_CODE (*tp) == CLEANUP_STMT && CLEANUP_DECL (*tp) == nrv) - CLEANUP_EXPR (*tp) = NULL_TREE; + CLEANUP_EH_ONLY (*tp) = 1; /* Keep iterating. */ return NULL_TREE; @@ -2521,15 +2504,16 @@ genrtl_start_function (fn) if (!current_function_cannot_inline) current_function_cannot_inline = cp_function_chain->cannot_inline; - /* We don't need the saved data anymore. */ - free (DECL_SAVED_FUNCTION_DATA (fn)); - DECL_SAVED_FUNCTION_DATA (fn) = NULL; + /* We don't need the saved data anymore. Unless this is an inline + function; we need the named return value info for + cp_copy_res_decl_for_inlining. */ + if (! DECL_INLINE (fn)) + { + free (DECL_SAVED_FUNCTION_DATA (fn)); + DECL_SAVED_FUNCTION_DATA (fn) = NULL; + } } - /* Tell the cross-reference machinery that we're defining this - function. */ - GNU_xref_function (fn, DECL_ARGUMENTS (fn)); - /* Keep track of how many functions we're presently expanding. */ ++function_depth; diff --git a/contrib/gcc/cp/spew.c b/contrib/gcc/cp/spew.c index e610aec..212dada 100644 --- a/contrib/gcc/cp/spew.c +++ b/contrib/gcc/cp/spew.c @@ -221,16 +221,11 @@ read_process_identifier (pyylval) case RID_NOT_EQ: pyylval->code = NE_EXPR; return EQCOMPARE; default: - if (C_RID_YYCODE (id) == TYPESPEC) - GNU_xref_ref (current_function_decl, IDENTIFIER_POINTER (id)); - pyylval->ttype = ridpointers[C_RID_CODE (id)]; return C_RID_YYCODE (id); } } - GNU_xref_ref (current_function_decl, IDENTIFIER_POINTER (id)); - /* Make sure that user does not collide with our internal naming scheme. This is not necessary if '.' is used to remove them from the user's namespace, but is if '$' or double underscores are. */ diff --git a/contrib/gcc/cp/tree.c b/contrib/gcc/cp/tree.c index d353b06..d703b8a 100644 --- a/contrib/gcc/cp/tree.c +++ b/contrib/gcc/cp/tree.c @@ -464,7 +464,12 @@ build_cplus_array_type_1 (elt_type, index_type) if (elt_type == error_mark_node || index_type == error_mark_node) return error_mark_node; - if (processing_template_decl + /* Don't do the minimal thing just because processing_template_decl is + set; we want to give string constants the right type immediately, so + we don't have to fix them up at instantiation time. */ + if ((processing_template_decl + && index_type && TYPE_MAX_VALUE (index_type) + && TREE_CODE (TYPE_MAX_VALUE (index_type)) != INTEGER_CST) || uses_template_parms (elt_type) || uses_template_parms (index_type)) { @@ -505,18 +510,32 @@ build_cplus_array_type (elt_type, index_type) /* Make a variant of TYPE, qualified with the TYPE_QUALS. Handles arrays correctly. In particular, if TYPE is an array of T's, and - TYPE_QUALS is non-empty, returns an array of qualified T's. If - at attempt is made to qualify a type illegally, and COMPLAIN is - non-zero, an error is issued. If COMPLAIN is zero, error_mark_node - is returned. */ - + TYPE_QUALS is non-empty, returns an array of qualified T's. + + FLAGS determines how to deal with illformed qualifications. If + tf_ignore_bad_quals is set, then bad qualifications are dropped + (this is permitted if TYPE was introduced via a typedef or template + type parameter). If bad qualifications are dropped and tf_warning + is set, then a warning is issued for non-const qualifications. If + tf_ignore_bad_quals is not set and tf_error is not set, we + return error_mark_node. Otherwise, we issue an error, and ignore + the qualifications. + + Qualification of a reference type is valid when the reference came + via a typedef or template type argument. [dcl.ref] No such + dispensation is provided for qualifying a function type. [dcl.fct] + DR 295 queries this and the proposed resolution brings it into line + with qualifiying a reference. We implement the DR. We also behave + in a similar manner for restricting non-pointer types. */ + tree cp_build_qualified_type_real (type, type_quals, complain) tree type; int type_quals; - int complain; + tsubst_flags_t complain; { tree result; + int bad_quals = TYPE_UNQUALIFIED; if (type == error_mark_node) return type; @@ -524,32 +543,51 @@ cp_build_qualified_type_real (type, type_quals, complain) if (type_quals == cp_type_quals (type)) return type; - /* A restrict-qualified pointer type must be a pointer (or reference) + /* A reference, fucntion or method type shall not be cv qualified. + [dcl.ref], [dct.fct] */ + if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE) + && (TREE_CODE (type) == REFERENCE_TYPE + || TREE_CODE (type) == FUNCTION_TYPE + || TREE_CODE (type) == METHOD_TYPE)) + { + bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); + type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); + } + + /* A restrict-qualified type must be a pointer (or reference) to object or incomplete type. */ if ((type_quals & TYPE_QUAL_RESTRICT) && TREE_CODE (type) != TEMPLATE_TYPE_PARM - && (!POINTER_TYPE_P (type) - || TYPE_PTRMEM_P (type) - || TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)) + && TREE_CODE (type) != TYPENAME_TYPE + && !POINTER_TYPE_P (type)) { - if (complain) - error ("`%T' cannot be `restrict'-qualified", type); - else - return error_mark_node; - + bad_quals |= TYPE_QUAL_RESTRICT; type_quals &= ~TYPE_QUAL_RESTRICT; } - if (type_quals != TYPE_UNQUALIFIED - && TREE_CODE (type) == FUNCTION_TYPE) + if (bad_quals == TYPE_UNQUALIFIED) + /*OK*/; + else if (!(complain & (tf_error | tf_ignore_bad_quals))) + return error_mark_node; + else { - if (complain) - error ("`%T' cannot be `const'-, `volatile'-, or `restrict'-qualified", type); - else - return error_mark_node; - type_quals = TYPE_UNQUALIFIED; + if (complain & tf_ignore_bad_quals) + /* We're not going to warn about constifying things that can't + be constified. */ + bad_quals &= ~TYPE_QUAL_CONST; + if (bad_quals) + { + tree bad_type = build_qualified_type (ptr_type_node, bad_quals); + + if (!(complain & tf_ignore_bad_quals)) + error ("`%V' qualifiers cannot be applied to `%T'", + bad_type, type); + else if (complain & tf_warning) + warning ("ignoring `%V' qualifiers on `%T'", bad_type, type); + } } - else if (TREE_CODE (type) == ARRAY_TYPE) + + if (TREE_CODE (type) == ARRAY_TYPE) { /* In C++, the qualification really applies to the array element type. Obtain the appropriately qualified element type. */ @@ -591,7 +629,7 @@ cp_build_qualified_type_real (type, type_quals, complain) { /* For a pointer-to-member type, we can't just return a cv-qualified version of the RECORD_TYPE. If we do, we - haven't change the field that contains the actual pointer to + haven't changed the field that contains the actual pointer to a method, and so TYPE_PTRMEMFUNC_FN_TYPE will be wrong. */ tree t; @@ -599,7 +637,7 @@ cp_build_qualified_type_real (type, type_quals, complain) t = cp_build_qualified_type_real (t, type_quals, complain); return build_ptrmemfunc_type (t); } - + /* Retrieve (or create) the appropriately qualified variant. */ result = build_qualified_type (type, type_quals); @@ -999,7 +1037,6 @@ cp_statement_code_p (code) switch (code) { case SUBOBJECT: - case CLEANUP_STMT: case CTOR_STMT: case CTOR_INITIALIZER: case RETURN_INIT: @@ -2100,6 +2137,10 @@ cp_cannot_inline_tree_fn (fnp) { tree fn = *fnp; + if (flag_really_no_inline + && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL) + return 1; + /* We can inline a template instantiation only if it's fully instantiated. */ if (DECL_TEMPLATE_INFO (fn) diff --git a/contrib/gcc/cp/typeck.c b/contrib/gcc/cp/typeck.c index 5e69b98..fc37236 100644 --- a/contrib/gcc/cp/typeck.c +++ b/contrib/gcc/cp/typeck.c @@ -45,7 +45,7 @@ Boston, MA 02111-1307, USA. */ static tree convert_for_assignment PARAMS ((tree, tree, const char *, tree, int)); -static tree pointer_int_sum PARAMS ((enum tree_code, tree, tree)); +static tree cp_pointer_int_sum PARAMS ((enum tree_code, tree, tree)); static tree rationalize_conditional_expr PARAMS ((enum tree_code, tree)); static int comp_target_parms PARAMS ((tree, tree)); static int comp_ptr_ttypes_real PARAMS ((tree, tree, int)); @@ -285,7 +285,7 @@ commonparms (p1, p2) if (TREE_VALUE (p1) != TREE_VALUE (p2)) { any_change = 1; - TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2)); + TREE_VALUE (n) = merge_types (TREE_VALUE (p1), TREE_VALUE (p2)); } else TREE_VALUE (n) = TREE_VALUE (p1); @@ -330,16 +330,38 @@ type_after_usual_arithmetic_conversions (t1, t2) /* FIXME: Attributes. */ my_friendly_assert (ARITHMETIC_TYPE_P (t1) + || TREE_CODE (t1) == COMPLEX_TYPE || TREE_CODE (t1) == ENUMERAL_TYPE, 19990725); my_friendly_assert (ARITHMETIC_TYPE_P (t2) + || TREE_CODE (t2) == COMPLEX_TYPE || TREE_CODE (t2) == ENUMERAL_TYPE, 19990725); - /* In what follows, we slightly generalize the rules given in [expr] - so as to deal with `long long'. First, merge the attributes. */ + /* In what follows, we slightly generalize the rules given in [expr] so + as to deal with `long long' and `complex'. First, merge the + attributes. */ attributes = (*targetm.merge_type_attributes) (t1, t2); + /* If one type is complex, form the common type of the non-complex + components, then make that complex. Use T1 or T2 if it is the + required type. */ + if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE) + { + tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1; + tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2; + tree subtype + = type_after_usual_arithmetic_conversions (subtype1, subtype2); + + if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype) + return build_type_attribute_variant (t1, attributes); + else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype) + return build_type_attribute_variant (t2, attributes); + else + return build_type_attribute_variant (build_complex_type (subtype), + attributes); + } + /* If only one is real, use it as the result. */ if (code1 == REAL_TYPE && code2 != REAL_TYPE) return build_type_attribute_variant (t1, attributes); @@ -359,6 +381,10 @@ type_after_usual_arithmetic_conversions (t1, t2) else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1)) return build_type_attribute_variant (t2, attributes); + /* The types are the same; no need to do anything fancy. */ + if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) + return build_type_attribute_variant (t1, attributes); + if (code1 != REAL_TYPE) { /* If one is a sizetype, use it so size_binop doesn't blow up. */ @@ -420,9 +446,17 @@ type_after_usual_arithmetic_conversions (t1, t2) || same_type_p (TYPE_MAIN_VARIANT (t2), double_type_node)) return build_type_attribute_variant (double_type_node, attributes); - else + if (same_type_p (TYPE_MAIN_VARIANT (t1), float_type_node) + || same_type_p (TYPE_MAIN_VARIANT (t2), float_type_node)) return build_type_attribute_variant (float_type_node, attributes); + + /* Two floating-point types whose TYPE_MAIN_VARIANTs are none of + the standard C++ floating-point types. Logic earlier in this + function has already eliminated the possibility that + TYPE_PRECISION (t2) != TYPE_PRECISION (t1), so there's no + compelling reason to choose one or the other. */ + return build_type_attribute_variant (t1, attributes); } } @@ -439,6 +473,7 @@ composite_pointer_type (t1, t2, arg1, arg2, location) const char* location; { tree result_type; + tree attributes; /* [expr.rel] @@ -456,6 +491,9 @@ composite_pointer_type (t1, t2, arg1, arg2, location) if (TYPE_PTRMEMFUNC_P (t2)) t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2); + /* Merge the attributes. */ + attributes = (*targetm.merge_type_attributes) (t1, t2); + /* We have: [expr.rel] @@ -504,21 +542,18 @@ composite_pointer_type (t1, t2, arg1, arg2, location) } } - return result_type; + return build_type_attribute_variant (result_type, attributes); } -/* Return the common type of two types. +/* Return the merged type of two types. We assume that comptypes has already been done and returned 1; if that isn't so, this may crash. - This is the type for the result of most arithmetic operations - if the operands have the given two types. - - We do not deal with enumeral types here because they have already been - converted to integer types. */ + This just combines attributes and default arguments; any other + differences would cause the two types to compare unalike. */ tree -common_type (t1, t2) +merge_types (t1, t2) tree t1, t2; { register enum tree_code code1; @@ -528,9 +563,7 @@ common_type (t1, t2) /* Save time if the two types are the same. */ if (t1 == t2) return t1; - t1 = original_type (t1); - t2 = original_type (t2); - if (t1 == t2) + if (original_type (t1) == original_type (t2)) return t1; /* If one type is nonsense, use the other. */ @@ -539,20 +572,11 @@ common_type (t1, t2) if (t2 == error_mark_node) return t1; - if ((ARITHMETIC_TYPE_P (t1) || TREE_CODE (t1) == ENUMERAL_TYPE) - && (ARITHMETIC_TYPE_P (t2) || TREE_CODE (t2) == ENUMERAL_TYPE)) - return type_after_usual_arithmetic_conversions (t1, t2); - /* Merge the attributes. */ attributes = (*targetm.merge_type_attributes) (t1, t2); /* Treat an enum type as the unsigned integer type of the same width. */ - if (TREE_CODE (t1) == ENUMERAL_TYPE) - t1 = type_for_size (TYPE_PRECISION (t1), 1); - if (TREE_CODE (t2) == ENUMERAL_TYPE) - t2 = type_for_size (TYPE_PRECISION (t2), 1); - if (TYPE_PTRMEMFUNC_P (t1)) t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1); if (TYPE_PTRMEMFUNC_P (t2)) @@ -561,88 +585,21 @@ common_type (t1, t2) code1 = TREE_CODE (t1); code2 = TREE_CODE (t2); - /* If one type is complex, form the common type of the non-complex - components, then make that complex. Use T1 or T2 if it is the - required type. */ - if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE) - { - tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1; - tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2; - tree subtype = common_type (subtype1, subtype2); - - if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype) - return build_type_attribute_variant (t1, attributes); - else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype) - return build_type_attribute_variant (t2, attributes); - else - return build_type_attribute_variant (build_complex_type (subtype), - attributes); - } - switch (code1) { - case INTEGER_TYPE: - case REAL_TYPE: - /* We should have called type_after_usual_arithmetic_conversions - above. */ - abort (); - break; - case POINTER_TYPE: case REFERENCE_TYPE: - /* For two pointers, do this recursively on the target type, - and combine the qualifiers of the two types' targets. */ - /* This code was turned off; I don't know why. - But ISO C++ specifies doing this with the qualifiers. - So I turned it on again. */ + /* For two pointers, do this recursively on the target type. */ { - tree tt1 = TREE_TYPE (t1); - tree tt2 = TREE_TYPE (t2); - tree b1, b2; - int type_quals; - tree target; - - if (TREE_CODE (tt1) == OFFSET_TYPE) - { - b1 = TYPE_OFFSET_BASETYPE (tt1); - b2 = TYPE_OFFSET_BASETYPE (tt2); - tt1 = TREE_TYPE (tt1); - tt2 = TREE_TYPE (tt2); - } - else - b1 = b2 = NULL_TREE; - - type_quals = (cp_type_quals (tt1) | cp_type_quals (tt2)); - tt1 = TYPE_MAIN_VARIANT (tt1); - tt2 = TYPE_MAIN_VARIANT (tt2); - - if (tt1 == tt2) - target = tt1; - else if (VOID_TYPE_P (tt1) || VOID_TYPE_P (tt2)) - target = void_type_node; - else if (tt1 == unknown_type_node) - target = tt2; - else if (tt2 == unknown_type_node) - target = tt1; - else - target = common_type (tt1, tt2); - - target = cp_build_qualified_type (target, type_quals); - - if (b1) - { - if (same_type_p (b1, b2) - || (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2))) - target = build_offset_type (b2, target); - else if (binfo_or_else (b2, b1)) - target = build_offset_type (b1, target); - } + tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2)); + int quals = cp_type_quals (t1); if (code1 == POINTER_TYPE) t1 = build_pointer_type (target); else t1 = build_reference_type (target); t1 = build_type_attribute_variant (t1, attributes); + t1 = cp_build_qualified_type (t1, quals); if (TREE_CODE (target) == METHOD_TYPE) t1 = build_ptrmemfunc_type (t1); @@ -650,9 +607,17 @@ common_type (t1, t2) return t1; } + case OFFSET_TYPE: + { + tree base = TYPE_OFFSET_BASETYPE (t1); + tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2)); + t1 = build_offset_type (base, target); + break; + } + case ARRAY_TYPE: { - tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2)); + tree elt = merge_types (TREE_TYPE (t1), TREE_TYPE (t2)); /* Save space: see if the result is identical to one of the args. */ if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1)) return build_type_attribute_variant (t1, attributes); @@ -661,14 +626,14 @@ common_type (t1, t2) /* Merge the element types, and have a size if either arg has one. */ t1 = build_cplus_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2)); - return build_type_attribute_variant (t1, attributes); + break; } case FUNCTION_TYPE: /* Function types: prefer the one that specified arg types. If both do, merge the arg types. Also merge the return types. */ { - tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2)); + tree valtype = merge_types (TREE_TYPE (t1), TREE_TYPE (t2)); tree p1 = TYPE_ARG_TYPES (t1); tree p2 = TYPE_ARG_TYPES (t2); tree rval, raises; @@ -697,73 +662,72 @@ common_type (t1, t2) } rval = build_function_type (valtype, commonparms (p1, p2)); - rval = build_exception_variant (rval, raises); - return build_type_attribute_variant (rval, attributes); + t1 = build_exception_variant (rval, raises); + break; } - case RECORD_TYPE: - case UNION_TYPE: - t1 = TYPE_MAIN_VARIANT (t1); - t2 = TYPE_MAIN_VARIANT (t2); + case METHOD_TYPE: + { + /* Get this value the long way, since TYPE_METHOD_BASETYPE + is just the main variant of this. */ + tree basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2))); + tree raises = TYPE_RAISES_EXCEPTIONS (t1); + tree t3; + + /* If this was a member function type, get back to the + original type of type member function (i.e., without + the class instance variable up front. */ + t1 = build_function_type (TREE_TYPE (t1), + TREE_CHAIN (TYPE_ARG_TYPES (t1))); + t2 = build_function_type (TREE_TYPE (t2), + TREE_CHAIN (TYPE_ARG_TYPES (t2))); + t3 = merge_types (t1, t2); + t3 = build_cplus_method_type (basetype, TREE_TYPE (t3), + TYPE_ARG_TYPES (t3)); + t1 = build_exception_variant (t3, raises); + break; + } - if (DERIVED_FROM_P (t1, t2) && binfo_or_else (t1, t2)) - return build_type_attribute_variant (t1, attributes); - else if (binfo_or_else (t2, t1)) - return build_type_attribute_variant (t2, attributes); - else - { - compiler_error ("common_type called with uncommon aggregate types"); - return error_mark_node; - } + default:; + } + return build_type_attribute_variant (t1, attributes); +} - case METHOD_TYPE: - if (TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2))) - { - /* Get this value the long way, since TYPE_METHOD_BASETYPE - is just the main variant of this. */ - tree basetype; - tree raises, t3; +/* Return the common type of two types. + We assume that comptypes has already been done and returned 1; + if that isn't so, this may crash. - tree b1 = TYPE_OFFSET_BASETYPE (t1); - tree b2 = TYPE_OFFSET_BASETYPE (t2); + This is the type for the result of most arithmetic operations + if the operands have the given two types. */ - if (same_type_p (b1, b2) - || (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2))) - basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2))); - else - { - if (binfo_or_else (b2, b1) == NULL_TREE) - compiler_error ("common_type called with uncommon method types"); - basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t1))); - } +tree +common_type (t1, t2) + tree t1, t2; +{ + enum tree_code code1; + enum tree_code code2; - raises = TYPE_RAISES_EXCEPTIONS (t1); - - /* If this was a member function type, get back to the - original type of type member function (i.e., without - the class instance variable up front. */ - t1 = build_function_type (TREE_TYPE (t1), - TREE_CHAIN (TYPE_ARG_TYPES (t1))); - t2 = build_function_type (TREE_TYPE (t2), - TREE_CHAIN (TYPE_ARG_TYPES (t2))); - t3 = common_type (t1, t2); - t3 = build_cplus_method_type (basetype, TREE_TYPE (t3), - TYPE_ARG_TYPES (t3)); - t1 = build_exception_variant (t3, raises); - } - else - compiler_error ("common_type called with uncommon method types"); + /* If one type is nonsense, bail. */ + if (t1 == error_mark_node || t2 == error_mark_node) + return error_mark_node; - return build_type_attribute_variant (t1, attributes); + code1 = TREE_CODE (t1); + code2 = TREE_CODE (t2); - case OFFSET_TYPE: - /* Pointers to members should now be handled by the POINTER_TYPE - case above. */ - abort (); + if ((ARITHMETIC_TYPE_P (t1) || code1 == ENUMERAL_TYPE + || code1 == COMPLEX_TYPE) + && (ARITHMETIC_TYPE_P (t2) || code2 == ENUMERAL_TYPE + || code2 == COMPLEX_TYPE)) + return type_after_usual_arithmetic_conversions (t1, t2); - default: - return build_type_attribute_variant (t1, attributes); - } + else if ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2)) + || (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (t2)) + || (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2))) + return composite_pointer_type (t1, t2, error_mark_node, error_mark_node, + "conversion"); + + else + abort (); } /* Compare two exception specifier types for exactness or subsetness, if @@ -1037,20 +1001,6 @@ comptypes (t1, t2, strict) && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict)); break; - case METHOD_TYPE: - if (! comp_except_specs (TYPE_RAISES_EXCEPTIONS (t1), - TYPE_RAISES_EXCEPTIONS (t2), 1)) - return 0; - - /* This case is anti-symmetrical! - One can pass a base member (or member function) - to something expecting a derived member (or member function), - but not vice-versa! */ - - val = (comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict) - && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2))); - break; - case POINTER_TYPE: case REFERENCE_TYPE: t1 = TREE_TYPE (t1); @@ -1065,11 +1015,8 @@ comptypes (t1, t2, strict) goto look_hard; break; + case METHOD_TYPE: case FUNCTION_TYPE: - if (! comp_except_specs (TYPE_RAISES_EXCEPTIONS (t1), - TYPE_RAISES_EXCEPTIONS (t2), 1)) - return 0; - val = ((TREE_TYPE (t1) == TREE_TYPE (t2) || comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict)) && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2))); @@ -1999,6 +1946,8 @@ build_component_ref (datum, component, basetype_path, protect) register tree ref; tree field_type; int type_quals; + tree old_datum; + tree old_basetype; if (processing_template_decl) return build_min_nt (COMPONENT_REF, datum, component); @@ -2202,6 +2151,9 @@ build_component_ref (datum, component, basetype_path, protect) if (TREE_DEPRECATED (field)) warn_deprecated_use (field); + old_datum = datum; + old_basetype = basetype; + /* See if we have to do any conversions so that we pick up the field from the right context. */ if (DECL_FIELD_CONTEXT (field) != basetype) @@ -2215,12 +2167,17 @@ build_component_ref (datum, component, basetype_path, protect) /* Handle base classes here... */ if (base != basetype && TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (basetype)) { - tree binfo = lookup_base (TREE_TYPE (datum), base, ba_check, NULL); - + base_kind kind; + tree binfo = lookup_base (TREE_TYPE (datum), base, ba_check, &kind); + + /* Complain about use of offsetof which will break. */ if (TREE_CODE (datum) == INDIRECT_REF - && integer_zerop (TREE_OPERAND (datum, 0))) + && integer_zerop (TREE_OPERAND (datum, 0)) + && kind == bk_via_virtual) { - error ("invalid reference to NULL ptr, use ptr-to-member instead"); + error ("\ +invalid offsetof from non-POD type `%#T'; use pointer to member instead", + basetype); return error_mark_node; } datum = build_base_path (PLUS_EXPR, datum, binfo, 1); @@ -2239,6 +2196,18 @@ build_component_ref (datum, component, basetype_path, protect) } } + /* Complain about other invalid uses of offsetof, even though they will + give the right answer. Note that we complain whether or not they + actually used the offsetof macro, since there's no way to know at this + point. So we just give a warning, instead of a pedwarn. */ + if (protect + && CLASSTYPE_NON_POD_P (old_basetype) + && TREE_CODE (old_datum) == INDIRECT_REF + && integer_zerop (TREE_OPERAND (old_datum, 0))) + warning ("\ +invalid offsetof from non-POD type `%#T'; use pointer to member instead", + basetype); + /* Compute the type of the field, as described in [expr.ref]. */ type_quals = TYPE_UNQUALIFIED; field_type = TREE_TYPE (field); @@ -2904,19 +2873,18 @@ get_member_function_from_ptrfunc (instance_ptrptr, function) load-with-sign-extend, while the second used normal load then shift to sign-extend. An optimizer flaw, perhaps, but it's easier to make this change. */ + idx = cp_build_binary_op (TRUNC_DIV_EXPR, + build1 (NOP_EXPR, vtable_index_type, e3), + TYPE_SIZE_UNIT (vtable_entry_type)); switch (TARGET_PTRMEMFUNC_VBIT_LOCATION) { case ptrmemfunc_vbit_in_pfn: - idx = cp_build_binary_op (TRUNC_DIV_EXPR, - build1 (NOP_EXPR, vtable_index_type, e3), - TYPE_SIZE_UNIT (vtable_entry_type)); e1 = cp_build_binary_op (BIT_AND_EXPR, build1 (NOP_EXPR, vtable_index_type, e3), integer_one_node); break; case ptrmemfunc_vbit_in_delta: - idx = build1 (NOP_EXPR, vtable_index_type, e3); e1 = cp_build_binary_op (BIT_AND_EXPR, delta, integer_one_node); delta = cp_build_binary_op (RSHIFT_EXPR, @@ -2991,10 +2959,6 @@ build_function_call_real (function, params, require_complete, flags) name = DECL_NAME (function); assembler_name = DECL_ASSEMBLER_NAME (function); - GNU_xref_call (current_function_decl, - IDENTIFIER_POINTER (name ? name - : TYPE_IDENTIFIER (DECL_CLASS_CONTEXT - (function)))); mark_used (function); fndecl = function; @@ -3396,7 +3360,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) /* DTRT if one side is an overloaded function, but complain about it. */ if (type_unknown_p (op0)) { - tree t = instantiate_type (TREE_TYPE (op1), op0, itf_none); + tree t = instantiate_type (TREE_TYPE (op1), op0, tf_none); if (t != error_mark_node) { pedwarn ("assuming cast to type `%T' from overloaded function", @@ -3406,7 +3370,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) } if (type_unknown_p (op1)) { - tree t = instantiate_type (TREE_TYPE (op0), op1, itf_none); + tree t = instantiate_type (TREE_TYPE (op0), op1, tf_none); if (t != error_mark_node) { pedwarn ("assuming cast to type `%T' from overloaded function", @@ -3434,9 +3398,9 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) case PLUS_EXPR: /* Handle the pointer + int case. */ if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - return pointer_int_sum (PLUS_EXPR, op0, op1); + return cp_pointer_int_sum (PLUS_EXPR, op0, op1); else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE) - return pointer_int_sum (PLUS_EXPR, op1, op0); + return cp_pointer_int_sum (PLUS_EXPR, op1, op0); else common = 1; break; @@ -3449,7 +3413,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) return pointer_diff (op0, op1, common_type (type0, type1)); /* Handle pointer minus int. Just like pointer plus int. */ else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - return pointer_int_sum (MINUS_EXPR, op0, op1); + return cp_pointer_int_sum (MINUS_EXPR, op0, op1); else common = 1; break; @@ -3496,31 +3460,6 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) case BIT_XOR_EXPR: if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) shorten = -1; - /* If one operand is a constant, and the other is a short type - that has been converted to an int, - really do the work in the short type and then convert the - result to int. If we are lucky, the constant will be 0 or 1 - in the short type, making the entire operation go away. */ - if (TREE_CODE (op0) == INTEGER_CST - && TREE_CODE (op1) == NOP_EXPR - && (TYPE_PRECISION (type1) - > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)))) - && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op1, 0)))) - { - final_type = result_type; - op1 = TREE_OPERAND (op1, 0); - result_type = TREE_TYPE (op1); - } - if (TREE_CODE (op1) == INTEGER_CST - && TREE_CODE (op0) == NOP_EXPR - && (TYPE_PRECISION (type0) - > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))) - && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0)))) - { - final_type = result_type; - op0 = TREE_OPERAND (op0, 0); - result_type = TREE_TYPE (op0); - } break; case TRUNC_MOD_EXPR: @@ -4079,94 +4018,20 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) of pointer PTROP and integer INTOP. */ static tree -pointer_int_sum (resultcode, ptrop, intop) +cp_pointer_int_sum (resultcode, ptrop, intop) enum tree_code resultcode; register tree ptrop, intop; { - tree size_exp; + tree res_type = TREE_TYPE (ptrop); - register tree result; - register tree folded = fold (intop); + /* pointer_int_sum() uses size_in_bytes() on the TREE_TYPE(res_type) + in certain circumstance (when it's valid to do so). So we need + to make sure it's complete. We don't need to check here, if we + can actually complete it at all, as those checks will be done in + pointer_int_sum() anyway. */ + complete_type (TREE_TYPE (res_type)); - /* The result is a pointer of the same type that is being added. */ - - register tree result_type = TREE_TYPE (ptrop); - - if (!complete_type_or_else (result_type, ptrop)) - return error_mark_node; - - if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("ISO C++ forbids using pointer of type `void *' in pointer arithmetic"); - size_exp = integer_one_node; - } - else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("ISO C++ forbids using a pointer-to-function in pointer arithmetic"); - size_exp = integer_one_node; - } - else if (TREE_CODE (TREE_TYPE (result_type)) == METHOD_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("ISO C++ forbids using a pointer to member function in pointer arithmetic"); - size_exp = integer_one_node; - } - else if (TREE_CODE (TREE_TYPE (result_type)) == OFFSET_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("ISO C++ forbids using pointer to a member in pointer arithmetic"); - size_exp = integer_one_node; - } - else - size_exp = size_in_bytes (complete_type (TREE_TYPE (result_type))); - - /* Needed to make OOPS V2R3 work. */ - intop = folded; - if (integer_zerop (intop)) - return ptrop; - - /* If what we are about to multiply by the size of the elements - contains a constant term, apply distributive law - and multiply that constant term separately. - This helps produce common subexpressions. */ - - if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR) - && ! TREE_CONSTANT (intop) - && TREE_CONSTANT (TREE_OPERAND (intop, 1)) - && TREE_CONSTANT (size_exp)) - { - enum tree_code subcode = resultcode; - if (TREE_CODE (intop) == MINUS_EXPR) - subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR); - ptrop = cp_build_binary_op (subcode, ptrop, TREE_OPERAND (intop, 1)); - intop = TREE_OPERAND (intop, 0); - } - - /* Convert the integer argument to a type the same size as sizetype - so the multiply won't overflow spuriously. */ - - if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)) - intop = cp_convert (type_for_size (TYPE_PRECISION (sizetype), 0), intop); - - /* Replace the integer argument with a suitable product by the object size. - Do this multiplication as signed, then convert to the appropriate - pointer type (actually unsigned integral). */ - - intop = cp_convert (result_type, - cp_build_binary_op (MULT_EXPR, intop, - cp_convert (TREE_TYPE (intop), - size_exp))); - - /* Create the sum or difference. */ - - result = build (resultcode, result_type, ptrop, intop); - - folded = fold (result); - if (folded == result) - TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop); - return folded; + return pointer_int_sum (resultcode, ptrop, fold (intop)); } /* Return a tree for the difference of pointers OP0 and OP1. @@ -5159,6 +5024,22 @@ build_static_cast (type, expr) && kind != bk_via_virtual) ok = 1; } + else if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype)) + { + /* They're pointers to members. The pointed to objects must be + the same (ignoring CV qualifiers), and the containing classes + must be related non-virtually. */ + base_kind kind; + + if (same_type_p + (strip_all_pointer_quals (TREE_TYPE (TREE_TYPE (type))), + strip_all_pointer_quals (TREE_TYPE (TREE_TYPE (intype)))) + && (lookup_base (TYPE_OFFSET_BASETYPE (TREE_TYPE (intype)), + TYPE_OFFSET_BASETYPE (TREE_TYPE (type)), + ba_ignore | ba_quiet, &kind)) + && kind != bk_via_virtual) + ok = 1; + } else if (TREE_CODE (intype) != BOOLEAN_TYPE && TREE_CODE (type) != ARRAY_TYPE && TREE_CODE (type) != FUNCTION_TYPE @@ -5726,8 +5607,6 @@ build_modify_expr (lhs, modifycode, rhs) if (!lvalue_or_else (lhs, "assignment")) return error_mark_node; - GNU_xref_assign (lhs); - /* Warn about modifying something that is `const'. Don't warn if this is initialization. */ if (modifycode != INIT_EXPR @@ -5777,15 +5656,16 @@ build_modify_expr (lhs, modifycode, rhs) { int from_array; - if (!same_or_base_type_p (lhstype, TREE_TYPE (rhs))) + if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype), + TYPE_MAIN_VARIANT (TREE_TYPE (rhs)))) { error ("incompatible types in assignment of `%T' to `%T'", - TREE_TYPE (rhs), lhstype); + TREE_TYPE (rhs), lhstype); return error_mark_node; } /* Allow array assignment in compiler-generated code. */ - if (pedantic && ! DECL_ARTIFICIAL (current_function_decl)) + if (! DECL_ARTIFICIAL (current_function_decl)) pedwarn ("ISO C++ forbids assignment of arrays"); from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE @@ -6090,7 +5970,7 @@ build_ptrmemfunc (type, pfn, force) } if (type_unknown_p (pfn)) - return instantiate_type (type, pfn, itf_complain); + return instantiate_type (type, pfn, tf_error | tf_warning); fn = TREE_OPERAND (pfn, 0); my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0); @@ -6318,7 +6198,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) overloaded function. Call instantiate_type to get error messages. */ if (rhstype == unknown_type_node) - instantiate_type (type, rhs, itf_complain); + instantiate_type (type, rhs, tf_error | tf_warning); else if (fndecl) error ("cannot convert `%T' to `%T' for argument `%P' to `%D'", rhstype, type, parmnum, fndecl); diff --git a/contrib/gcc/cp/typeck2.c b/contrib/gcc/cp/typeck2.c index 314685a..48caade 100644 --- a/contrib/gcc/cp/typeck2.c +++ b/contrib/gcc/cp/typeck2.c @@ -544,7 +544,7 @@ digest_init (type, init, tail) if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE || code == ENUMERAL_TYPE || code == REFERENCE_TYPE - || code == BOOLEAN_TYPE || code == COMPLEX_TYPE || code == VECTOR_TYPE + || code == BOOLEAN_TYPE || code == COMPLEX_TYPE || TYPE_PTRMEMFUNC_P (type)) { if (raw_constructor) @@ -578,7 +578,7 @@ digest_init (type, init, tail) return error_mark_node; } - if (code == ARRAY_TYPE || IS_AGGR_TYPE_CODE (code)) + if (code == ARRAY_TYPE || code == VECTOR_TYPE || IS_AGGR_TYPE_CODE (code)) { if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type) && TREE_HAS_CONSTRUCTOR (init)) @@ -659,18 +659,26 @@ process_init_constructor (type, init, elts) for each element of this aggregate. Chain them together in result. If there are too few, use 0 for each scalar ultimate component. */ - if (TREE_CODE (type) == ARRAY_TYPE) + if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE) { - tree domain = TYPE_DOMAIN (type); register long len; register int i; - if (domain) - len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain)) - - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain)) - + 1); + if (TREE_CODE (type) == ARRAY_TYPE) + { + tree domain = TYPE_DOMAIN (type); + if (domain) + len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain)) + - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain)) + + 1); + else + len = -1; /* Take as many as there are */ + } else - len = -1; /* Take as many as there are */ + { + /* Vectors are like simple fixed-size arrays. */ + len = TYPE_VECTOR_SUBPARTS (type); + } for (i = 0; len < 0 || i < len; i++) { |