/* Process declarations and variables for C compiler.
- Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
- Free Software Foundation, Inc.
+ Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
#include "cp-tree.h"
#include "decl.h"
#include "lex.h"
-#include "defaults.h"
#include "output.h"
#include "except.h"
#include "toplev.h"
extern int (*valid_lang_attribute) PARAMS ((tree, tree, tree, tree));
#ifndef BOOL_TYPE_SIZE
-#ifdef SLOW_BYTE_ACCESS
/* In the new ABI, `bool' has size and alignment `1', on all
platforms. */
-#define BOOL_TYPE_SIZE \
- ((SLOW_BYTE_ACCESS && !flag_new_abi) ? (POINTER_SIZE) : (CHAR_TYPE_SIZE))
-#else
#define BOOL_TYPE_SIZE CHAR_TYPE_SIZE
#endif
-#endif
-
-/* We let tm.h override the types used here, to handle trivial differences
- such as the choice of unsigned int or long unsigned int for size_t.
- When machines start needing nontrivial differences in the size type,
- it would be best to do something here to figure out automatically
- from other information what type to use. */
-
-#ifndef SIZE_TYPE
-#define SIZE_TYPE "long unsigned int"
-#endif
-
-#ifndef PTRDIFF_TYPE
-#define PTRDIFF_TYPE "long int"
-#endif
-
-#ifndef WCHAR_TYPE
-#define WCHAR_TYPE "int"
-#endif
static tree grokparms PARAMS ((tree));
static const char *redeclaration_error_message PARAMS ((tree, tree));
struct binding_level *, int));
static void set_identifier_type_value_with_scope
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, enum tree_code, tree));
static int member_function_or_else PARAMS ((tree, tree, enum overload_flags));
static tree cp_make_fname_decl PARAMS ((tree, const char *, int));
static void initialize_predefined_identifiers PARAMS ((void));
static tree check_special_function_return_type
- PARAMS ((special_function_kind, tree, tree, tree));
+ PARAMS ((special_function_kind, tree, tree));
static tree push_cp_library_fn PARAMS ((enum tree_code, tree));
static tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree));
static void store_parm_decls PARAMS ((tree));
+static int cp_missing_noreturn_ok_p PARAMS ((tree));
#if defined (DEBUG_CP_BINDING_LEVELS)
static void indent PARAMS ((void));
int flag_noniso_default_format_attributes = 1;
-/* Nonzero means give `double' the same size as `float'. */
-
-extern int flag_short_double;
-
/* Nonzero if we want to conserve space in the .o files. We do this
by putting uninitialized data and runtime initialized data into
.common instead of .data at the expense of not flagging multiple
/* If this binding level is the binding level for a class, then
class_shadowed is a TREE_LIST. The TREE_PURPOSE of each node
- is the name of an entity bound in the class; the TREE_VALUE is
- the IDENTIFIER_CLASS_VALUE before we entered the class. Thus,
- when leaving class scope, we can restore the
- IDENTIFIER_CLASS_VALUE by walking this list. The TREE_TYPE is
+ is the name of an entity bound in the class. The TREE_TYPE is
the DECL bound by this name in the class. */
tree class_shadowed;
/* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and
- is used for all binding levels. */
+ is used for all binding levels. In addition the TREE_VALUE is the
+ IDENTIFIER_TYPE_VALUE before we entered the class. */
tree type_shadowed;
/* A TREE_LIST. Each TREE_VALUE is the LABEL_DECL for a local
#define current_binding_level \
(cfun \
- ? cp_function_chain->bindings \
+ ? cp_function_chain->bindings \
: scope_chain->bindings)
/* The binding level of the current class, if any. */
keep_next_level_flag = 0;
}
+/* We're defining an object of type TYPE. If it needs a cleanup, but
+ we're not allowed to add any more objects with cleanups to the current
+ scope, create a new binding level. */
+
+void
+maybe_push_cleanup_level (type)
+ tree type;
+{
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+ && current_binding_level->more_cleanups_ok == 0)
+ {
+ keep_next_level (2);
+ pushlevel (1);
+ clear_last_expr ();
+ add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1);
+ }
+}
+
/* Enter a new scope. The KIND indicates what kind of scope is being
created. */
#define BINDING_LEVEL(NODE) \
(((struct tree_binding*)NODE)->scope.level)
+/* A free list of CPLUS_BINDING nodes, connected by their
+ TREE_CHAINs. */
+
+static tree free_bindings;
+
/* Make DECL the innermost binding for ID. The LEVEL is the binding
level at which this declaration is being bound. */
{
tree binding;
- binding = make_node (CPLUS_BINDING);
+ if (free_bindings)
+ {
+ binding = free_bindings;
+ free_bindings = TREE_CHAIN (binding);
+ }
+ else
+ binding = make_node (CPLUS_BINDING);
/* Now, fill in the binding information. */
BINDING_VALUE (binding) = decl;
else
{
my_friendly_assert (DECL_P (decl), 0);
- context = CP_DECL_CONTEXT (decl);
+ context = context_for_name_lookup (decl);
}
if (is_properly_derived_from (current_class_type, context))
my_friendly_abort (0);
if (!BINDING_VALUE (binding) && !BINDING_TYPE (binding))
- /* We're completely done with the innermost binding for this
- identifier. Unhook it from the list of bindings. */
- IDENTIFIER_BINDING (id) = TREE_CHAIN (binding);
+ {
+ /* We're completely done with the innermost binding for this
+ identifier. Unhook it from the list of bindings. */
+ IDENTIFIER_BINDING (id) = TREE_CHAIN (binding);
+
+ /* Add it to the free list. */
+ TREE_CHAIN (binding) = free_bindings;
+ free_bindings = binding;
+
+ /* Clear the BINDING_LEVEL so the garbage collector doesn't walk
+ it. */
+ BINDING_LEVEL (binding) = NULL;
+ }
}
/* When a label goes out of scope, check to see if that label was used
if (TREE_VEC_ELT (t1, 0) == id)
goto skip_it;
+ my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
binding = make_tree_vec (4);
-
- if (id)
- {
- my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
- TREE_VEC_ELT (binding, 0) = id;
- TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id);
- TREE_VEC_ELT (binding, 2) = IDENTIFIER_BINDING (id);
- TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id);
- IDENTIFIER_BINDING (id) = NULL_TREE;
- IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
- }
+ TREE_VEC_ELT (binding, 0) = id;
+ TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id);
+ TREE_VEC_ELT (binding, 2) = IDENTIFIER_BINDING (id);
+ TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id);
+ IDENTIFIER_BINDING (id) = NULL_TREE;
+ IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
TREE_CHAIN (binding) = old_bindings;
old_bindings = binding;
skip_it:
for (t = s->old_bindings; t; t = TREE_CHAIN (t))
{
tree id = TREE_VEC_ELT (t, 0);
- if (id)
- {
- SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1));
- IDENTIFIER_BINDING (id) = TREE_VEC_ELT (t, 2);
- IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3);
- }
+
+ SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1));
+ IDENTIFIER_BINDING (id) = TREE_VEC_ELT (t, 2);
+ IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3);
}
/* If we were in the middle of compiling a function, restore our
VARRAY_PUSH_TREE (local_classes, type);
if (!uses_template_parms (type))
- {
- if (flag_new_abi)
- DECL_ASSEMBLER_NAME (d) = mangle_type (type);
- else
- DECL_ASSEMBLER_NAME (d)
- = get_identifier (build_overload_name (type, 1, 1));
- }
+ DECL_ASSEMBLER_NAME (d) = mangle_type (type);
}
if (b->parm_flag == 2)
{
DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
DECL_NEEDS_FINAL_OVERRIDER_P (newdecl) |= DECL_NEEDS_FINAL_OVERRIDER_P (olddecl);
DECL_THIS_STATIC (newdecl) |= DECL_THIS_STATIC (olddecl);
- DECL_LANG_SPECIFIC (newdecl)->u2 = DECL_LANG_SPECIFIC (olddecl)->u2;
+ if (DECL_OVERLOADED_OPERATOR_P (olddecl) != ERROR_MARK)
+ SET_OVERLOADED_OPERATOR_CODE
+ (newdecl, DECL_OVERLOADED_OPERATOR_P (olddecl));
new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
/* Optionally warn about more than one declaration for the same
DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl);
DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
+ DECL_INITIALIZED_IN_CLASS_P (newdecl)
+ |= DECL_INITIALIZED_IN_CLASS_P (olddecl);
olddecl_friend = DECL_FRIEND_P (olddecl);
/* Only functions have DECL_BEFRIENDING_CLASSES. */
DECL_INLINE (olddecl) = 1;
DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
+ /* Preserve abstractness on cloned [cd]tors. */
+ DECL_ABSTRACT (newdecl) = DECL_ABSTRACT (olddecl);
+
if (! types_match)
{
DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl);
else if (TREE_CODE (t) == PARM_DECL)
{
if (DECL_CONTEXT (t) == NULL_TREE)
- fatal ("parse errors have confused me too much");
+ /* This is probaby caused by too many errors, but calling
+ abort will say that if errors have occurred. */
+ abort ();
/* Check for duplicate params. */
if (duplicate_decls (x, t))
else
old_decl = BINDING_VALUE (binding);
- /* There was already a binding for X containing fewer
- functions than are named in X. Find the previous
- declaration of X on the class-shadowed list, and update it. */
+ /* Find the previous binding of name on the class-shadowed
+ list, and update it. */
for (shadow = class_binding_level->class_shadowed;
shadow;
shadow = TREE_CHAIN (shadow))
BINDING_VALUE (binding) = x;
INHERITED_VALUE_BINDING_P (binding) = 0;
TREE_TYPE (shadow) = x;
+ IDENTIFIER_CLASS_VALUE (name) = x;
return;
}
}
/* If we didn't replace an existing binding, put the binding on the
- stack of bindings for the identifier, and update
- IDENTIFIER_CLASS_VALUE. */
+ stack of bindings for the identifier, and update the shadowed list. */
if (push_class_binding (name, x))
{
class_binding_level->class_shadowed
- = tree_cons (name, IDENTIFIER_CLASS_VALUE (name),
+ = tree_cons (name, NULL,
class_binding_level->class_shadowed);
/* Record the value we are binding NAME to so that we can know
what to pop later. */
/* Note that we've seen a definition of a case label, and complain if this
is a bad place for one. */
-void
+tree
finish_case_label (low_value, high_value)
tree low_value;
tree high_value;
{
- tree cond;
+ tree cond, r;
register struct binding_level *p;
if (! switch_stack)
low_value);
else
error ("`default' label not within a switch statement");
- return;
+ return NULL_TREE;
}
if (processing_template_decl)
/* For templates, just add the case label; we'll do semantic
analysis at instantiation-time. */
label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
- add_stmt (build_case_label (low_value, high_value, label));
- return;
+ return add_stmt (build_case_label (low_value, high_value, label));
}
/* Find the condition on which this switch statement depends. */
if (cond && TREE_CODE (cond) == TREE_LIST)
cond = TREE_VALUE (cond);
- c_add_case_label (switch_stack->cases, cond, low_value, high_value);
+ r = c_add_case_label (switch_stack->cases, cond, low_value, high_value);
+ if (r == error_mark_node)
+ r = NULL_TREE;
check_switch_goto (switch_stack->level);
for (p = current_binding_level; !(p->parm_flag); p = p->level_chain)
p->more_cleanups_ok = 0;
current_function_return_value = NULL_TREE;
+
+ return r;
}
\f
/* Return the list of declarations of the current level.
TREE_OPERAND (template_id, 1),
/*in_decl=*/NULL_TREE,
/*context=*/NULL_TREE,
- /*entering_scope=*/0);
+ /*entering_scope=*/0,
+ /*complain=*/1);
else if (DECL_FUNCTION_TEMPLATE_P (val)
|| TREE_CODE (val) == OVERLOAD)
val = lookup_template_function (val,
{
tree t;
tree d;
- struct hash_entry* e;
+ struct hash_entry *e;
static struct hash_table ht;
if (!ht.table)
{
static struct hash_table *h = &ht;
- if (!hash_table_init (&ht, &hash_newfunc, &typename_hash,
- &typename_compare))
- fatal ("virtual memory exhausted");
+
+ hash_table_init (&ht, &hash_newfunc, &typename_hash, &typename_compare);
ggc_add_tree_hash_table_root (&h, 1);
}
return lookup_template_class (tmpl,
TREE_OPERAND (fullname, 1),
NULL_TREE, context,
- /*entering_scope=*/0);
+ /*entering_scope=*/0,
+ /*complain=*/1);
}
else
{
&& TREE_CODE (val) == TYPE_DECL
&& ! same_type_p (TREE_TYPE (from_obj), TREE_TYPE (val)))
cp_pedwarn ("\
-lookup of `%D' in the scope of `%#T' (`%#T') \
-does not match lookup in the current scope (`%#T')",
- name, got_object, TREE_TYPE (from_obj),
- TREE_TYPE (val));
+lookup of `%D' in the scope of `%#T' (`%#D') \
+does not match lookup in the current scope (`%#D')",
+ name, got_object, from_obj, val);
/* We don't change val to from_obj if got_object depends on
template parms because that breaks implicit typename for
in the array RID_POINTERS. NAME is the name used when looking
up the builtin type. TYPE is the _TYPE node for the builtin type. */
-static void
+void
record_builtin_type (rid_index, name, type)
enum rid rid_index;
const char *name;
init_decl_processing ()
{
tree fields[20];
- int wchar_type_size;
- tree array_domain_type;
/* Check to see that the user did not specify an invalid combination
of command-line options. */
- if (flag_new_abi && !flag_vtable_thunks)
- fatal ("the new ABI requires vtable thunks");
+ if (!flag_vtable_thunks)
+ error ("the ABI requires vtable thunks");
/* Create all the identifiers we need. */
initialize_predefined_identifiers ();
mark_lang_status = &mark_cp_function_context;
lang_safe_from_p = &c_safe_from_p;
lang_dump_tree = &cp_dump_tree;
+ lang_missing_noreturn_ok_p = &cp_missing_noreturn_ok_p;
cp_parse_init ();
init_decl2 ();
pushdecl (fake_std_node);
}
- /* Define `int' and `char' first so that dbx will output them first. */
- record_builtin_type (RID_INT, NULL_PTR, integer_type_node);
- record_builtin_type (RID_CHAR, "char", char_type_node);
-
- /* `signed' is the same as `int' */
- record_builtin_type (RID_SIGNED, NULL_PTR, integer_type_node);
- record_builtin_type (RID_LONG, "long int", long_integer_type_node);
- record_builtin_type (RID_UNSIGNED, "unsigned int", unsigned_type_node);
- record_builtin_type (RID_MAX, "long unsigned int",
- long_unsigned_type_node);
- record_builtin_type (RID_MAX, "unsigned long", long_unsigned_type_node);
- record_builtin_type (RID_MAX, "long long int",
- long_long_integer_type_node);
- record_builtin_type (RID_MAX, "long long unsigned int",
- long_long_unsigned_type_node);
- record_builtin_type (RID_MAX, "long long unsigned",
- long_long_unsigned_type_node);
- record_builtin_type (RID_SHORT, "short int", short_integer_type_node);
- record_builtin_type (RID_MAX, "short unsigned int",
- short_unsigned_type_node);
- record_builtin_type (RID_MAX, "unsigned short",
- short_unsigned_type_node);
-
- /* Define both `signed char' and `unsigned char'. */
- record_builtin_type (RID_MAX, "signed char", signed_char_type_node);
- record_builtin_type (RID_MAX, "unsigned char", unsigned_char_type_node);
-
- /* `unsigned long' is the standard type for sizeof.
- Note that stddef.h uses `unsigned long',
- and this must agree, even if long and int are the same size. */
- c_size_type_node =
- TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE)));
- signed_size_type_node = signed_type (c_size_type_node);
- set_sizetype (c_size_type_node);
-
- /* Create the widest literal types. */
- widest_integer_literal_type_node = make_signed_type (HOST_BITS_PER_WIDE_INT * 2);
- pushdecl (build_decl (TYPE_DECL, NULL_TREE,
- widest_integer_literal_type_node));
-
- widest_unsigned_literal_type_node = make_unsigned_type (HOST_BITS_PER_WIDE_INT * 2);
- pushdecl (build_decl (TYPE_DECL, NULL_TREE,
- widest_unsigned_literal_type_node));
-
- /* These are types that type_for_size and type_for_mode use. */
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, intQI_type_node));
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, intHI_type_node));
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node));
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node));
-#if HOST_BITS_PER_WIDE_INT >= 64
- pushdecl (build_decl (TYPE_DECL, get_identifier ("__int128_t"), intTI_type_node));
-#endif
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node));
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intHI_type_node));
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node));
- pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node));
-#if HOST_BITS_PER_WIDE_INT >= 64
- pushdecl (build_decl (TYPE_DECL, get_identifier ("__uint128_t"), unsigned_intTI_type_node));
-#endif
-
- build_common_tree_nodes_2 (flag_short_double);
+ c_common_nodes_and_builtins ();
java_byte_type_node = record_builtin_java_type ("__java_byte", 8);
java_short_type_node = record_builtin_java_type ("__java_short", 16);
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);
- record_builtin_type (RID_DOUBLE, NULL_PTR, double_type_node);
- record_builtin_type (RID_MAX, "long double", long_double_type_node);
-
- pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
- complex_integer_type_node));
- pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
- complex_float_type_node));
- pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
- complex_double_type_node));
- pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
- complex_long_double_type_node));
-
TREE_TYPE (signed_size_zero_node) = make_signed_type (TYPE_PRECISION (sizetype));
- record_builtin_type (RID_VOID, NULL_PTR, void_type_node);
- void_list_node = build_tree_list (NULL_TREE, void_type_node);
- TREE_PARMLIST (void_list_node) = 1;
-
empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE);
- /* 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. */
- array_domain_type = build_index_type (build_int_2 (200, 0));
-
- /* Make a type for arrays of characters.
- With luck nothing will ever really depend on the length of this
- array type. */
- char_array_type_node
- = build_array_type (char_type_node, array_domain_type);
-
- /* Likewise for arrays of ints. */
- int_array_type_node
- = build_array_type (integer_type_node, array_domain_type);
-
- c_common_nodes_and_builtins ();
#if 0
record_builtin_type (RID_MAX, NULL_PTR, string_type_node);
#endif
- 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;
+ delta_type_node = ptrdiff_type_node;
+ vtable_index_type = ptrdiff_type_node;
vtt_parm_type = build_pointer_type (const_ptr_type_node);
lang_type_promotes_to = convert_type_from_ellipsis;
void_ftype_ptr
= build_exception_variant (void_ftype_ptr, empty_except_spec);
-#ifdef MD_INIT_BUILTINS
- MD_INIT_BUILTINS;
-#endif
-
/* C++ extensions */
unknown_type_node = make_node (UNKNOWN_TYPE);
TYPE_POINTER_TO (unknown_type_node) = unknown_type_node;
TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node;
- /* This is special for C++ so functions can be overloaded. */
- wchar_type_node = get_identifier (flag_short_wchar
- ? "short unsigned int"
- : WCHAR_TYPE);
- wchar_type_node = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (wchar_type_node));
- wchar_type_size = TYPE_PRECISION (wchar_type_node);
- if (TREE_UNSIGNED (wchar_type_node))
- wchar_type_node = make_signed_type (wchar_type_size);
- else
- wchar_type_node = make_unsigned_type (wchar_type_size);
- record_builtin_type (RID_WCHAR, "wchar_t", wchar_type_node);
-
- /* This is for wide string constants. */
- wchar_array_type_node
- = build_array_type (wchar_type_node, array_domain_type);
-
if (flag_vtable_thunks)
{
/* Make sure we get a unique function type, so we can give
layout_type (vtbl_ptr_type_node);
record_builtin_type (RID_MAX, NULL_PTR, vtbl_ptr_type_node);
- if (flag_new_abi)
- {
- push_namespace (get_identifier ("__cxxabiv1"));
- abi_node = current_namespace;
- pop_namespace ();
- }
+ push_namespace (get_identifier ("__cxxabiv1"));
+ abi_node = current_namespace;
+ pop_namespace ();
global_type_node = make_node (LANG_TYPE);
record_unknown_type (global_type_node, "global type");
}
abort_fndecl
- = build_library_fn_ptr ((flag_new_abi
- ? "__cxa_pure_virtual"
- : "__pure_virtual"),
- void_ftype);
+ = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype);
/* Perform other language dependent initializations. */
init_class_processing ();
ggc_add_tree_root (¤t_lang_name, 1);
ggc_add_tree_root (&static_aggregates, 1);
+ ggc_add_tree_root (&free_bindings, 1);
}
/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
if (!processing_template_decl)
type_dep = 0;
if (!type_dep)
- domain = build_index_type (build_int_2 (length, 0));
+ domain = build_index_type (size_int (length));
type = build_cplus_array_type
(build_qualified_type (char_type_node, TYPE_QUAL_CONST),
function in the namespace. */
if (libname)
DECL_ASSEMBLER_NAME (decl) = get_identifier (libname);
- make_function_rtl (decl);
+ make_decl_rtl (decl, NULL);
/* Warn if a function in the namespace for users
is used without an occasion to consider it declared. */
tree type;
{
tree fn = build_library_fn_1 (name, ERROR_MARK, type);
- make_function_rtl (fn);
+ make_decl_rtl (fn, NULL);
return fn;
}
TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace);
set_mangled_name_for_decl (fn);
- make_function_rtl (fn);
+ make_decl_rtl (fn, NULL);
return fn;
}
/* ISO C++ 9.5.3. Anonymous unions may not have function members. */
if (TYPE_METHODS (t))
- error ("an anonymous union cannot have function members");
+ cp_error_at ("an anonymous union cannot have function members", t);
}
/* Make sure that a declaration with no declarator is well-formed, i.e.
{
int found_type = 0;
int saw_friend = 0;
+ int saw_typedef = 0;
tree ob_modifier = NULL_TREE;
register tree link;
register tree t = NULL_TREE;
register tree value = TREE_VALUE (link);
if (TYPE_P (value)
+ || TREE_CODE (value) == TYPE_DECL
|| (TREE_CODE (value) == IDENTIFIER_NODE
&& IDENTIFIER_GLOBAL_VALUE (value)
- && TYPE_P (IDENTIFIER_GLOBAL_VALUE (value))))
+ && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (value)) == TYPE_DECL))
{
++found_type;
- if ((TREE_CODE (value) != TYPENAME_TYPE && IS_AGGR_TYPE (value))
- || TREE_CODE (value) == ENUMERAL_TYPE)
+ if (found_type == 2 && TREE_CODE (value) == IDENTIFIER_NODE)
+ {
+ if (! in_system_header)
+ cp_pedwarn ("redeclaration of C++ built-in type `%T'", value);
+ return NULL_TREE;
+ }
+
+ if (TYPE_P (value)
+ && ((TREE_CODE (value) != TYPENAME_TYPE && IS_AGGR_TYPE (value))
+ || TREE_CODE (value) == ENUMERAL_TYPE))
{
my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261);
t = value;
}
}
+ else if (value == ridpointers[(int) RID_TYPEDEF])
+ saw_typedef = 1;
else if (value == ridpointers[(int) RID_FRIEND])
{
if (current_class_type == NULL_TREE
&& TYPE_NAME (t)
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
{
+ /* 7/3 In a simple-declaration, the optional init-declarator-list
+ can be omitted only when declaring a class (clause 9) or
+ enumeration (7.2), that is, when the decl-specifier-seq contains
+ either a class-specifier, an elaborated-type-specifier with
+ a class-key (9.1), or an enum-specifier. In these cases and
+ whenever a class-specifier or enum-specifier is present in the
+ decl-specifier-seq, the identifiers in these specifiers are among
+ the names being declared by the declaration (as class-name,
+ enum-names, or enumerators, depending on the syntax). In such
+ cases, and except for the declaration of an unnamed bit-field (9.6),
+ the decl-specifier-seq shall introduce one or more names into the
+ program, or shall redeclare a name introduced by a previous
+ declaration. [Example:
+ enum { }; // ill-formed
+ typedef class { }; // ill-formed
+ --end example] */
+ if (saw_typedef)
+ {
+ error ("Missing type-name in typedef-declaration.");
+ return NULL_TREE;
+ }
/* Anonymous unions are objects, so they can have specifiers. */;
SET_ANON_AGGR_TYPE_P (t);
if (type == error_mark_node)
return;
- /* 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_HAS_NONTRIVIAL_DESTRUCTOR (type)
- && current_binding_level->more_cleanups_ok == 0)
- {
- keep_next_level (2);
- pushlevel (1);
- clear_last_expr ();
- add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1);
- }
+ maybe_push_cleanup_level (type);
if (initialized)
/* Is it valid for this decl to have an initializer at all?
which we can't if it has been initialized. */
if (TREE_PUBLIC (decl))
- DECL_ASSEMBLER_NAME (decl)
- = build_static_name (current_function_decl, DECL_NAME (decl));
+ DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
else
{
cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl);
DECL_INITIAL (decl) = init;
- /* This will keep us from needing to worry about our obstacks. */
my_friendly_assert (init != NULL_TREE, 149);
init = NULL_TREE;
}
else if (!DECL_EXTERNAL (decl) && TREE_CODE (type) == REFERENCE_TYPE)
{
if (TREE_STATIC (decl))
- make_decl_rtl (decl, NULL_PTR, toplevel_bindings_p ());
+ make_decl_rtl (decl, NULL_PTR);
grok_reference_init (decl, type, init);
init = NULL_TREE;
}
/* If we're deferring the variable, just make RTL. Do not actually
emit the variable. */
if (defer_p)
- make_decl_rtl (decl, asmspec, toplev);
+ make_decl_rtl (decl, asmspec);
/* If we're not deferring, go ahead and assemble the variable. */
else
rest_of_decl_compilation (decl, asmspec, toplev, at_eof);
&& CP_DECL_CONTEXT (decl) == current_class_type
&& TYPE_BEING_DEFINED (current_class_type)
&& (DECL_INITIAL (decl) || init))
- DECL_DEFINED_IN_CLASS_P (decl) = 1;
+ DECL_INITIALIZED_IN_CLASS_P (decl) = 1;
if (TREE_CODE (decl) == VAR_DECL
&& DECL_CONTEXT (decl)
grokclassfn. Lay this out fresh. */
DECL_RTL (TREE_TYPE (decl)) = NULL_RTX;
DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
- make_decl_rtl (decl, asmspec, 0);
+ make_decl_rtl (decl, asmspec);
}
/* Deduce size of array from initialization, if not already known. */
object, type);
if (friendp)
cp_error_at ("`%D' declared as a friend", object);
- if (raises)
+ if (raises && !TYPE_PTRFN_P (TREE_TYPE (object))
+ && !TYPE_PTRMEMFUNC_P (TREE_TYPE (object)))
cp_error_at ("`%D' declared with an exception specification", object);
}
{
tree fns = TREE_OPERAND (orig_declarator, 0);
tree args = TREE_OPERAND (orig_declarator, 1);
-
+
if (PROCESSING_REAL_TEMPLATE_DECL_P ())
{
/* Something like `template <class T> friend void f<T>()'. */
up an operator_name or PFUNCNAME within the current class
(see template_id in parse.y). If the current class contains
such a name, we'll get a COMPONENT_REF here. Undo that. */
-
+
my_friendly_assert (TREE_TYPE (TREE_OPERAND (fns, 0))
== current_class_type, 20001120);
fns = TREE_OPERAND (fns, 1);
/* Plain overloading: will not be grok'd by grokclassfn. */
if (! ctype && ! processing_template_decl
- && !DECL_EXTERN_C_P (decl)
- && (! DECL_USE_TEMPLATE (decl) || name_mangling_version < 1))
+ && (! DECL_EXTERN_C_P (decl) || DECL_OVERLOADED_OPERATOR_P (decl))
+ && ! DECL_USE_TEMPLATE (decl))
set_mangled_name_for_decl (decl);
if (funcdef_flag)
/* DECL_ASSEMBLER_NAME is needed only for full-instantiated
templates. */
if (!uses_template_parms (decl))
- {
- if (flag_new_abi)
- DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
- else
- DECL_ASSEMBLER_NAME (decl) = build_static_name (basetype,
- declarator);
- }
+ DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
}
else
{
context = DECL_CONTEXT (decl);
if (declarator && context && current_lang_name != lang_name_c)
- {
- if (flag_new_abi)
- DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
- else
- DECL_ASSEMBLER_NAME (decl)
- = build_static_name (context, declarator);
- }
+ DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
}
if (in_namespace)
{
tree fields[4];
tree t;
- tree u;
tree unqualified_variant = NULL_TREE;
if (type == error_mark_node)
return type;
-
+
/* If a canonical type already exists for this type, use it. We use
this method instead of type_hash_canon, because it only does a
simple equality check on the list of field members. */
/* ... and not really an aggregate. */
SET_IS_AGGR_TYPE (t, 0);
- if (!flag_new_abi)
- {
- u = make_aggr_type (UNION_TYPE);
- SET_IS_AGGR_TYPE (u, 0);
- fields[0] = build_decl (FIELD_DECL, pfn_identifier, type);
- fields[1] = build_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_decl (FIELD_DECL, delta_identifier,
- delta_type_node);
- fields[1] = build_decl (FIELD_DECL, index_identifier,
- delta_type_node);
- fields[2] = build_decl (FIELD_DECL, pfn_or_delta2_identifier, u);
- finish_builtin_type (t, "__ptrmemfunc_type", fields, 2, ptr_type_node);
- }
- else
- {
- fields[0] = build_decl (FIELD_DECL, pfn_identifier, type);
- fields[1] = build_decl (FIELD_DECL, delta_identifier,
- delta_type_node);
- finish_builtin_type (t, "__ptrmemfunc_type", fields, 1, ptr_type_node);
- }
+ fields[0] = build_decl (FIELD_DECL, pfn_identifier, type);
+ fields[1] = build_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. */
/* Check that it's OK to declare a function with the indicated TYPE.
SFK indicates the kind of special function (if any) that this
- function is. CTYPE is the class of which this function is a
- member. OPTYPE is the type given in a conversion operator
+ function is. OPTYPE is the type given in a conversion operator
declaration. Returns the actual return type of the function; that
may be different than TYPE if an error occurs, or for certain
special functions. */
static tree
-check_special_function_return_type (sfk, type, ctype, optype)
+check_special_function_return_type (sfk, type, optype)
special_function_kind sfk;
tree type;
- tree ctype;
tree optype;
{
switch (sfk)
if (type)
cp_error ("return type specification for constructor invalid");
- /* In the old ABI, we return `this'; in the new ABI we don't
- bother. */
- type = flag_new_abi ? void_type_node : build_pointer_type (ctype);
+ /* In the new ABI constructors do not return a value. */
+ type = void_type_node;
break;
case sfk_destructor:
if (sfk != sfk_none)
type = check_special_function_return_type (sfk, type,
- ctor_return_type,
ctor_return_type);
else if (type == NULL_TREE)
{
else if (RIDBIT_SETP (RID_TYPEDEF, specbits))
;
else if (decl_context == FIELD
- /* C++ allows static class elements */
- && RIDBIT_SETP (RID_STATIC, specbits))
- /* C++ also allows inlines and signed and unsigned elements,
- but in those cases we don't come in here. */
+ /* C++ allows static class elements */
+ && RIDBIT_SETP (RID_STATIC, specbits))
+ /* C++ also allows inlines and signed and unsigned elements,
+ but in those cases we don't come in here. */
;
else
{
cp_error ("constructors may not be `%s'",
IDENTIFIER_POINTER (TREE_VALUE (quals)));
quals = NULL_TREE;
- }
+ }
{
RID_BIT_TYPE tmp_bits;
memcpy (&tmp_bits, &specbits, sizeof (RID_BIT_TYPE));
the definition of `S<int>::f'. */
if (CLASSTYPE_TEMPLATE_INFO (t)
&& (CLASSTYPE_TEMPLATE_INSTANTIATION (t)
- || uses_template_parms (CLASSTYPE_TI_ARGS (t))))
+ || uses_template_parms (CLASSTYPE_TI_ARGS (t)))
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))
template_count += 1;
t = TYPE_MAIN_DECL (t);
- if (DECL_LANG_SPECIFIC (t))
- t = DECL_CONTEXT (t);
- else
- t = NULL_TREE;
+ t = DECL_CONTEXT (t);
}
if (sname == NULL_TREE)
{
incomplete_type_error (NULL_TREE, ctype);
return error_mark_node;
- }
+ }
declarator = sname;
}
DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
= TYPE_IDENTIFIER (type);
- if (flag_new_abi)
- DECL_ASSEMBLER_NAME (decl) = mangle_type (type);
- else
- {
- /* XXX Temporarily set the scope.
- When returning, start_decl expects it as NULL_TREE,
- and will then then set it using pushdecl. */
- my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 980404);
- if (current_class_type)
- DECL_CONTEXT (decl) = current_class_type;
- else
- DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
-
- DECL_ASSEMBLER_NAME (decl) = DECL_NAME (decl);
- DECL_ASSEMBLER_NAME (decl)
- = get_identifier (build_overload_name (type, 1, 1));
- DECL_CONTEXT (decl) = NULL_TREE;
- }
+ DECL_ASSEMBLER_NAME (decl) = mangle_type (type);
/* FIXME remangle member functions; member functions of a
type with external linkage have external linkage. */
if (type != integer_type_node)
{
decl_type_access_control (TYPE_NAME (type));
-
+
/* A friendly class? */
if (current_class_type)
make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type));
else
cp_error ("trying to make class `%T' a friend of global scope",
type);
-
+
type = void_type_node;
}
}
/* The constructor can be called with exactly one
parameter if there is at least one parameter, and
any subsequent parameters have default arguments.
- We don't look at the first parameter, which is
- really just the `this' parameter for the new
- object. */
- tree arg_types =
- TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)));
-
- /* Skip the `in_chrg' argument too, if present. */
- if (DECL_HAS_IN_CHARGE_PARM_P (decl))
- arg_types = TREE_CHAIN (arg_types);
+ Ignore any compiler-added parms. */
+ tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (decl);
if (arg_types == void_list_node
|| (arg_types
break;
decl = grokdeclarator (TREE_VALUE (decl), TREE_PURPOSE (decl),
- PARM, init != NULL_TREE, NULL_TREE);
+ PARM, init != NULL_TREE, NULL_TREE);
if (! decl || TREE_TYPE (decl) == error_mark_node)
continue;
-
+
type = TREE_TYPE (decl);
if (VOID_TYPE_P (type))
{
TREE_TYPE (decl) = error_mark_node;
}
- if (type != error_mark_node)
+ if (type != error_mark_node)
{
/* Top-level qualifiers on the parameters are
ignored for function types. */
{
/* [dcl.fct]/6, parameter types cannot contain pointers
(references) to arrays of unknown bound. */
- tree t = type;
-
- while (POINTER_TYPE_P (t)
- || (TREE_CODE (t) == ARRAY_TYPE
- && TYPE_DOMAIN (t) != NULL_TREE))
- t = TREE_TYPE (t);
+ tree t = TREE_TYPE (type);
+ int ptr = TYPE_PTR_P (type);
+
+ while (1)
+ {
+ if (TYPE_PTR_P (t))
+ ptr = 1;
+ else if (TREE_CODE (t) != ARRAY_TYPE)
+ break;
+ else if (!TYPE_DOMAIN (t))
+ break;
+ t = TREE_TYPE (t);
+ }
if (TREE_CODE (t) == ARRAY_TYPE)
cp_error ("parameter `%D' includes %s to array of unknown bound `%T'",
- decl, TYPE_PTR_P (type) ? "pointer" : "reference", t);
+ decl, ptr ? "pointer" : "reference", t);
}
DECL_ARG_TYPE (decl) = TREE_TYPE (decl);
return result;
}
-/* Called from the parser to update an element of TYPE_ARG_TYPES for some
- FUNCTION_TYPE with the newly parsed version of its default argument, which
- was previously digested as text. See snarf_defarg et al in lex.c. */
-
-void
-replace_defarg (arg, init)
- tree arg, init;
-{
- if (! processing_template_decl
- && ! can_convert_arg (TREE_VALUE (arg), TREE_TYPE (init), init))
- cp_pedwarn ("invalid type `%T' for default argument to `%T'",
- TREE_TYPE (init), TREE_VALUE (arg));
- 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
if (!DECL_FUNCTION_MEMBER_P (d))
return 0;
- t = FUNCTION_ARG_CHAIN (d);
- if (DECL_CONSTRUCTOR_P (d) && DECL_HAS_IN_CHARGE_PARM_P (d))
- t = TREE_CHAIN (t);
+ t = FUNCTION_FIRST_USER_PARMTYPE (d);
if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
&& (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t)))
== DECL_CONTEXT (d))
grok_ctor_properties (ctype, decl)
tree ctype, decl;
{
- tree parmtypes = FUNCTION_ARG_CHAIN (decl);
+ tree parmtypes = FUNCTION_FIRST_USER_PARMTYPE (decl);
tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node;
- /* When a type has virtual baseclasses, a magical first int argument is
- added to any ctor so we can tell if the class has been initialized
- yet. This could screw things up in this function, so we deliberately
- ignore the leading int if we're in that situation. */
- if (DECL_HAS_IN_CHARGE_PARM_P (decl))
- {
- my_friendly_assert (parmtypes
- && TREE_VALUE (parmtypes) == integer_type_node,
- 980529);
- parmtypes = TREE_CHAIN (parmtypes);
- parmtype = TREE_VALUE (parmtypes);
- }
-
/* [class.copy]
A non-template constructor for class X is a copy constructor if
/* Constructors and destructors need to know whether they're "in
charge" of initializing virtual base classes. */
+ t = TREE_CHAIN (t);
if (DECL_HAS_IN_CHARGE_PARM_P (decl1))
- current_in_charge_parm = TREE_CHAIN (t);
+ {
+ current_in_charge_parm = t;
+ t = TREE_CHAIN (t);
+ }
+ if (DECL_HAS_VTT_PARM_P (decl1))
+ {
+ if (DECL_NAME (t) != vtt_parm_identifier)
+ abort ();
+ current_vtt_parm = t;
+ }
}
if (DECL_INTERFACE_KNOWN (decl1))
/* We need to do this even if we aren't expanding yet so that
assemble_external works. */
- make_function_rtl (decl1);
+ make_decl_rtl (decl1, NULL);
/* Promote the value to int before returning it. */
if (C_PROMOTING_INTEGER_TYPE_P (restype))
dtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
DECL_CONTEXT (dtor_label) = current_function_decl;
}
- /* Under the old ABI we return `this' from constructors, so we make
- ordinary `return' statements in constructors jump to CTOR_LABEL;
- from there we return `this'. Under the new ABI, we don't bother
- with any of this. By not setting CTOR_LABEL the remainder of the
- machinery is automatically disabled. */
- else if (!flag_new_abi && DECL_CONSTRUCTOR_P (decl1))
- {
- ctor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
- DECL_CONTEXT (ctor_label) = current_function_decl;
- }
store_parm_decls (current_function_parms);
finish_destructor_body ()
{
tree compound_stmt;
- tree virtual_size;
tree exprstmt;
- tree if_stmt;
/* Create a block to contain all the extra code. */
compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
vbases = TREE_CHAIN (vbases))
{
tree vbase = TREE_VALUE (vbases);
+ tree base_type = BINFO_TYPE (vbase);
- if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (vbase)))
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (base_type))
{
- tree vb = get_vbase
- (BINFO_TYPE (vbase),
- TYPE_BINFO (current_class_type));
- finish_expr_stmt
- (build_scoped_method_call
- (current_class_ref, vb, base_dtor_identifier,
- NULL_TREE));
+ tree base_ptr_type = build_pointer_type (base_type);
+ tree expr = current_class_ptr;
+
+ /* Convert to the basetype here, as we know the layout is
+ fixed. What is more, if we let build_method_call do it,
+ it will use the vtable, which may have been clobbered
+ by the deletion of our primary base. */
+
+ expr = build1 (NOP_EXPR, base_ptr_type, expr);
+ expr = build (PLUS_EXPR, base_ptr_type, expr,
+ BINFO_OFFSET (vbase));
+ expr = build_indirect_ref (expr, NULL);
+ expr = build_method_call (expr, base_dtor_identifier,
+ NULL_TREE, vbase,
+ LOOKUP_NORMAL);
+ finish_expr_stmt (expr);
}
}
}
}
- virtual_size = c_sizeof (current_class_type);
-
- /* At the end, call delete if that's what's requested. */
+ /* In a virtual destructor, we must call delete. */
+ if (DECL_VIRTUAL_P (current_function_decl))
+ {
+ tree if_stmt;
+ tree virtual_size = c_sizeof (current_class_type);
- /* FDIS sez: At the point of definition of a virtual destructor
- (including an implicit definition), non-placement operator delete
- shall be looked up in the scope of the destructor's class and if
- found shall be accessible and unambiguous.
+ /* [class.dtor]
- This is somewhat unclear, but I take it to mean that if the class
- only defines placement deletes we don't do anything here. So we
- pass LOOKUP_SPECULATIVELY; delete_sanity will complain for us if
- they ever try to delete one of these. */
- exprstmt = build_op_delete_call
- (DELETE_EXPR, current_class_ptr, virtual_size,
- LOOKUP_NORMAL | LOOKUP_SPECULATIVELY, NULL_TREE);
+ At the point of definition of a virtual destructor (including
+ an implicit definition), non-placement operator delete shall
+ be looked up in the scope of the destructor's class and if
+ found shall be accessible and unambiguous. */
+ exprstmt = build_op_delete_call
+ (DELETE_EXPR, current_class_ptr, virtual_size,
+ LOOKUP_NORMAL | LOOKUP_SPECULATIVELY, NULL_TREE);
- if_stmt = begin_if_stmt ();
- finish_if_stmt_cond (build (BIT_AND_EXPR, integer_type_node,
- current_in_charge_parm,
- integer_one_node),
- if_stmt);
- finish_expr_stmt (exprstmt);
- finish_then_clause (if_stmt);
- finish_if_stmt ();
+ if_stmt = begin_if_stmt ();
+ finish_if_stmt_cond (build (BIT_AND_EXPR, integer_type_node,
+ current_in_charge_parm,
+ integer_one_node),
+ if_stmt);
+ finish_expr_stmt (exprstmt);
+ finish_then_clause (if_stmt);
+ finish_if_stmt ();
+ }
/* Close the block we started above. */
finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
f->language = 0;
}
+/* Mark I for GC. */
+
+static void
+mark_inlined_fns (i)
+ struct lang_decl_inlined_fns *i;
+{
+ int n;
+
+ for (n = i->num_fns - 1; n >= 0; n--)
+ ggc_mark_tree (i->fns [n]);
+ ggc_set_mark (i);
+}
+
/* Mark P for GC. */
static void
ggc_mark_tree (ld->befriending_classes);
ggc_mark_tree (ld->context);
ggc_mark_tree (ld->cloned_function);
- if (!DECL_OVERLOADED_OPERATOR_P (t))
- ggc_mark_tree (ld->u2.vtt_parm);
+ if (ld->inlined_fns)
+ mark_inlined_fns (ld->inlined_fns);
if (TREE_CODE (t) == TYPE_DECL)
ggc_mark_tree (ld->u.sorted_fields);
else if (TREE_CODE (t) == FUNCTION_DECL
{
return IDENTIFIER_GLOBAL_VALUE (t);
}
+
+/* Build the void_list_node (void_type_node having been created). */
+tree
+build_void_list_node ()
+{
+ tree t = build_tree_list (NULL_TREE, void_type_node);
+ TREE_PARMLIST (t) = 1;
+ return t;
+}
+
+static int
+cp_missing_noreturn_ok_p (decl)
+ tree decl;
+{
+ /* A missing noreturn is ok for the `main' function. */
+ return MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
+}