/* Process declarations and variables for C compiler.
- Copyright (C) 1988, 92-98, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+ Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
static void signal_catch PARAMS ((int)) ATTRIBUTE_NORETURN;
static void storedecls PARAMS ((tree));
static void require_complete_types_for_parms PARAMS ((tree));
-static void push_overloaded_decl_1 PARAMS ((tree));
static int ambi_op_p PARAMS ((tree));
static int unary_op_p PARAMS ((tree));
static tree store_bindings PARAMS ((tree, tree));
PARAMS ((tree, tree, struct binding_level *));
static void record_builtin_type PARAMS ((enum rid, const char *, tree));
static void record_unknown_type PARAMS ((tree, const char *));
+static tree build_library_fn_1 PARAMS ((tree, tree));
static int member_function_or_else PARAMS ((tree, tree, enum overload_flags));
static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int,
int));
static tree get_dso_handle_node PARAMS ((void));
static tree start_cleanup_fn PARAMS ((void));
static void end_cleanup_fn PARAMS ((void));
+static tree cp_make_fname_decl PARAMS ((tree, const char *, int));
#if defined (DEBUG_CP_BINDING_LEVELS)
static void indent PARAMS ((void));
tree __ptmf_desc_array_type, __ptmd_desc_array_type;
#endif
- tree class_star_type_node;
tree class_type_node, record_type_node, union_type_node, enum_type_node;
tree unknown_type_node;
#define named_labels cp_function_chain->x_named_labels
-/* The FUNCTION_DECL for the function currently being compiled,
- or 0 if between functions. */
-tree current_function_decl;
-
/* Set to 0 at beginning of a function definition, and whenever
a label (case or named) is defined. Set to value of expression
returned from function when that value can be transformed into
tree incomplete;
/* List of VAR_DECLS saved from a previous for statement.
- These would be dead in ANSI-conforming code, but might
+ These would be dead in ISO-conforming code, but might
be referenced in ARM-era code. These are stored in a
TREE_LIST; the TREE_VALUE is the actual declaration. */
tree dead_vars_from_for;
unsigned namespace_p : 1;
/* True if this level is that of a for-statement where we need to
- worry about ambiguous (ARM or ANSI) scope rules. */
+ worry about ambiguous (ARM or ISO) scope rules. */
unsigned is_for_scope : 1;
/* True if this level corresponds to an EH region, as for a try block. */
else
{
if (TREE_CODE (decl) == OVERLOAD)
- context = DECL_REAL_CONTEXT (OVL_CURRENT (decl));
+ context = CP_DECL_CONTEXT (OVL_CURRENT (decl));
else
{
my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd',
0);
- context = DECL_REAL_CONTEXT (decl);
+ context = CP_DECL_CONTEXT (decl);
}
if (is_properly_derived_from (current_class_type, context))
Put them into VEC from back to front, then take out from front. */
for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
- vec[len - i - 1] = decl;
+ {
+ /* Pretend we've output an unused static variable. This ensures
+ that the toplevel __FUNCTION__ etc won't be emitted, unless
+ needed. */
+ if (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)
+ && !TREE_PUBLIC (decl) && !TREE_USED (decl))
+ {
+ TREE_ASM_WRITTEN (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
+ }
+ vec[len - i - 1] = decl;
+ }
if (last_time)
{
/* When declaring a friend class of a local class, we want
to inject the newly named class into the scope
containing the local class, not the namespace scope. */
- context = hack_decl_function_context (get_type_decl (cs));
+ context = decl_function_context (get_type_decl (cs));
}
if (!context)
context = current_namespace;
tree p1 = TYPE_ARG_TYPES (f1);
tree p2 = TYPE_ARG_TYPES (f2);
- if (DECL_REAL_CONTEXT (newdecl) != DECL_REAL_CONTEXT (olddecl)
+ if (CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)
&& ! (DECL_LANGUAGE (newdecl) == lang_c
&& DECL_LANGUAGE (olddecl) == lang_c))
return 0;
- /* When we parse a static member function definition,
- we put together a FUNCTION_DECL which thinks its type
- is METHOD_TYPE. Change that to FUNCTION_TYPE, and
- proceed. */
- if (TREE_CODE (f1) == METHOD_TYPE && DECL_STATIC_FUNCTION_P (olddecl))
- revert_static_member_fn (&newdecl, &f1, &p1);
- else if (TREE_CODE (f2) == METHOD_TYPE
- && DECL_STATIC_FUNCTION_P (newdecl))
- revert_static_member_fn (&olddecl, &f2, &p2);
-
- /* Here we must take care of the case where new default
- parameters are specified. Also, warn if an old
- declaration becomes ambiguous because default
- parameters may cause the two to be ambiguous. */
if (TREE_CODE (f1) != TREE_CODE (f2))
- {
- if (TREE_CODE (f1) == OFFSET_TYPE)
- cp_compiler_error ("`%D' redeclared as member function", newdecl);
- else
- cp_compiler_error ("`%D' redeclared as non-member function", newdecl);
- return 0;
- }
+ return 0;
if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2)))
{
}
else if (!types_match)
{
- if (DECL_REAL_CONTEXT (newdecl) != DECL_REAL_CONTEXT (olddecl))
+ if (CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl))
/* These are certainly not duplicate declarations; they're
from different scopes. */
return 0;
definition. */
if (DECL_VINDEX (olddecl))
DECL_VINDEX (newdecl) = DECL_VINDEX (olddecl);
+ if (DECL_VIRTUAL_CONTEXT (olddecl))
+ DECL_VIRTUAL_CONTEXT (newdecl) = DECL_VIRTUAL_CONTEXT (olddecl);
if (DECL_CONTEXT (olddecl))
DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
- if (DECL_CLASS_CONTEXT (olddecl))
- DECL_CLASS_CONTEXT (newdecl) = DECL_CLASS_CONTEXT (olddecl);
if (DECL_PENDING_INLINE_INFO (newdecl) == (struct pending_inline *)0)
DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl);
DECL_STATIC_CONSTRUCTOR (newdecl) |= DECL_STATIC_CONSTRUCTOR (olddecl);
scoped of the current namespace, not the current
function. */
&& !(TREE_CODE (x) == VAR_DECL && DECL_EXTERNAL (x))
- /* Don't change DECL_CONTEXT of virtual methods. */
- && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x))
&& !DECL_CONTEXT (x))
DECL_CONTEXT (x) = current_function_decl;
if (!DECL_CONTEXT (x))
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
- /* ANSI standard says implicit declarations are in the innermost block.
+ /* ISO standard says implicit declarations are in the innermost block.
So we record the decl in the standard fashion. */
pushdecl (decl);
rest_of_decl_compilation (decl, NULL_PTR, 0, 0);
return "redefinition of `%#D'";
return 0;
}
- else if (toplevel_bindings_p ())
+ else if (toplevel_bindings_p () || DECL_NAMESPACE_SCOPE_P (newdecl))
{
/* Objects declared at top level: */
/* If at least one is a reference, it's ok. */
TYPE_MODE (type) = TYPE_MODE (void_type_node);
}
-/* Push overloaded decl, in global scope, with one argument so it
- can be used as a callback from define_function. */
-
-static void
-push_overloaded_decl_1 (x)
- tree x;
-{
- pushdecl (x);
-}
-
-inline tree
-auto_function (name, type)
- tree name, type;
-{
- return define_function
- (IDENTIFIER_POINTER (name), type, push_overloaded_decl_1,
- IDENTIFIER_POINTER (build_decl_overload (name, TYPE_ARG_TYPES (type),
- 0)));
-}
-
/* Create the predefined scalar types of C,
and some nodes representing standard constants (0, 1, (void *)0).
Initialize the global binding level.
boolean_true_node = build_int_2 (1, 0);
TREE_TYPE (boolean_true_node) = boolean_type_node;
- signed_size_zero_node = build_int_2 (0, 0); record_builtin_type (RID_FLOAT, NULL_PTR, float_type_node);
+ signed_size_zero_node = build_int_2 (0, 0);
+ record_builtin_type (RID_FLOAT, NULL_PTR, float_type_node);
record_builtin_type (RID_DOUBLE, NULL_PTR, double_type_node);
record_builtin_type (RID_MAX, "long double", long_double_type_node);
/* Make a type to be the domain of a few array types
whose domains don't really matter.
- 200 is small enough that it always fits in size_t
- and large enough that it can hold most function names for the
- initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */
+ 200 is small enough that it always fits in size_t. */
array_domain_type = build_index_type (build_int_2 (200, 0));
/* Make a type for arrays of characters.
int_array_type_node
= build_array_type (integer_type_node, array_domain_type);
- /* This is just some anonymous class type. Nobody should ever
- need to look inside this envelope. */
- class_star_type_node = build_pointer_type (make_aggr_type (RECORD_TYPE));
-
- if (flag_huge_objects)
+ if (flag_new_abi)
+ delta_type_node = ptrdiff_type_node;
+ else if (flag_huge_objects)
delta_type_node = long_integer_type_node;
else
delta_type_node = short_integer_type_node;
+ if (flag_new_abi)
+ vtable_index_type = ptrdiff_type_node;
+ else
+ vtable_index_type = delta_type_node;
+
default_function_type
= build_function_type (integer_type_node, NULL_TREE);
DECL_NAME (fields[3]) = delta2_identifier;
DECL_MODE (fields[3]) = TYPE_MODE (delta_type_node);
DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node);
+ DECL_SIZE_UNIT (fields[3]) = TYPE_SIZE_UNIT (delta_type_node);
TREE_UNSIGNED (fields[3]) = 0;
TREE_CHAIN (fields[2]) = fields[3];
vtable_entry_type = build_qualified_type (vtable_entry_type,
newtype = build_exception_variant
(ptr_ftype_sizetype, add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1));
deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
- auto_function (ansi_opname[(int) NEW_EXPR], newtype);
- auto_function (ansi_opname[(int) VEC_NEW_EXPR], newtype);
- global_delete_fndecl = auto_function (ansi_opname[(int) DELETE_EXPR],
- deltype);
- auto_function (ansi_opname[(int) VEC_DELETE_EXPR], deltype);
+ push_cp_library_fn (ansi_opname[(int) NEW_EXPR], newtype);
+ push_cp_library_fn (ansi_opname[(int) VEC_NEW_EXPR], newtype);
+ global_delete_fndecl = push_cp_library_fn (ansi_opname[(int) DELETE_EXPR],
+ deltype);
+ push_cp_library_fn (ansi_opname[(int) VEC_DELETE_EXPR], deltype);
}
abort_fndecl
- = define_function ("__pure_virtual", void_ftype, 0, 0);
+ = build_library_fn_ptr ("__pure_virtual", void_ftype);
/* Perform other language dependent initializations. */
init_class_processing ();
flag_weak = 0;
/* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */
+ make_fname_decl = cp_make_fname_decl;
declare_function_name ();
/* Prepare to check format strings against argument lists. */
ggc_add_tree_root (&static_aggregates, 1);
}
+/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
+ decl, NAME is the initialization string and TYPE_DEP indicates whether
+ NAME depended on the type of the function. We make use of that to detect
+ __PRETTY_FUNCTION__ inside a template fn. Because we build a tree for
+ the function before emitting any of it, we don't need to treat the
+ VAR_DECL specially. We can decide whether to emit it later, if it was
+ used. */
+
+static tree
+cp_make_fname_decl (id, name, type_dep)
+ tree id;
+ const char *name;
+ int type_dep;
+{
+ tree decl, type, init;
+ size_t length = strlen (name);
+ tree domain = NULL_TREE;
+
+ if (!processing_template_decl)
+ type_dep = 0;
+ if (!type_dep)
+ domain = build_index_type (build_int_2 (length, 0));
+
+ type = build_cplus_array_type
+ (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
+ domain);
+
+ decl = build_lang_decl (VAR_DECL, id, type);
+ TREE_STATIC (decl) = 1;
+ TREE_READONLY (decl) = 1;
+ DECL_SOURCE_LINE (decl) = 0;
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_IN_SYSTEM_HEADER (decl) = 1;
+ pushdecl (decl);
+ if (processing_template_decl)
+ decl = push_template_decl (decl);
+ if (type_dep)
+ {
+ init = build (FUNCTION_NAME, type);
+ DECL_PRETTY_FUNCTION_P (decl) = 1;
+ }
+ else
+ {
+ init = build_string (length + 1, name);
+ TREE_TYPE (init) = type;
+ }
+ DECL_INITIAL (decl) = init;
+ cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
+
+ /* We will have to make sure we only emit this, if it is actually used. */
+ return decl;
+}
+
/* Function to print any language-specific context for an error message. */
static void
maybe_print_template_context ();
}
-/* Make a definition for a builtin function named NAME and whose data type
+/* 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.
- If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
+ 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
-define_function (name, type, pfn, library_name)
+builtin_function (name, type, code, class, libname)
const char *name;
tree type;
- void (*pfn) PARAMS ((tree));
- const char *library_name;
+ int code;
+ enum built_in_class class;
+ const char *libname;
{
- tree decl = build_lang_decl (FUNCTION_DECL, get_identifier (name), type);
- DECL_EXTERNAL (decl) = 1;
- TREE_PUBLIC (decl) = 1;
- DECL_ARTIFICIAL (decl) = 1;
+ tree decl = build_library_fn_1 (get_identifier (name), type);
+ DECL_BUILT_IN_CLASS (decl) = class;
+ DECL_FUNCTION_CODE (decl) = code;
my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392);
- DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
/* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME,
we cannot change DECL_ASSEMBLER_NAME until we have installed this
function in the namespace. */
- if (pfn) (*pfn) (decl);
- if (library_name)
- DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name);
+ pushdecl (decl);
+ if (libname)
+ DECL_ASSEMBLER_NAME (decl) = get_identifier (libname);
make_function_rtl (decl);
return decl;
}
+/* Generate a FUNCTION_DECL with the typical flags for a runtime library
+ function. Not called directly. */
+
+static tree
+build_library_fn_1 (name, type)
+ tree name;
+ tree type;
+{
+ tree fn = build_lang_decl (FUNCTION_DECL, name, type);
+ DECL_EXTERNAL (fn) = 1;
+ TREE_PUBLIC (fn) = 1;
+ DECL_ARTIFICIAL (fn) = 1;
+ TREE_NOTHROW (fn) = 1;
+ return fn;
+}
+
+/* Returns the _DECL for a library function with C linkage.
+ We assume that such functions never throw; if this is incorrect,
+ callers should unset TREE_NOTHROW. */
+
+tree
+build_library_fn (name, type)
+ tree name;
+ tree type;
+{
+ tree fn = build_library_fn_1 (name, type);
+ make_function_rtl (fn);
+ return fn;
+}
-/* Wrapper around define_function, for the benefit of
- c_common_nodes_and_builtins.
- FUNCTION_CODE tells later passes how to compile calls to this function.
- See tree.h for its possible values. */
+/* Returns the _DECL for a library function with C++ linkage. */
tree
-builtin_function (name, type, code, class, libname)
+build_cp_library_fn (name, type)
+ tree name;
+ tree type;
+{
+ tree fn = build_library_fn_1 (name, type);
+ TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
+ set_mangled_name_for_decl (fn);
+ make_function_rtl (fn);
+ return fn;
+}
+
+/* Like build_library_fn, but takes a C string instead of an
+ IDENTIFIER_NODE. */
+
+tree
+build_library_fn_ptr (name, type)
const char *name;
tree type;
- int code;
- enum built_in_class class;
- const char *libname;
{
- tree decl = define_function (name, type, (void (*) PARAMS ((tree)))pushdecl,
- libname);
- DECL_BUILT_IN_CLASS (decl) = class;
- DECL_FUNCTION_CODE (decl) = code;
- return decl;
+ return build_library_fn (get_identifier (name), type);
+}
+
+/* Like build_cp_library_fn, but takes a C string instead of an
+ IDENTIFIER_NODE. */
+
+tree
+build_cp_library_fn_ptr (name, type)
+ const char *name;
+ tree type;
+{
+ return build_cp_library_fn (get_identifier (name), type);
+}
+
+/* Like build_library_fn, but also pushes the function so that we will
+ be able to find it via IDENTIFIER_GLOBAL_VALUE. */
+
+tree
+push_library_fn (name, type)
+ tree name, type;
+{
+ tree fn = build_library_fn (name, type);
+ pushdecl_top_level (fn);
+ return fn;
+}
+
+/* Like build_cp_library_fn, but also pushes the function so that it
+ will be found by normal lookup. */
+
+tree
+push_cp_library_fn (name, type)
+ tree name;
+ tree type;
+{
+ tree fn = build_cp_library_fn (name, type);
+ pushdecl (fn);
+ return fn;
+}
+
+/* Like push_library_fn, but takes a TREE_LIST of parm types rather than
+ a FUNCTION_TYPE. */
+
+tree
+push_void_library_fn (name, parmtypes)
+ tree name, parmtypes;
+{
+ tree type = build_function_type (void_type_node, parmtypes);
+ return push_library_fn (name, type);
+}
+
+/* Like push_library_fn, but also note that this function throws
+ and does not return. Used for __throw_foo and the like. */
+
+tree
+push_throw_library_fn (name, type)
+ tree name, type;
+{
+ tree fn = push_library_fn (name, type);
+ TREE_THIS_VOLATILE (fn) = 1;
+ TREE_NOTHROW (fn) = 0;
+ return fn;
}
\f
/* When we call finish_struct for an anonymous union, we create
q = &TREE_CHAIN (*q);
}
- /* ANSI C++ June 5 1992 WP 9.5.3. Anonymous unions may not have
- function members. */
+ /* ISO C++ 9.5.3. Anonymous unions may not have function members. */
if (TYPE_METHODS (t))
error ("an anonymous union cannot have function members");
}
if (type == error_mark_node)
return NULL_TREE;
- context
- = (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl))
- ? DECL_CLASS_CONTEXT (decl)
- : DECL_CONTEXT (decl);
+ context = DECL_CONTEXT (decl);
if (initialized && context && TREE_CODE (context) == NAMESPACE_DECL
&& context != current_namespace && TREE_CODE (decl) == VAR_DECL)
{
if (DECL_CONTEXT (field) != context)
{
- cp_pedwarn ("ANSI C++ does not permit `%T::%D' to be defined as `%T::%D'",
+ cp_pedwarn ("ISO C++ does not permit `%T::%D' to be defined as `%T::%D'",
DECL_CONTEXT (field), DECL_NAME (decl),
context, DECL_NAME (decl));
DECL_CONTEXT (decl) = DECL_CONTEXT (field);
/* If this type of object needs a cleanup, but we're not allowed to
add any more objects with cleanups to the current scope, create a
new binding level. */
- if (TYPE_NEEDS_DESTRUCTOR (type)
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
&& current_binding_level->more_cleanups_ok == 0)
{
keep_next_level (2);
if (TREE_CODE (init) == CONSTRUCTOR)
{
- cp_error ("ANSI C++ forbids use of initializer list to initialize reference `%D'", decl);
+ cp_error ("ISO C++ forbids use of initializer list to initialize reference `%D'", decl);
return;
}
`extern X x' for some incomplete type `X'.) */
if (!DECL_EXTERNAL (decl))
complete_type (type);
- if (!DECL_SIZE (decl)&& TYPE_SIZE (type))
+ if (!DECL_SIZE (decl) && TYPE_SIZE (type))
layout_decl (decl, 0);
if (!DECL_EXTERNAL (decl) && DECL_SIZE (decl) == NULL_TREE)
linkage. */
if (TREE_STATIC (decl)
/* Don't mess with __FUNCTION__. */
- && ! TREE_ASM_WRITTEN (decl)
+ && ! DECL_ARTIFICIAL (decl)
&& current_function_decl
&& DECL_CONTEXT (decl) == current_function_decl
&& (DECL_THIS_INLINE (current_function_decl)
if (TREE_PUBLIC (decl))
DECL_ASSEMBLER_NAME (decl)
= build_static_name (current_function_decl, DECL_NAME (decl));
- else if (! DECL_ARTIFICIAL (decl))
+ else
{
cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl);
cp_warning_at (" you can work around this by removing the initializer", decl);
if (TREE_STATIC (decl))
{
if (TYPE_NEEDS_CONSTRUCTING (type) || init != NULL_TREE
- || TYPE_NEEDS_DESTRUCTOR (type))
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
expand_static_init (decl, init);
return;
}
marked used. (see TREE_USED, above.) */
if (TYPE_NEEDS_CONSTRUCTING (type)
&& ! already_used
- && !TYPE_NEEDS_DESTRUCTOR (type)
+ && TYPE_HAS_TRIVIAL_DESTRUCTOR (type)
&& DECL_NAME (decl))
TREE_USED (decl) = 0;
else if (already_used)
return;
/* And only things with destructors need cleaning up. */
- if (!TYPE_NEEDS_DESTRUCTOR (type))
+ if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
return;
if (TREE_CODE (decl) == VAR_DECL &&
If the length of an array type is not known before,
it must be determined now, from the initial value, or it is an error.
- For C++, `cp_finish_decl' must be fairly evasive: it must keep initializers
- for aggregates that have constructors alive on the permanent obstack,
- so that the global initializing functions can be written at the end.
-
INIT0 holds the value of an initializer that should be allowed to escape
the normal rules.
- FLAGS is LOOKUP_ONLYCONVERTING is the = init syntax was used, else 0
+ FLAGS is LOOKUP_ONLYCONVERTING if the = init syntax was used, else 0
if the (init) syntax was used.
For functions that take default parameters, DECL points to its
const char *asmspec = NULL;
int was_readonly = 0;
- /* If this is 0, then we did not change obstacks. */
if (! decl)
{
if (init)
return;
}
- /* Handling __FUNCTION__ and its ilk in a template-function requires
- some special processing because we are called from
- language-independent code. */
- if (cfun && processing_template_decl
- && current_function_name_declared == 2)
- {
- /* Since we're in a template function, we need to
- push_template_decl. The language-independent code in
- declare_hidden_char_array doesn't know to do this. */
- retrofit_lang_decl (decl);
- decl = push_template_decl (decl);
-
- if (strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)),
- "__PRETTY_FUNCTION__") == 0)
- {
- init = build (FUNCTION_NAME, const_string_type_node);
- DECL_PRETTY_FUNCTION_P (decl) = 1;
- }
- }
-
/* If a name was specified, get the string. */
if (asmspec_tree)
asmspec = TREE_STRING_POINTER (asmspec_tree);
if (init && TREE_CODE (init) == NAMESPACE_DECL)
{
- cp_error ("Cannot initialize `%D' to namespace `%D'",
+ cp_error ("cannot initialize `%D' to namespace `%D'",
decl, init);
init = NULL_TREE;
}
if (current_class_type
- && DECL_REAL_CONTEXT (decl) == current_class_type
+ && CP_DECL_CONTEXT (decl) == current_class_type
&& TYPE_BEING_DEFINED (current_class_type)
&& (DECL_INITIAL (decl) || init))
DECL_DEFINED_IN_CLASS_P (decl) = 1;
{
/* Cleanups for static variables are handled by `finish_file'. */
if (TYPE_NEEDS_CONSTRUCTING (type) || init != NULL_TREE
- || TYPE_NEEDS_DESTRUCTOR (type))
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
expand_static_init (decl, init);
}
finish_end0:
due to initialization of qualified member variable.
I.e., Foo::x = 10; */
{
- tree context = DECL_REAL_CONTEXT (decl);
+ tree context = CP_DECL_CONTEXT (decl);
if (context
&& TREE_CODE_CLASS (TREE_CODE (context)) == 't'
&& (TREE_CODE (decl) == VAR_DECL
finish_end:
- /* If requested, warn about definitions of large data objects. */
-
- if (warn_larger_than
- && ! processing_template_decl
- && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
- && !DECL_EXTERNAL (decl))
- {
- register tree decl_size = DECL_SIZE (decl);
-
- if (decl_size && TREE_CODE (decl_size) == INTEGER_CST)
- {
- unsigned units = TREE_INT_CST_LOW (decl_size) / BITS_PER_UNIT;
-
- if (units > larger_than_size)
- warning_with_decl (decl, "size of `%s' is %u bytes", units);
- }
- }
-
if (was_readonly)
TREE_READONLY (decl) = 1;
}
/* Now, build the function declaration. */
push_lang_context (lang_name_c);
- atexit_fndecl = define_function (name, fn_type, /*pfn=*/0, NULL_PTR);
+ atexit_fndecl = build_library_fn_ptr (name, fn_type);
mark_used (atexit_fndecl);
pop_lang_context ();
atexit_node = default_conversion (atexit_fndecl);
int saved_flag_access_control;
- if (!TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl)))
+ if (TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
return;
/* Call build_cleanup before we enter the anonymous function so that
else if (TREE_CODE (initial_value) == CONSTRUCTOR)
{
tree elts = CONSTRUCTOR_ELTS (initial_value);
- maxindex = size_binop (MINUS_EXPR, integer_zero_node, size_one_node);
+
+ maxindex = ssize_int (-1);
for (; elts; elts = TREE_CHAIN (elts))
{
if (TREE_PURPOSE (elts))
maxindex = TREE_PURPOSE (elts);
else
- maxindex = size_binop (PLUS_EXPR, maxindex, size_one_node);
+ maxindex = size_binop (PLUS_EXPR, maxindex, ssize_int (1));
}
maxindex = copy_node (maxindex);
}
}
if (ctype)
- DECL_CLASS_CONTEXT (decl) = ctype;
+ DECL_CONTEXT (decl) = ctype;
if (ctype == NULL_TREE && DECL_MAIN_P (decl))
{
if (processing_template_decl)
- error ("cannot declare `main' to be a template");
+ error ("cannot declare `::main' to be a template");
if (inlinep)
- error ("cannot declare `main' to be inline");
+ error ("cannot declare `::main' to be inline");
else if (! publicp)
- error ("cannot declare `main' to be static");
+ error ("cannot declare `::main' to be static");
inlinep = 0;
publicp = 1;
}
/* Members of anonymous types and local classes have no linkage; make
them internal. */
if (ctype && (ANON_AGGRNAME_P (TYPE_IDENTIFIER (ctype))
- || hack_decl_function_context (TYPE_MAIN_DECL (ctype))))
+ || decl_function_context (TYPE_MAIN_DECL (ctype))))
publicp = 0;
if (publicp)
if (IDENTIFIER_OPNAME_P (DECL_NAME (decl)))
grok_op_properties (decl, virtualp, check < 0);
- if (ctype && hack_decl_function_context (decl))
+ if (ctype && decl_function_context (decl))
DECL_NO_STATIC_CHAIN (decl) = 1;
for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
if (PROCESSING_REAL_TEMPLATE_DECL_P ())
{
/* Something like `template <class T> friend void f<T>()'. */
- cp_error ("template-id `%D' in declaration of primary template",
+ cp_error ("invalid use of template-id `%D' in declaration of primary template",
orig_declarator);
return NULL_TREE;
}
tentative. error_mark_node is replaced later with the BLOCK. */
DECL_INITIAL (decl) = error_mark_node;
+ if (nothrow_libfn_p (decl))
+ TREE_NOTHROW (decl) = 1;
+
/* Caller will do the rest of this. */
if (check < 0)
return decl;
type = TREE_TYPE (type);
decl = build_lang_decl (VAR_DECL, declarator, type);
DECL_CONTEXT (decl) = basetype;
- DECL_CLASS_CONTEXT (decl) = basetype;
DECL_ASSEMBLER_NAME (decl) = build_static_name (basetype, declarator);
}
else
unqualified_variant
= build_ptrmemfunc_type (TYPE_MAIN_VARIANT (type));
- u = make_aggr_type (UNION_TYPE);
- SET_IS_AGGR_TYPE (u, 0);
- fields[0] = build_lang_decl (FIELD_DECL, pfn_identifier, type);
- fields[1] = build_lang_decl (FIELD_DECL, delta2_identifier,
- delta_type_node);
- finish_builtin_type (u, "__ptrmemfunc_type", fields, 1, ptr_type_node);
- TYPE_NAME (u) = NULL_TREE;
-
t = make_aggr_type (RECORD_TYPE);
-
/* Let the front-end know this is a pointer to member function... */
TYPE_PTRMEMFUNC_FLAG (t) = 1;
/* ... and not really an aggregate. */
SET_IS_AGGR_TYPE (t, 0);
- fields[0] = build_lang_decl (FIELD_DECL, delta_identifier,
- delta_type_node);
- fields[1] = build_lang_decl (FIELD_DECL, index_identifier,
- delta_type_node);
- fields[2] = build_lang_decl (FIELD_DECL, pfn_or_delta2_identifier, u);
- finish_builtin_type (t, "__ptrmemfunc_type", fields, 2, ptr_type_node);
+ if (!flag_new_abi)
+ {
+ u = make_aggr_type (UNION_TYPE);
+ SET_IS_AGGR_TYPE (u, 0);
+ fields[0] = build_lang_decl (FIELD_DECL, pfn_identifier, type);
+ fields[1] = build_lang_decl (FIELD_DECL, delta2_identifier,
+ delta_type_node);
+ finish_builtin_type (u, "__ptrmemfunc_type", fields, 1, ptr_type_node);
+ TYPE_NAME (u) = NULL_TREE;
+
+ fields[0] = build_lang_decl (FIELD_DECL, delta_identifier,
+ delta_type_node);
+ fields[1] = build_lang_decl (FIELD_DECL, index_identifier,
+ delta_type_node);
+ fields[2] = build_lang_decl (FIELD_DECL, pfn_or_delta2_identifier, u);
+ finish_builtin_type (t, "__ptrmemfunc_type", fields, 2, ptr_type_node);
+ }
+ else
+ {
+ fields[0] = build_lang_decl (FIELD_DECL, pfn_identifier, type);
+ fields[1] = build_lang_decl (FIELD_DECL, delta_identifier,
+ delta_type_node);
+ finish_builtin_type (t, "__ptrmemfunc_type", fields, 1, ptr_type_node);
+ }
/* Zap out the name so that the back-end will give us the debugging
information for this anonymous RECORD_TYPE. */
required. */
if (CLASS_TYPE_P (type) || TREE_CODE (type) == REFERENCE_TYPE)
{
- cp_error ("in-class initialization of static data member of non-integral type `%T'",
+ cp_error ("invalid in-class initialization of static data member of non-integral type `%T'",
type);
/* If we just return the declaration, crashes will sometimes
occur. We therefore return void_type_node, as if this was a
return 1;
}
else if (!CP_TYPE_CONST_P (type))
- cp_error ("ANSI C++ forbids in-class initialization of non-const static member `%D'",
+ cp_error ("ISO C++ forbids in-class initialization of non-const static member `%D'",
decl);
else if (pedantic && !INTEGRAL_TYPE_P (type))
- cp_pedwarn ("ANSI C++ forbids initialization of member constant `%D' of non-integral type `%T'", decl, type);
+ cp_pedwarn ("ISO C++ forbids initialization of member constant `%D' of non-integral type `%T'", decl, type);
return 0;
}
else if (integer_zerop (size) && pedantic && !in_system_header)
{
if (name)
- cp_pedwarn ("ANSI C++ forbids zero-size array `%D'", name);
+ cp_pedwarn ("ISO C++ forbids zero-size array `%D'", name);
else
- cp_pedwarn ("ANSI C++ forbids zero-size array");
+ cp_pedwarn ("ISO C++ forbids zero-size array");
}
}
if (pedantic)
{
if (name)
- cp_pedwarn ("ANSI C++ forbids variable-size array `%D'",
+ cp_pedwarn ("ISO C++ forbids variable-size array `%D'",
name);
else
- cp_pedwarn ("ANSI C++ forbids variable-size array");
+ cp_pedwarn ("ISO C++ forbids variable-size array");
}
/* Create a variable-sized array index type. */
can be omitted only for the first member of the sequence. */
if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))
{
- cp_error ("declaration of `%D' as multidimensional array",
+ cp_error ("declaration of `%D' as multidimensional array must have bounds for all dimensions except the first",
name);
- cp_error ("must have bounds for all dimensions except the first");
return error_mark_node;
}
decl = start_decl (declarator, declspecs, 1,
attributes, prefix_attributes);
+ decl_type_access_control (decl);
if (decl)
{
/* Look for __unused__ attribute */
if (i == (int) RID_LONG && RIDBIT_SETP (i, specbits))
{
if (pedantic && ! in_system_header && warn_long_long)
- pedwarn ("ANSI C++ does not support `long long'");
+ pedwarn ("ISO C++ does not support `long long'");
if (longlong)
error ("`long long long' is too long for GCC");
else
if (in_system_header || flag_ms_extensions)
/* Allow it, sigh. */;
else if (pedantic || ! is_main)
- cp_pedwarn ("ANSI C++ forbids declaration of `%s' with no type",
+ cp_pedwarn ("ISO C++ forbids declaration of `%s' with no type",
name);
else if (warn_return_type)
- cp_warning ("ANSI C++ forbids declaration of `%s' with no type",
+ cp_warning ("ISO C++ forbids declaration of `%s' with no type",
name);
type = integer_type_node;
if (flags == DTOR_FLAG)
{
- /* ANSI C++ June 5 1992 WP 12.4.1. A destructor may
- not be declared const or volatile. A destructor
- may not be static. */
+ /* ISO C++ 12.4/2. A destructor may not be
+ declared const or volatile. A destructor may
+ not be static. */
if (staticp == 2)
error ("destructor cannot be static member function");
if (quals)
{
if (explicitp == 1)
explicitp = 2;
- /* ANSI C++ June 5 1992 WP 12.1.2. A constructor may
- not be declared const or volatile. A constructor may
- not be virtual. A constructor may not be static. */
+ /* ISO C++ 12.1. A constructor may not be
+ declared const or volatile. A constructor may
+ not be virtual. A constructor may not be
+ static. */
if (staticp == 2)
error ("constructor cannot be static member function");
if (virtualp)
template_count += 1;
t = TYPE_MAIN_DECL (t);
if (DECL_LANG_SPECIFIC (t))
- t = DECL_CLASS_CONTEXT (t);
+ t = DECL_CONTEXT (t);
else
t = NULL_TREE;
}
if (decl_context == FIELD)
{
if (declarator == constructor_name (current_class_type))
- cp_pedwarn ("ANSI C++ forbids nested type `%D' with same name as enclosing class",
+ cp_pedwarn ("ISO C++ forbids nested type `%D' with same name as enclosing class",
declarator);
decl = build_lang_decl (TYPE_DECL, declarator, type);
}
if (ctype == NULL_TREE)
{
if (TREE_CODE (type) != METHOD_TYPE)
- cp_error_at ("invalid type qualifier for non-method type", decl);
+ cp_error_at ("invalid type qualifier for non-member function type", decl);
else
ctype = TYPE_METHOD_BASETYPE (type);
}
}
else if (quals)
{
- tree dummy = build_decl (TYPE_DECL, declarator, type);
if (ctype == NULL_TREE)
{
- my_friendly_assert (TREE_CODE (type) == METHOD_TYPE, 159);
- ctype = TYPE_METHOD_BASETYPE (type);
+ if (TREE_CODE (type) != METHOD_TYPE)
+ cp_error ("invalid qualifiers on non-member function type");
+ else
+ ctype = TYPE_METHOD_BASETYPE (type);
+ }
+ if (ctype)
+ {
+ tree dummy = build_decl (TYPE_DECL, declarator, type);
+ grok_method_quals (ctype, dummy, quals);
+ type = TREE_TYPE (dummy);
}
- grok_method_quals (ctype, dummy, quals);
- type = TREE_TYPE (dummy);
}
return type;
/* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */
function_context = (ctype != NULL_TREE) ?
- hack_decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE;
+ decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE;
publicp = (! friendp || ! staticp)
&& function_context == NULL_TREE;
decl = grokfndecl (ctype, type,
{
if (friendp)
{
- error ("`%s' is neither function nor method; cannot be declared friend",
+ error ("`%s' is neither function nor member function; cannot be declared friend",
IDENTIFIER_POINTER (declarator));
friendp = 0;
}
the rest of the compiler does not correctly
handle the initialization unless the member is
static so we make it static below. */
- cp_pedwarn ("ANSI C++ forbids initialization of member `%D'",
+ cp_pedwarn ("ISO C++ forbids initialization of member `%D'",
declarator);
cp_pedwarn ("making `%D' static", declarator);
staticp = 1;
allow non-static data members here, because C does
and /usr/include/netinet/in.h uses that. */
&& (staticp || ! in_system_header))
- cp_pedwarn ("ANSI C++ forbids data member `%D' with same name as enclosing class",
+ cp_pedwarn ("ISO C++ forbids data member `%D' with same name as enclosing class",
declarator);
if (staticp)
TREE_PURPOSE (arg) = init;
}
\f
+/* D is a constructor or overloaded `operator='. Returns non-zero if
+ D's arguments allow it to be a copy constructor, or copy assignment
+ operator. */
+
int
copy_args_p (d)
tree d;
{
- tree t = FUNCTION_ARG_CHAIN (d);
+ tree t;
+
+ if (!DECL_FUNCTION_MEMBER_P (d))
+ return 0;
+
+ t = FUNCTION_ARG_CHAIN (d);
if (DECL_CONSTRUCTOR_P (d)
&& TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (d)))
t = TREE_CHAIN (t);
if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
&& (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t)))
- == DECL_CLASS_CONTEXT (d))
+ == DECL_CONTEXT (d))
&& (TREE_CHAIN (t) == NULL_TREE
|| TREE_CHAIN (t) == void_list_node
|| TREE_PURPOSE (TREE_CHAIN (t))))
|| name == ansi_opname[(int) MEMBER_REF])
TYPE_OVERLOADS_ARROW (current_class_type) = 1;
else if (name == ansi_opname[(int) NEW_EXPR])
- TYPE_GETS_NEW (current_class_type) |= 1;
+ TYPE_HAS_NEW_OPERATOR (current_class_type) = 1;
else if (name == ansi_opname[(int) DELETE_EXPR])
TYPE_GETS_DELETE (current_class_type) |= 1;
else if (name == ansi_opname[(int) VEC_NEW_EXPR])
- TYPE_GETS_NEW (current_class_type) |= 2;
+ TYPE_HAS_ARRAY_NEW_OPERATOR (current_class_type) = 1;
else if (name == ansi_opname[(int) VEC_DELETE_EXPR])
TYPE_GETS_DELETE (current_class_type) |= 2;
}
hash_tree_chain (ptr_type_node,
void_list_node));
else
- {
- TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
-
- if (! friendp && name == ansi_opname[(int) VEC_DELETE_EXPR]
- && (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)))
- != void_list_node))
- TYPE_VEC_DELETE_TAKES_SIZE (current_class_type) = 1;
- }
+ TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
}
else
{
if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl))
{
tree t = TREE_TYPE (name);
- if (TREE_CODE (t) == VOID_TYPE)
- pedwarn ("void is not a valid type conversion operator");
- else if (! friendp)
+ if (! friendp)
{
int ref = (TREE_CODE (t) == REFERENCE_TYPE);
const char *what = 0;
+
if (ref)
t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
- if (t == current_class_type)
+ if (TREE_CODE (t) == VOID_TYPE)
+ what = "void";
+ else if (t == current_class_type)
what = "the same type";
/* Don't force t to be complete here. */
else if (IS_AGGR_TYPE (t)
else if (name == ansi_opname[(int) COND_EXPR])
{
/* 13.4.0.3 */
- cp_error ("ANSI C++ prohibits overloading operator ?:");
+ cp_error ("ISO C++ prohibits overloading operator ?:");
}
else if (ambi_op_p (name))
{
}
else
{
- /* If it no longer looks like a nested type, make sure it's
- in global scope.
- If it is not an IDENTIFIER, this is not a declaration */
- if (b->namespace_p && !class_binding_level
- && TREE_CODE (name) == IDENTIFIER_NODE
- && IDENTIFIER_NAMESPACE_VALUE (name) == NULL_TREE)
- SET_IDENTIFIER_NAMESPACE_VALUE (name, TYPE_NAME (ref));
-
if (!globalize && processing_template_decl && IS_AGGR_TYPE (ref))
redeclare_class_template (ref, current_template_parms);
}
the `accessibility' of that particular inheritance is.) */
base_binfo
- = make_binfo (integer_zero_node, basetype,
+ = make_binfo (size_zero_node, basetype,
CLASS_TYPE_P (basetype)
? TYPE_BINFO_VTABLE (basetype) : NULL_TREE,
CLASS_TYPE_P (basetype)
if (CLASS_TYPE_P (basetype))
{
- TYPE_GETS_NEW (ref) |= TYPE_GETS_NEW (basetype);
+ TYPE_HAS_NEW_OPERATOR (ref)
+ |= TYPE_HAS_NEW_OPERATOR (basetype);
+ TYPE_HAS_ARRAY_NEW_OPERATOR (ref)
+ |= TYPE_HAS_ARRAY_NEW_OPERATOR (basetype);
TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
/* If the base-class uses multiple inheritance, so do we. */
TYPE_USES_MULTIPLE_INHERITANCE (ref)
/* The next value is the previous value ... */
prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype)));
/* ... plus one. */
- value = build_binary_op_nodefault (PLUS_EXPR,
- prev_value,
- integer_one_node,
- PLUS_EXPR);
+ value = build_binary_op (PLUS_EXPR,
+ prev_value,
+ integer_one_node);
if (tree_int_cst_lt (value, prev_value))
cp_error ("overflow in enumeration values at `%D'", name);
if (TREE_CODE (fntype) == METHOD_TYPE)
ctype = TYPE_METHOD_BASETYPE (fntype);
- /* ANSI C++ June 5 1992 WP 11.4.5. A friend function defined in a
- class is in the (lexical) scope of the class in which it is
- defined. */
+ /* ISO C++ 11.4/5. A friend function defined in a class is in
+ the (lexical) scope of the class in which it is defined. */
if (!ctype && DECL_FRIEND_P (decl1))
{
- ctype = DECL_CLASS_CONTEXT (decl1);
+ ctype = DECL_FRIEND_CONTEXT (decl1);
/* CTYPE could be null here if we're dealing with a template;
for example, `inline friend float foo()' inside a template
if (DECL_INTERFACE_KNOWN (decl1))
{
- tree ctx = hack_decl_function_context (decl1);
+ tree ctx = decl_function_context (decl1);
if (DECL_NOT_REALLY_EXTERN (decl1))
DECL_EXTERNAL (decl1) = 0;
if ((DECL_THIS_INLINE (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1))
&& ! DECL_INTERFACE_KNOWN (decl1)
/* Don't try to defer nested functions for now. */
- && ! hack_decl_function_context (decl1))
+ && ! decl_function_context (decl1))
DECL_DEFER_OUTPUT (decl1) = 1;
else
DECL_INTERFACE_KNOWN (decl1) = 1;
else
cp_error ("parameter `%D' declared void", parm);
- cleanup = maybe_build_cleanup (parm);
+ cleanup = (processing_template_decl
+ ? NULL_TREE
+ : maybe_build_cleanup (parm));
if (cleanup)
cleanups = tree_cons (parm, cleanup, cleanups);
}
else if (type != error_mark_node
- && TYPE_NEEDS_DESTRUCTOR (type))
+ && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
parms_have_cleanups = 1;
}
else
/* Do the starting of the exception specifications, if we have any. */
if (flag_exceptions && !processing_template_decl
+ && flag_enforce_eh_specs
&& building_stmt_tree ()
&& TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
current_eh_spec_try_block = expand_start_eh_spec ();
while (vbases)
{
- if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (vbases)))
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (vbases)))
{
tree vb = get_vbase
(BINFO_TYPE (vbases),
/* Finish dealing with exception specifiers. */
if (flag_exceptions && !processing_template_decl
+ && flag_enforce_eh_specs
&& TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
expand_end_eh_spec (TYPE_RAISES_EXCEPTIONS
(TREE_TYPE (current_function_decl)),
{
int returns_null;
int returns_value;
- int saved_flag_keep_inline_functions =
- flag_keep_inline_functions;
/* So we can tell if jump_optimize sets it to 1. */
can_reach_end = 0;
- if (DECL_CONTEXT (fndecl) != NULL_TREE
- && hack_decl_function_context (fndecl))
- /* Trick rest_of_compilation into not deferring output of this
- function, even if it is inline, since the rtl_obstack for
- this function is the function_obstack of the enclosing
- function and will be deallocated when the enclosing
- function is gone. See save_tree_status. */
- flag_keep_inline_functions = 1;
-
/* Before we call rest_of_compilation (which will pop the
CURRENT_FUNCTION), we must save these values. */
returns_null = current_function_returns_null;
if (function_depth > 1)
ggc_pop_context ();
- flag_keep_inline_functions = saved_flag_keep_inline_functions;
-
if (DECL_SAVED_INSNS (fndecl) && ! TREE_ASM_WRITTEN (fndecl))
{
/* Set DECL_EXTERNAL so that assemble_external will be called as
tree decl, auto_delete;
{
tree type = TREE_TYPE (decl);
- if (type != error_mark_node && TYPE_NEEDS_DESTRUCTOR (type))
+ if (type != error_mark_node && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
{
int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR;
tree rval;