diff options
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r-- | gcc/cp/decl2.c | 433 |
1 files changed, 165 insertions, 268 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 442b31bf37d..0f279bc0d53 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -283,10 +283,6 @@ int warn_overloaded_virtual; int warn_nonvdtor; -/* Non-zero means warn when a function is declared extern and later inline. */ - -int warn_extern_inline; - /* Non-zero means warn when the compiler will reorder code. */ int warn_reorder; @@ -337,20 +333,11 @@ int warn_deprecated = 1; #endif int dollars_in_ident = DOLLARS_IN_IDENTIFIERS; -/* Nonzero means that labels can be used as first-class objects */ - -int flag_labels_ok; - /* Nonzero means allow Microsoft extensions without a pedwarn. */ int flag_ms_extensions; /* C++ specific flags. */ -/* Zero means that `this' is a *const. This gives nice behavior in the - 2.0 world. 1 gives 1.2-compatible behavior. 2 gives Spring behavior. - -2 means we're constructing an object and it has fixed type. */ - -int flag_this_is_variable; /* Nonzero means we should attempt to elide constructors when possible. */ @@ -396,10 +383,6 @@ int flag_operator_names = 1; int flag_check_new; -/* Nonnull if we want to dump class heirarchies. */ - -const char *flag_dump_class_layout; - /* Nonzero if we want the new ISO rules for pushing a new scope for `for' initialization variables. 0: Old rules, set by -fno-for-scope. @@ -415,10 +398,6 @@ int flag_new_for_scope = 1; int flag_weak = 1; -/* Nonzero to enable experimental ABI changes. */ - -int flag_new_abi = 1; - /* Nonzero to use __cxa_atexit, rather than atexit, to register destructors for local statics and global objects. */ @@ -428,8 +407,10 @@ int flag_use_cxa_atexit; int flag_honor_std = ENABLE_STD_NAMESPACE; -/* Nonzero if we should expand functions calls inline at the tree - level, rather than at the RTL level. */ +/* 0 if we should not perform inlining. + 1 if we should expand functions calls inline at the tree level. + 2 if we should consider *all* functions to be inline + candidates. */ int flag_inline_trees = 0; @@ -439,17 +420,6 @@ int flag_inline_trees = 0; int max_tinst_depth = 50; -/* The name-mangling scheme to use. Must be 1 or greater to support - template functions with identical types, but different template - arguments. */ -int name_mangling_version = 2; - -/* Nonzero if squashed mangling is to be performed. - This uses the B and K codes to reference previously seen class types - and class qualifiers. */ - -int flag_do_squangling; - /* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc. */ int flag_vtable_gc; @@ -503,12 +473,9 @@ lang_f_options[] = {"for-scope", &flag_new_for_scope, 2}, {"gnu-keywords", &flag_no_gnu_keywords, 0}, {"handle-exceptions", &flag_exceptions, 1}, - {"honor-std", &flag_honor_std, 1}, - {"huge-objects", &flag_huge_objects, 1}, {"implement-inlines", &flag_implement_inlines, 1}, {"implicit-inline-templates", &flag_implicit_inline_templates, 1}, {"implicit-templates", &flag_implicit_templates, 1}, - {"labels-ok", &flag_labels_ok, 1}, {"ms-extensions", &flag_ms_extensions, 1}, {"nonansi-builtins", &flag_no_nonansi_builtin, 0}, {"operator-names", &flag_operator_names, 1}, @@ -516,13 +483,9 @@ lang_f_options[] = {"permissive", &flag_permissive, 1}, {"repo", &flag_use_repository, 1}, {"rtti", &flag_rtti, 1}, - {"squangle", &flag_do_squangling, 1}, {"stats", &flag_detailed_statistics, 1}, {"use-cxa-atexit", &flag_use_cxa_atexit, 1}, - {"vtable-gc", &flag_vtable_gc, 1}, - {"vtable-thunks", &flag_vtable_thunks, 1}, - {"weak", &flag_weak, 1}, - {"xref", &flag_gnu_xref, 1} + {"weak", &flag_weak, 1} }; /* The list of `-f' options that we no longer support. The `-f' @@ -533,9 +496,17 @@ static const char * const unsupported_options[] = { "cond-mismatch", "enum-int-equiv", "guiding-decls", + "honor-std", + "huge-objects", + "labels-ok", + "new-abi", "nonnull-objects", - "this-is-variable", + "squangle", "strict-prototype", + "this-is-variable", + "vtable-gc", + "vtable-thunks", + "xref" }; /* Compare two option strings, pointed two by P1 and P2, for use with @@ -620,43 +591,18 @@ cxx_decode_option (argc, argv) flag_external_templates = 1; cp_deprecated ("-fexternal-templates"); } - else if (!strcmp (p, "new-abi")) - { - flag_new_abi = 1; - flag_do_squangling = 1; - flag_vtable_thunks = 1; - } - else if (!strcmp (p, "no-new-abi")) - { - flag_new_abi = 0; - flag_do_squangling = 0; - } else if ((option_value = skip_leading_substring (p, "template-depth-"))) max_tinst_depth = read_integral_parameter (option_value, p - 2, max_tinst_depth); else if ((option_value = skip_leading_substring (p, "name-mangling-version-"))) - name_mangling_version - = read_integral_parameter (option_value, p - 2, name_mangling_version); - else if ((option_value - = skip_leading_substring (p, "dump-translation-unit="))) { - if (!*option_value) - error ("no file specified with -fdump-translation-unit"); - else - flag_dump_translation_unit = option_value; - } - else if ((option_value - = skip_leading_substring (p, "dump-class-layout="))) - { - if (!*option_value) - error ("no file specified with -fdump-class-layout"); - else - flag_dump_class_layout = option_value; + warning ("-fname-mangling-version is no longer supported"); + return 1; } - else if (!strcmp (p, "dump-class-layout")) - flag_dump_class_layout = ""; /* empty string for stderr */ + else if (dump_switch_p (p)) + ; else { int found = 0; @@ -745,8 +691,6 @@ cxx_decode_option (argc, argv) warn_parentheses = setting; else if (!strcmp (p, "non-virtual-dtor")) warn_nonvdtor = setting; - else if (!strcmp (p, "extern-inline")) - warn_extern_inline = setting; else if (!strcmp (p, "reorder")) warn_reorder = setting; else if (!strcmp (p, "synth")) @@ -949,7 +893,10 @@ build_artificial_parm (name, type) This function adds the "in-charge" flag to member function FN if appropriate. It is called from grokclassfn and tsubst. - FN must be either a constructor or destructor. */ + FN must be either a constructor or destructor. + + The in-charge flag follows the 'this' parameter, and is followed by the + VTT parm (if any), then the user-written parms. */ void maybe_retrofit_in_chrg (fn) @@ -972,17 +919,38 @@ maybe_retrofit_in_chrg (fn) && !TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) return; - /* First add it to DECL_ARGUMENTS... */ - parm = build_artificial_parm (in_charge_identifier, integer_type_node); - TREE_READONLY (parm) = 1; - parms = DECL_ARGUMENTS (fn); - TREE_CHAIN (parm) = TREE_CHAIN (parms); - TREE_CHAIN (parms) = parm; - - /* ...and then to TYPE_ARG_TYPES. */ arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn)); basetype = TREE_TYPE (TREE_VALUE (arg_types)); - arg_types = hash_tree_chain (integer_type_node, TREE_CHAIN (arg_types)); + arg_types = TREE_CHAIN (arg_types); + + parms = TREE_CHAIN (DECL_ARGUMENTS (fn)); + + /* If this is a subobject constructor or destructor, our caller will + pass us a pointer to our VTT. */ + if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) + { + parm = build_artificial_parm (vtt_parm_identifier, vtt_parm_type); + + /* First add it to DECL_ARGUMENTS between 'this' and the real args... */ + TREE_CHAIN (parm) = parms; + parms = parm; + + /* ...and then to TYPE_ARG_TYPES. */ + arg_types = hash_tree_chain (vtt_parm_type, arg_types); + + DECL_HAS_VTT_PARM_P (fn) = 1; + } + + /* Then add the in-charge parm (before the VTT parm). */ + parm = build_artificial_parm (in_charge_identifier, integer_type_node); + TREE_CHAIN (parm) = parms; + parms = parm; + arg_types = hash_tree_chain (integer_type_node, arg_types); + + /* Insert our new parameter(s) into the list. */ + TREE_CHAIN (DECL_ARGUMENTS (fn)) = parms; + + /* And rebuild the function type. */ fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)), arg_types); if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))) @@ -992,18 +960,6 @@ maybe_retrofit_in_chrg (fn) /* Now we've got the in-charge parameter. */ DECL_HAS_IN_CHARGE_PARM_P (fn) = 1; - - /* If this is a subobject constructor or destructor, our caller will - pass us a pointer to our VTT. */ - if (flag_new_abi && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) - { - DECL_VTT_PARM (fn) = build_artificial_parm (vtt_parm_identifier, - vtt_parm_type); - DECL_CONTEXT (DECL_VTT_PARM (fn)) = fn; - DECL_USE_VTT_PARM (fn) = build_artificial_parm (NULL_TREE, - boolean_type_node); - DECL_CONTEXT (DECL_USE_VTT_PARM (fn)) = fn; - } } /* Classes overload their constituent function names automatically. @@ -1037,7 +993,7 @@ grokclassfn (ctype, function, flags, quals) /* Even within an `extern "C"' block, members get C++ linkage. See [dcl.link] for details. */ - DECL_LANGUAGE (function) = lang_cplusplus; + SET_DECL_LANGUAGE (function, lang_cplusplus); if (fn_name == NULL_TREE) { @@ -1075,22 +1031,17 @@ grokclassfn (ctype, function, flags, quals) DECL_ARGUMENTS (function) = last_function_parms; DECL_CONTEXT (function) = ctype; + if (flags == DTOR_FLAG) + DECL_DESTRUCTOR_P (function) = 1; + if (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function)) maybe_retrofit_in_chrg (function); if (flags == DTOR_FLAG) { DECL_DESTRUCTOR_P (function) = 1; - - if (flag_new_abi) - set_mangled_name_for_decl (function); - else - DECL_ASSEMBLER_NAME (function) = build_destructor_name (ctype); - TYPE_HAS_DESTRUCTOR (ctype) = 1; } - else - set_mangled_name_for_decl (function); } /* Work on the expr used by alignof (this is only called by the parser). */ @@ -1103,7 +1054,7 @@ grok_alignof (expr) int bestalign; if (processing_template_decl) - return build_min (ALIGNOF_EXPR, sizetype, expr); + return build_min_nt (ALIGNOF_EXPR, expr); if (TREE_CODE (expr) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1))) @@ -1455,22 +1406,6 @@ check_classfn (ctype, function) fndecls = OVL_NEXT (fndecls)) { fndecl = OVL_CURRENT (fndecls); - /* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL, or - for a for member function of a template class, is - not mangled, so the check below does not work - correctly in that case. Since mangled destructor - names do not include the type of the arguments, - we can't use this short-cut for them, either. - (It's not legal to declare arguments for a - destructor, but some people try.) */ - if (!DECL_DESTRUCTOR_P (function) - && (DECL_ASSEMBLER_NAME (function) - != DECL_NAME (function)) - && (DECL_ASSEMBLER_NAME (fndecl) - != DECL_NAME (fndecl)) - && (DECL_ASSEMBLER_NAME (function) - == DECL_ASSEMBLER_NAME (fndecl))) - return fndecl; /* We cannot simply call decls_match because this doesn't work for static member functions that are @@ -1544,11 +1479,6 @@ finish_static_data_member_decl (decl, init, asmspec_tree, flags) tree asmspec_tree; int flags; { - const char *asmspec = 0; - - if (asmspec_tree) - asmspec = TREE_STRING_POINTER (asmspec_tree); - my_friendly_assert (TREE_PUBLIC (decl), 0); DECL_CONTEXT (decl) = current_class_type; @@ -1557,15 +1487,9 @@ finish_static_data_member_decl (decl, init, asmspec_tree, flags) decl of our TREE_CHAIN. Instead, we modify cp_finish_decl to do the right thing, namely, to put this decl out straight away. */ /* current_class_type can be NULL_TREE in case of error. */ - if (!asmspec && current_class_type) - { - DECL_INITIAL (decl) = error_mark_node; - if (flag_new_abi) - DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl); - else - DECL_ASSEMBLER_NAME (decl) - = build_static_name (current_class_type, DECL_NAME (decl)); - } + if (!asmspec_tree && current_class_type) + DECL_INITIAL (decl) = error_mark_node; + if (! processing_template_decl) { if (!pending_statics) @@ -1695,18 +1619,6 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist) if (CLASS_TYPE_P (TREE_TYPE (value))) CLASSTYPE_GOT_SEMICOLON (TREE_TYPE (value)) = 1; - /* Now that we've updated the context, we need to remangle the - name for this TYPE_DECL. */ - DECL_ASSEMBLER_NAME (value) = DECL_NAME (value); - if (!uses_template_parms (value)) - { - if (flag_new_abi) - DECL_ASSEMBLER_NAME (value) = mangle_type (TREE_TYPE (value)); - else - DECL_ASSEMBLER_NAME (value) = - get_identifier (build_overload_name (TREE_TYPE (value), 1, 1)); - } - if (processing_template_decl) value = push_template_decl (value); @@ -1804,8 +1716,8 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist) { /* This must override the asm specifier which was placed by grokclassfn. Lay this out fresh. */ - DECL_RTL (value) = NULL_RTX; - DECL_ASSEMBLER_NAME (value) = get_identifier (asmspec); + SET_DECL_RTL (value, NULL_RTX); + SET_DECL_ASSEMBLER_NAME (value, get_identifier (asmspec)); } cp_finish_decl (value, init, asmspec_tree, flags); @@ -1886,10 +1798,7 @@ grokoptypename (declspecs, declarator) tree declspecs, declarator; { tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL_TREE); - if (flag_new_abi) - return mangle_conv_op_name_for_type (t); - else - return build_typename_overload (t); + return mangle_conv_op_name_for_type (t); } /* When a function is declared with an initializer, @@ -1960,25 +1869,8 @@ grok_function_init (decl, init) if (TREE_CODE (type) == FUNCTION_TYPE) cp_error ("initializer specified for non-member function `%D'", decl); -#if 0 - /* We'll check for this in finish_struct_1. */ - else if (DECL_VINDEX (decl) == NULL_TREE) - cp_error ("initializer specified for non-virtual member function `%D'", decl); -#endif else if (integer_zerop (init)) { -#if 0 - /* Mark this function as being "defined". */ - DECL_INITIAL (decl) = error_mark_node; - /* pure virtual destructors must be defined. */ - /* pure virtual needs to be defined (as abort) only when put in - vtbl. For wellformed call, it should be itself. pr4737 */ - if (!DECL_DESTRUCTOR_P (decl))) - { - /* Give this node rtl from `abort'. */ - DECL_RTL (decl) = DECL_RTL (abort_fndecl); - } -#endif DECL_PURE_VIRTUAL_P (decl) = 1; if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR) { @@ -2216,6 +2108,9 @@ finish_anon_union (anon_union_decl) int static_p = TREE_STATIC (anon_union_decl); int external_p = DECL_EXTERNAL (anon_union_decl); + /* The VAR_DECL's context is the same as the TYPE's context. */ + DECL_CONTEXT (anon_union_decl) = DECL_CONTEXT (TYPE_NAME (type)); + if (TYPE_FIELDS (type) == NULL_TREE) return; @@ -2238,7 +2133,7 @@ finish_anon_union (anon_union_decl) if (static_p) { make_decl_rtl (main_decl, 0); - DECL_RTL (anon_union_decl) = DECL_RTL (main_decl); + COPY_DECL_RTL (main_decl, anon_union_decl); expand_anon_union_decl (anon_union_decl, NULL_TREE, DECL_ANON_UNION_ELEMS (anon_union_decl)); @@ -2373,7 +2268,8 @@ mark_vtable_entries (decl) fnaddr = (flag_vtable_thunks ? TREE_VALUE (entries) : FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries))); - if (TREE_CODE (fnaddr) != ADDR_EXPR) + if (TREE_CODE (fnaddr) != ADDR_EXPR + && TREE_CODE (fnaddr) != FDESC_EXPR) /* This entry is an offset: a virtual base class offset, a virtual call offset, and RTTI offset, etc. */ continue; @@ -2385,7 +2281,7 @@ mark_vtable_entries (decl) we know all the thunks we'll need when we emit a virtual function, so we emit the thunks there instead. */ if (DECL_THUNK_P (fn)) - use_thunk (fn, THUNK_GENERATE_WITH_VTABLE_P (fn)); + use_thunk (fn, /*emit_p=*/0); mark_used (fn); } } @@ -2488,7 +2384,7 @@ key_method (type) for (method = TYPE_METHODS (type); method != NULL_TREE; method = TREE_CHAIN (method)) if (DECL_VINDEX (method) != NULL_TREE - && ! DECL_THIS_INLINE (method) + && ! DECL_DECLARED_INLINE_P (method) && ! DECL_PURE_VIRTUAL_P (method)) return method; @@ -2740,7 +2636,8 @@ import_export_decl (decl) if ((DECL_IMPLICIT_INSTANTIATION (decl) || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)) && (flag_implicit_templates - || (flag_implicit_inline_templates && DECL_THIS_INLINE (decl)))) + || (flag_implicit_inline_templates + && DECL_DECLARED_INLINE_P (decl)))) { if (!TREE_PUBLIC (decl)) /* Templates are allowed to have internal linkage. See @@ -2754,23 +2651,24 @@ import_export_decl (decl) } else if (DECL_FUNCTION_MEMBER_P (decl)) { - tree ctype = DECL_CONTEXT (decl); - import_export_class (ctype); - if (CLASSTYPE_INTERFACE_KNOWN (ctype) - && (flag_new_abi - ? (! DECL_THIS_INLINE (decl)) - : (! DECL_ARTIFICIAL (decl) || DECL_VINDEX (decl)))) + if (!DECL_DECLARED_INLINE_P (decl)) { - DECL_NOT_REALLY_EXTERN (decl) - = ! (CLASSTYPE_INTERFACE_ONLY (ctype) - || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines - && !DECL_VINDEX (decl))); - - /* Always make artificials weak. */ - if (DECL_ARTIFICIAL (decl) && flag_weak) - comdat_linkage (decl); - else - maybe_make_one_only (decl); + tree ctype = DECL_CONTEXT (decl); + import_export_class (ctype); + if (CLASSTYPE_INTERFACE_KNOWN (ctype)) + { + DECL_NOT_REALLY_EXTERN (decl) + = ! (CLASSTYPE_INTERFACE_ONLY (ctype) + || (DECL_DECLARED_INLINE_P (decl) + && ! flag_implement_inlines + && !DECL_VINDEX (decl))); + + /* Always make artificials weak. */ + if (DECL_ARTIFICIAL (decl) && flag_weak) + comdat_linkage (decl); + else + maybe_make_one_only (decl); + } } else comdat_linkage (decl); @@ -2797,7 +2695,8 @@ import_export_decl (decl) { DECL_NOT_REALLY_EXTERN (decl) = ! (CLASSTYPE_INTERFACE_ONLY (ctype) - || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines + || (DECL_DECLARED_INLINE_P (decl) + && ! flag_implement_inlines && !DECL_VINDEX (decl))); /* Always make artificials weak. */ @@ -2846,23 +2745,7 @@ get_guard (decl) tree sname; tree guard; - /* For a local variable, under the old ABI, we do not try to get a - unique mangled name for the DECL. */ - if (!flag_new_abi && DECL_FUNCTION_SCOPE_P (decl)) - { - guard = get_temp_name (integer_type_node); - cp_finish_decl (guard, NULL_TREE, NULL_TREE, 0); - return guard; - } - - if (!flag_new_abi) - /* For struct X foo __attribute__((weak)), there is a counter - __snfoo. Since base is already an assembler name, sname should - be globally unique */ - sname = get_id_2 ("__sn", DECL_ASSEMBLER_NAME (decl)); - else - sname = mangle_guard_variable (decl); - + sname = mangle_guard_variable (decl); guard = IDENTIFIER_GLOBAL_VALUE (sname); if (! guard) { @@ -2870,11 +2753,7 @@ get_guard (decl) /* Under the new ABI, we use a type that is big enough to contain a mutex as well as an integer counter. */ - if (flag_new_abi) - guard_type = long_long_integer_type_node; - else - guard_type = integer_type_node; - + guard_type = long_long_integer_type_node; guard = build_decl (VAR_DECL, sname, guard_type); /* The guard should have the same linkage as what it guards. */ @@ -2900,9 +2779,6 @@ static tree get_guard_bits (guard) tree guard; { - if (!flag_new_abi) - return guard; - /* Under the new ABI, we only set the first byte of the guard, in order to leave room for a mutex in the high-order bits. */ guard = build1 (ADDR_EXPR, @@ -3332,10 +3208,13 @@ start_static_initialization_or_destruction (decl, initp) my_friendly_assert (initp, 20000629); guard_cond = get_guard_cond (guard); } - /* Under the old ABI, e do initializations only if the GUARD is - zero, i.e., if we are the first to initialize the variable. - We do destructions only if the GUARD is one, i.e., if we are - the last to destroy the variable. */ + /* If we don't have __cxa_atexit, then we will be running + destructors from .fini sections, or their equivalents. So, + we need to know how many times we've tried to initialize this + object. We do initializations only if the GUARD is zero, + i.e., if we are the first to initialize the variable. We do + destructions only if the GUARD is one, i.e., if we are the + last to destroy the variable. */ else if (initp) guard_cond = cp_build_binary_op (EQ_EXPR, @@ -3356,9 +3235,9 @@ start_static_initialization_or_destruction (decl, initp) finish_if_stmt_cond (cond, guard_if_stmt); - /* Under the new ABI, we have not already set the GUARD, so we must - do so now. */ - if (guard && initp && flag_new_abi) + /* If we're using __cxa_atexit, we have not already set the GUARD, + so we must do so now. */ + if (guard && initp && flag_use_cxa_atexit) finish_expr_stmt (set_guard (guard)); return guard_if_stmt; @@ -3629,8 +3508,7 @@ finish_file () timevar_push (TV_VARCONST); - if (new_abi_rtti_p ()) - emit_support_tinfos (); + emit_support_tinfos (); do { @@ -3650,8 +3528,7 @@ finish_file () /* Write out needed type info variables. Writing out one variable might cause others to be needed. */ - if (new_abi_rtti_p () - && walk_globals (tinfo_decl_p, emit_tinfo_decl, /*data=*/0)) + if (walk_globals (tinfo_decl_p, emit_tinfo_decl, /*data=*/0)) reconsider = 1; /* The list of objects with static storage duration is built up @@ -3724,19 +3601,12 @@ finish_file () finish_function doesn't clean things up, and we end up with CURRENT_FUNCTION_DECL set. */ push_to_top_level (); - if (DECL_TINFO_FN_P (decl)) - synthesize_tinfo_fn (decl); - else - synthesize_method (decl); + synthesize_method (decl); pop_from_top_level (); reconsider = 1; } } - /* Mark all functions that might deal with exception-handling as - referenced. */ - mark_all_runtime_matches (); - /* We lie to the back-end, pretending that some functions are not defined when they really are. This keeps these functions from being put out unnecessarily. But, we must stop lying @@ -3842,9 +3712,17 @@ finish_file () /* The entire file is now complete. If requested, dump everything to a file. */ - if (flag_dump_translation_unit) - dump_node_to_file (global_namespace, flag_dump_translation_unit); + { + int flags; + FILE *stream = dump_begin (TDI_all, &flags); + if (stream) + { + dump_node (global_namespace, flags & ~TDF_SLIM, stream); + dump_end (TDI_all, stream); + } + } + /* If there's some tool that wants to examine the entire translation unit, let it do so now. */ if (back_end_hook) @@ -4400,9 +4278,26 @@ merge_functions (s1, s2) { for (; s2; s2 = OVL_NEXT (s2)) { - tree fn = OVL_CURRENT (s2); - if (! ovl_member (fn, s1)) - s1 = build_overload (fn, s1); + tree fn2 = OVL_CURRENT (s2); + tree fns1; + + for (fns1 = s1; fns1; fns1 = OVL_NEXT (fns1)) + { + tree fn1 = OVL_CURRENT (fns1); + + /* If the function from S2 is already in S1, there is no + need to add it again. For `extern "C"' functions, we + might have two FUNCTION_DECLs for the same function, in + different namespaces; again, we only need one of them. */ + if (fn1 == fn2 + || (DECL_EXTERN_C_P (fn1) && DECL_EXTERN_C_P (fn2) + && DECL_NAME (fn1) == DECL_NAME (fn2))) + break; + } + + /* If we exhausted all of the functions in S1, FN2 is new. */ + if (!fns1) + s1 = build_overload (fn2, s1); } return s1; } @@ -4598,6 +4493,9 @@ set_decl_namespace (decl, scope, friendp) if (!old) /* No old declaration at all. */ goto complain; + /* A template can be explicitly specialized in any namespace. */ + if (processing_explicit_instantiation) + return; if (!is_overloaded_fn (decl)) /* Don't compare non-function decls with decls_match here, since it can't check for the correct constness at this @@ -5091,16 +4989,6 @@ validate_nonmember_using_decl (decl, scope, name) if (TREE_CODE (decl) == SCOPE_REF && TREE_OPERAND (decl, 0) == fake_std_node) { - if (namespace_bindings_p () - && current_namespace == global_namespace) - /* There's no need for a using declaration at all, here, - since `std' is the same as `::'. We can't just pass this - on because we'll complain later about declaring something - in the same scope as a using declaration with the same - name. We return NULL_TREE which indicates to the caller - that there's no need to do any further processing. */ - return NULL_TREE; - *scope = global_namespace; *name = TREE_OPERAND (decl, 1); } @@ -5113,7 +5001,8 @@ validate_nonmember_using_decl (decl, scope, name) A using-declaration for a class member shall be a member-declaration. */ - if (TREE_CODE (*scope) != NAMESPACE_DECL) + if (!processing_template_decl + && TREE_CODE (*scope) != NAMESPACE_DECL) { if (TYPE_P (*scope)) cp_error ("`%T' is not a namespace", *scope); @@ -5185,22 +5074,21 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype) { tree old_fn = OVL_CURRENT (tmp1); - if (!OVL_USED (tmp1) - && compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)), - TYPE_ARG_TYPES (TREE_TYPE (old_fn)))) + if (new_fn == old_fn) + /* The function already exists in the current namespace. */ + break; + else if (OVL_USED (tmp1)) + continue; /* this is a using decl */ + else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)), + TYPE_ARG_TYPES (TREE_TYPE (old_fn)))) { - if (!(DECL_EXTERN_C_P (new_fn) - && DECL_EXTERN_C_P (old_fn))) - /* There was already a non-using declaration in - this scope with the same parameter types. */ - cp_error ("`%D' is already declared in this scope", - name); + /* There was already a non-using declaration in + this scope with the same parameter types. If both + are the same extern "C" functions, that's ok. */ + if (!decls_match (new_fn, old_fn)) + cp_error ("`%D' is already declared in this scope", name); break; } - else if (duplicate_decls (new_fn, old_fn)) - /* We're re-using something we already used - before. We don't need to add it again. */ - break; } /* If we broke out of the loop, there's no reason to add @@ -5272,6 +5160,10 @@ do_local_using_decl (decl) if (decl == NULL_TREE) return; + if (building_stmt_tree () + && at_function_scope_p ()) + add_decl_stmt (decl); + oldval = lookup_name_current_level (name); oldtype = lookup_type_current_level (name); @@ -5339,18 +5231,23 @@ do_using_directive (namespace) { if (namespace == fake_std_node) return; + if (building_stmt_tree ()) + add_stmt (build_stmt (USING_STMT, namespace)); + /* using namespace A::B::C; */ if (TREE_CODE (namespace) == SCOPE_REF) namespace = TREE_OPERAND (namespace, 1); if (TREE_CODE (namespace) == IDENTIFIER_NODE) { /* Lookup in lexer did not find a namespace. */ - cp_error ("namespace `%T' undeclared", namespace); + if (!processing_template_decl) + cp_error ("namespace `%T' undeclared", namespace); return; } if (TREE_CODE (namespace) != NAMESPACE_DECL) { - cp_error ("`%T' is not a namespace", namespace); + if (!processing_template_decl) + cp_error ("`%T' is not a namespace", namespace); return; } namespace = ORIGINAL_NAMESPACE (namespace); |