aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl2.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r--gcc/cp/decl2.c433
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);