#include "toplev.h"
#include "../hash.h"
#include "ggc.h"
+#include "tm_p.h"
extern int current_class_depth;
#define WCHAR_TYPE "int"
#endif
-#ifndef WINT_TYPE
-#define WINT_TYPE "unsigned int"
-#endif
-
-#ifndef INTMAX_TYPE
-#define INTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
- ? "int" \
- : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
- ? "long int" \
- : "long long int"))
-#endif
-
-#ifndef UINTMAX_TYPE
-#define UINTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
- ? "unsigned int" \
- : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
- ? "long unsigned int" \
- : "long long unsigned int"))
-#endif
-
-static tree grokparms PARAMS ((tree, int));
+static tree grokparms PARAMS ((tree));
static const char *redeclaration_error_message PARAMS ((tree, tree));
static void push_binding_level PARAMS ((struct binding_level *, int,
static void end_cleanup_fn PARAMS ((void));
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
+static tree check_special_function_return_type
PARAMS ((special_function_kind, tree, 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));
replaced with a TEMPLATE_DECL. */
unsigned template_parms_p : 1;
- /* Nonzero if this scope corresponds to the `<>' in a
+ /* Nonzero if this scope corresponds to the `<>' in a
`template <>' clause. Whenever this flag is set,
TEMPLATE_PARMS_P will be set as well. */
unsigned template_spec_p : 1;
{
/* Add this level to the front of the chain (stack) of levels that
are active. */
- bzero ((char*) newlevel, sizeof (struct binding_level));
+ memset ((char*) newlevel, 0, sizeof (struct binding_level));
newlevel->level_chain = current_binding_level;
current_binding_level = newlevel;
newlevel->tag_transparent = tag_transparent;
/* Process the decls in reverse order--earliest first.
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))
- {
- /* 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;
- }
+ vec[len - i - 1] = decl;
if (last_time)
{
tree names, old_bindings;
{
tree t;
+ tree search_bindings = old_bindings;
+
for (t = names; t; t = TREE_CHAIN (t))
{
tree binding, t1, id;
|| !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
continue;
- for (t1 = old_bindings; t1; t1 = TREE_CHAIN (t1))
+ for (t1 = search_bindings; t1; t1 = TREE_CHAIN (t1))
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
all function definitions in a translation unit in a convenient
way. (It's otherwise tricky to find a member function definition
it's only pointed to from within a local class.) */
- if (TYPE_CONTEXT (type)
+ if (TYPE_CONTEXT (type)
&& TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL
&& !processing_template_decl)
VARRAY_PUSH_TREE (local_classes, type);
- if (!uses_template_parms (type))
+ if (!uses_template_parms (type))
{
if (flag_new_abi)
DECL_ASSEMBLER_NAME (d) = mangle_type (type);
/* Or in the innermost namespace. */
if (! t)
t = namespace_binding (name, DECL_CONTEXT (x));
- /* Does it have linkage? */
- if (t && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
+ /* Does it have linkage? Note that if this isn't a DECL, it's an
+ OVERLOAD, which is OK. */
+ if (t && DECL_P (t) && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
t = NULL_TREE;
if (t)
different_binding_level = 1;
warn if we later see static one. */
if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x))
TREE_PUBLIC (name) = 1;
-
+
/* Bind the mangled name for the entity. In the future, we
should not need to do this; mangled names are an
implementation detail of which the front-end should not
else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{
if ((TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
- && (DECL_TEMPLATE_RESULT (newdecl)
+ && (DECL_TEMPLATE_RESULT (newdecl)
!= DECL_TEMPLATE_RESULT (olddecl))
&& DECL_INITIAL (DECL_TEMPLATE_RESULT (newdecl))
&& DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)))
{
tree decl = lookup_label (name);
struct named_label_list *ent;
+ register struct binding_level *p;
for (ent = named_labels; ent; ent = ent->next)
if (ent->label_decl == decl)
break;
- /* After labels, make any new cleanups go into their
+ /* After labels, make any new cleanups in the function go into their
own new (temporary) binding contour. */
- current_binding_level->more_cleanups_ok = 0;
+ for (p = current_binding_level; !(p->parm_flag); p = p->level_chain)
+ p->more_cleanups_ok = 0;
if (name == get_identifier ("wchar_t"))
cp_pedwarn ("label named wchar_t");
mark the stack for garbage collection because it is only active
during the processing of the body of a function, and we never
collect at that point. */
-
+
static struct cp_switch *switch_stack;
/* Called right after a switch-statement condition is parsed.
pop_switch ()
{
struct cp_switch *cs;
-
+
cs = switch_stack;
splay_tree_delete (cs->cases);
switch_stack = switch_stack->next;
/* 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)
{
if (high_value)
error ("case label not within a switch statement");
else if (low_value)
- cp_error ("case label `%E' not within a switch statement",
+ cp_error ("case label `%E' not within a switch statement",
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);
- /* After labels, make any new cleanups go into their
+ /* After labels, make any new cleanups in the function go into their
own new (temporary) binding contour. */
- current_binding_level->more_cleanups_ok = 0;
+ 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.
/* When we implicitly declare some builtin entity, we mark it
DECL_ANTICIPATED, so that we know to ignore it until it is
really declared. */
- if (val && DECL_P (val)
- && DECL_LANG_SPECIFIC (val)
+ if (val && DECL_P (val)
+ && DECL_LANG_SPECIFIC (val)
&& DECL_ANTICIPATED (val))
return NULL_TREE;
if (got_scope)
goto done;
else if (got_object && val)
- from_obj = val;
+ {
+ from_obj = val;
+ val = NULL_TREE;
+ }
}
else
{
{
if (looking_for_typename && TREE_CODE (from_obj) == TYPE_DECL
&& TREE_CODE (val) == TYPE_DECL
- && TREE_TYPE (from_obj) != TREE_TYPE (val))
- {
- cp_pedwarn ("lookup of `%D' in the scope of `%#T' (`%#T')",
- name, got_object, TREE_TYPE (from_obj));
- cp_pedwarn (" does not match lookup in the current scope (`%#T')",
- TREE_TYPE (val));
- }
+ && ! 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));
/* We don't change val to from_obj if got_object depends on
template parms because that breaks implicit typename for
/* Create all the predefined identifiers. */
static void
-initialize_predefined_identifiers ()
+initialize_predefined_identifiers ()
{
struct predefined_identifier *pid;
free_lang_status = &pop_cp_function_context;
mark_lang_status = &mark_cp_function_context;
lang_safe_from_p = &c_safe_from_p;
+ lang_dump_tree = &cp_dump_tree;
cp_parse_init ();
init_decl2 ();
void_type_node);
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);
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);
+ short_unsigned_type_node);
record_builtin_type (RID_MAX, "unsigned short",
short_unsigned_type_node);
- ptrdiff_type_node
- = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
- unsigned_ptrdiff_type_node = unsigned_type (ptrdiff_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);
void_list_node = build_tree_list (NULL_TREE, void_type_node);
TREE_PARMLIST (void_list_node) = 1;
- string_type_node = build_pointer_type (char_type_node);
- const_string_type_node
- = build_pointer_type (build_qualified_type (char_type_node,
- TYPE_QUAL_CONST));
empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE);
-#if 0
- record_builtin_type (RID_MAX, NULL_PTR, string_type_node);
-#endif
-
/* 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. */
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)
else
vtable_index_type = delta_type_node;
- default_function_type
- = build_function_type (integer_type_node, NULL_TREE);
-
- ptr_type_node = build_pointer_type (void_type_node);
- const_ptr_type_node
- = build_pointer_type (build_qualified_type (void_type_node,
- TYPE_QUAL_CONST));
vtt_parm_type = build_pointer_type (const_ptr_type_node);
- c_common_nodes_and_builtins ();
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);
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);
-
- /* Artificial declaration of wchar_t -- can be bashed */
- wchar_decl_node = build_decl (TYPE_DECL, get_identifier ("wchar_t"),
- wchar_type_node);
- pushdecl (wchar_decl_node);
+ 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);
- wint_type_node =
- TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WINT_TYPE)));
-
- intmax_type_node =
- TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (INTMAX_TYPE)));
- uintmax_type_node =
- TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (UINTMAX_TYPE)));
-
if (flag_vtable_thunks)
{
/* Make sure we get a unique function type, so we can give
}
abort_fndecl
- = build_library_fn_ptr ("__pure_virtual", void_ftype);
+ = build_library_fn_ptr ((flag_new_abi
+ ? "__cxa_pure_virtual"
+ : "__pure_virtual"),
+ void_ftype);
/* Perform other language dependent initializations. */
init_class_processing ();
tree decl, type, init;
size_t length = strlen (name);
tree domain = NULL_TREE;
-
+
if (!processing_template_decl)
type_dep = 0;
if (!type_dep)
}
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;
}
/* All builtins that don't begin with an `_' should go in the `std'
namespace. */
- if (flag_honor_std && name[0] != '_')
+ if (flag_honor_std && name[0] != '_')
{
push_namespace (std_identifier);
DECL_CONTEXT (decl) = std_node;
enum tree_code operator_code;
tree type;
{
- tree fn = build_cp_library_fn (ansi_opname (operator_code),
+ tree fn = build_cp_library_fn (ansi_opname (operator_code),
operator_code,
type);
pushdecl (fn);
&& TREE_CODE (decl) != TYPE_DECL
&& TREE_CODE (decl) != TEMPLATE_DECL
&& type != error_mark_node
- && IS_AGGR_TYPE (type)
+ && IS_AGGR_TYPE (type)
&& ! DECL_EXTERNAL (decl))
{
if ((! processing_template_decl || ! uses_template_parms (type))
inlining of such functions. */
current_function_cannot_inline
= "function with static variable cannot be inline";
+ DECL_UNINLINABLE (current_function_decl) = 1;
/* If flag_weak, we don't need to mess with this, as we can just
make the function weak, and let it refer to its unique local
{
if (!DECL_NAME (decl))
return;
-
+
if (current_binding_level->is_for_scope)
{
struct binding_level *outer
saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
current_stmt_tree ()->stmts_are_full_exprs_p = 1;
finish_expr_stmt (build_aggr_init (decl, init, flags));
- current_stmt_tree ()->stmts_are_full_exprs_p =
+ current_stmt_tree ()->stmts_are_full_exprs_p =
saved_stmts_are_full_exprs_p;
}
if (type == error_mark_node)
return;
-
+
/* Add this declaration to the statement-tree. */
- if (building_stmt_tree ()
+ if (building_stmt_tree ()
&& at_function_scope_p ()
&& TREE_CODE (decl) != RESULT_DECL)
add_decl_stmt (decl);
orig_declarator);
else
{
+ 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>()'. */
/* A friend declaration of the form friend void f<>(). Record
the information in the TEMPLATE_ID_EXPR. */
SET_DECL_IMPLICIT_INSTANTIATION (decl);
- DECL_TEMPLATE_INFO (decl)
- = tree_cons (TREE_OPERAND (orig_declarator, 0),
- TREE_OPERAND (orig_declarator, 1),
- NULL_TREE);
+
+ if (TREE_CODE (fns) == COMPONENT_REF)
+ {
+ /* Due to bison parser ickiness, we will have already looked
+ 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);
+ }
+ my_friendly_assert (TREE_CODE (fns) == IDENTIFIER_NODE
+ || TREE_CODE (fns) == LOOKUP_EXPR
+ || TREE_CODE (fns) == OVERLOAD, 20001120);
+ DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE);
if (has_default_arg)
{
return decl;
if (virtualp)
- {
- DECL_VIRTUAL_P (decl) = 1;
- if (DECL_VINDEX (decl) == NULL_TREE)
- DECL_VINDEX (decl) = error_mark_node;
- IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
- }
+ DECL_VIRTUAL_P (decl) = 1;
return decl;
}
set_decl_namespace (decl, context, 0);
context = DECL_CONTEXT (decl);
- if (declarator && context && current_lang_name != lang_name_c)
+ 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)
+ DECL_ASSEMBLER_NAME (decl)
= build_static_name (context, declarator);
}
}
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. */
case sfk_constructor:
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);
ctor_return_type = TREE_TYPE (dname);
sfk = sfk_conversion;
if (IDENTIFIER_GLOBAL_VALUE (dname)
- && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (dname))
+ && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (dname))
== TYPE_DECL))
name = IDENTIFIER_POINTER (dname);
else
if (IDENTIFIER_TYPENAME_P (tmp))
{
if (IDENTIFIER_GLOBAL_VALUE (tmp)
- && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (tmp))
+ && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (tmp))
== TYPE_DECL))
name = IDENTIFIER_POINTER (tmp);
else
type = create_array_type_for_decl (dname, type, size);
/* VLAs never work as fields. */
- if (decl_context == FIELD && !processing_template_decl
+ if (decl_context == FIELD && !processing_template_decl
&& TREE_CODE (type) == ARRAY_TYPE
&& TYPE_DOMAIN (type) != NULL_TREE
&& !TREE_CONSTANT (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
}
{
RID_BIT_TYPE tmp_bits;
- bcopy ((void*)&specbits, (void*)&tmp_bits, sizeof (RID_BIT_TYPE));
+ memcpy (&tmp_bits, &specbits, sizeof (RID_BIT_TYPE));
RIDBIT_RESET (RID_INLINE, tmp_bits);
RIDBIT_RESET (RID_STATIC, tmp_bits);
if (RIDBIT_ANY_SET (tmp_bits))
/* FIXME: This is where default args should be fully
processed. */
- arg_types = grokparms (inner_parms, funcdecl_p ? funcdef_flag : 0);
+ arg_types = grokparms (inner_parms);
if (declarator && flags == DTOR_FLAG)
{
t = ctype;
while (t != NULL_TREE && CLASS_TYPE_P (t))
{
- /* You're supposed to have one `template <...>'
+ /* You're supposed to have one `template <...>'
for every template class, but you don't need one
for a full specialization. For example:
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
- if (current_class_type == NULL_TREE
- || friendp)
+ if (current_class_type == NULL_TREE || friendp)
type = build_cplus_method_type (ctype, TREE_TYPE (type),
TYPE_ARG_TYPES (type));
else
}
type = build_offset_type (ctype, type);
}
- else if (uses_template_parms (ctype))
- {
- if (TREE_CODE (type) == FUNCTION_TYPE)
- type
- = build_cplus_method_type (ctype, TREE_TYPE (type),
- TYPE_ARG_TYPES (type));
- }
else
- {
- cp_error ("structure `%T' not yet defined", ctype);
- return error_mark_node;
- }
+ {
+ 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)
+ if (flag_new_abi)
DECL_ASSEMBLER_NAME (decl) = mangle_type (type);
else
{
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));
}
/* Until core issue 180 is resolved, allow 'friend typename A::B'.
- But don't allow implicit typenames. */
+ But don't allow implicit typenames except with a class-key. */
if (!current_aggr && (TREE_CODE (type) != TYPENAME_TYPE
|| IMPLICIT_TYPENAME_P (type)))
{
/* Only try to do this stuff if we didn't already give up. */
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;
}
}
type = build_pointer_type (type);
else if (TREE_CODE (type) == OFFSET_TYPE)
type = build_pointer_type (type);
- else if (TREE_CODE (type) == VOID_TYPE && declarator)
- {
- error ("declaration of `%s' as void", name);
- return NULL_TREE;
- }
}
{
{
for (; parms; parms = TREE_CHAIN (parms))
{
- tree type = TREE_TYPE (parms);
-
- /* Try to complete the TYPE. */
- type = complete_type (type);
-
- if (type == error_mark_node)
- continue;
-
- if (!COMPLETE_TYPE_P (type))
- {
- if (DECL_NAME (parms))
- error ("parameter `%s' has incomplete type",
- IDENTIFIER_POINTER (DECL_NAME (parms)));
- else
- error ("parameter has incomplete type");
- TREE_TYPE (parms) = error_mark_node;
- }
- else
+ if (VOID_TYPE_P (TREE_TYPE (parms)))
+ /* grokparms will have already issued an error */
+ TREE_TYPE (parms) = error_mark_node;
+ else if (complete_type_or_else (TREE_TYPE (parms), parms))
layout_decl (parms, 0);
+ else
+ TREE_TYPE (parms) = error_mark_node;
}
}
The keyword `this' shall not be used in a default argument of a
member function. */
- var = walk_tree_without_duplicates (&arg, local_variable_p_walkfn,
+ var = walk_tree_without_duplicates (&arg, local_variable_p_walkfn,
NULL);
if (var)
{
Given the list of things declared inside the parens,
return a list of types.
- The list we receive can have three kinds of elements:
- an IDENTIFIER_NODE for names given without types,
- a TREE_LIST node for arguments given as typespecs or names with typespecs,
- or void_type_node, to mark the end of an argument list
- when additional arguments are not permitted (... was not used).
-
- FUNCDEF_FLAG is nonzero for a function definition, 0 for
- a mere declaration. A nonempty identifier-list gets an error message
- when FUNCDEF_FLAG is zero.
- If FUNCDEF_FLAG is 1, then parameter types must be complete.
- If FUNCDEF_FLAG is -1, then parameter types may be incomplete.
-
- If all elements of the input list contain types,
- we return a list of the types.
- If all elements contain no type (except perhaps a void_type_node
- at the end), we return a null list.
- If some have types and some do not, it is an error, and we
- return a null list.
-
- Also set last_function_parms to either
- a list of names (IDENTIFIER_NODEs) or a chain of PARM_DECLs.
- A list of names is converted to a chain of PARM_DECLs
- by store_parm_decls so that ultimately it is always a chain of decls.
-
- Note that in C++, parameters can take default values. These default
- values are in the TREE_PURPOSE field of the TREE_LIST. It is
- an error to specify default values which are followed by parameters
- that have no default values, or an ELLIPSES. For simplicities sake,
- only parameters which are specified with their types can take on
- default values. */
+ We determine whether ellipsis parms are used by PARMLIST_ELLIPSIS_P
+ flag. If unset, we append void_list_node. A parmlist declared
+ as `(void)' is accepted as the empty parmlist.
+
+ Also set last_function_parms to the chain of PARM_DECLs. */
static tree
-grokparms (first_parm, funcdef_flag)
+grokparms (first_parm)
tree first_parm;
- int funcdef_flag;
{
tree result = NULL_TREE;
tree decls = NULL_TREE;
+ int ellipsis = !first_parm || PARMLIST_ELLIPSIS_P (first_parm);
+ tree parm, chain;
+ int any_error = 0;
- if (first_parm != NULL_TREE
- && TREE_CODE (TREE_VALUE (first_parm)) == IDENTIFIER_NODE)
- {
- if (! funcdef_flag)
- pedwarn ("parameter names (without types) in function declaration");
- last_function_parms = first_parm;
- return NULL_TREE;
- }
- else if (first_parm != NULL_TREE
- && TREE_CODE (TREE_VALUE (first_parm)) != TREE_LIST
- && TREE_CODE (TREE_VALUE (first_parm)) != VOID_TYPE)
- my_friendly_abort (145);
- else
- {
- /* Types were specified. This is a list of declarators
- each represented as a TREE_LIST node. */
- register tree parm, chain;
- int any_init = 0, any_error = 0;
+ my_friendly_assert (!first_parm || TREE_PARMLIST (first_parm), 20001115);
- if (first_parm != NULL_TREE)
- {
- tree last_result = NULL_TREE;
- tree last_decl = NULL_TREE;
-
- for (parm = first_parm; parm != NULL_TREE; parm = chain)
- {
- tree type = NULL_TREE, list_node = parm;
- register tree decl = TREE_VALUE (parm);
- tree init = TREE_PURPOSE (parm);
-
- chain = TREE_CHAIN (parm);
- /* @@ weak defense against parse errors. */
- if (TREE_CODE (decl) != VOID_TYPE
- && TREE_CODE (decl) != TREE_LIST)
- {
- /* Give various messages as the need arises. */
- if (TREE_CODE (decl) == STRING_CST)
- cp_error ("invalid string constant `%E'", decl);
- else if (TREE_CODE (decl) == INTEGER_CST)
- error ("invalid integer constant in parameter list, did you forget to give parameter name?");
- continue;
- }
-
- if (TREE_CODE (decl) != VOID_TYPE)
- {
- decl = grokdeclarator (TREE_VALUE (decl),
- TREE_PURPOSE (decl),
- PARM, init != NULL_TREE,
- NULL_TREE);
- if (! decl || TREE_TYPE (decl) == error_mark_node)
- continue;
-
- /* Top-level qualifiers on the parameters are
- ignored for function types. */
- type = TYPE_MAIN_VARIANT (TREE_TYPE (decl));
-
- if (TREE_CODE (type) == VOID_TYPE)
- decl = void_type_node;
- else if (TREE_CODE (type) == METHOD_TYPE)
- {
- if (DECL_NAME (decl))
- /* Cannot use the decl here because
- we don't have DECL_CONTEXT set up yet. */
- cp_error ("parameter `%D' invalidly declared method type",
- DECL_NAME (decl));
- else
- error ("parameter invalidly declared method type");
- type = build_pointer_type (type);
- TREE_TYPE (decl) = type;
- }
- else if (TREE_CODE (type) == OFFSET_TYPE)
- {
- if (DECL_NAME (decl))
- cp_error ("parameter `%D' invalidly declared offset type",
- DECL_NAME (decl));
- else
- error ("parameter invalidly declared offset type");
- type = build_pointer_type (type);
- TREE_TYPE (decl) = type;
- }
- else if (abstract_virtuals_error (decl, type))
- any_error = 1; /* Seems like a good idea. */
- else if (POINTER_TYPE_P (type))
- {
- tree t = type;
- while (POINTER_TYPE_P (t)
- || (TREE_CODE (t) == ARRAY_TYPE
- && TYPE_DOMAIN (t) != NULL_TREE))
- t = TREE_TYPE (t);
- if (TREE_CODE (t) == ARRAY_TYPE)
- cp_error ("parameter type `%T' includes %s to array of unknown bound",
- type,
- TYPE_PTR_P (type) ? "pointer" : "reference");
- }
- }
+ for (parm = first_parm; parm != NULL_TREE; parm = chain)
+ {
+ tree type = NULL_TREE;
+ register tree decl = TREE_VALUE (parm);
+ tree init = TREE_PURPOSE (parm);
+
+ chain = TREE_CHAIN (parm);
+ /* @@ weak defense against parse errors. */
+ if (TREE_CODE (decl) != VOID_TYPE
+ && TREE_CODE (decl) != TREE_LIST)
+ {
+ /* Give various messages as the need arises. */
+ if (TREE_CODE (decl) == STRING_CST)
+ cp_error ("invalid string constant `%E'", decl);
+ else if (TREE_CODE (decl) == INTEGER_CST)
+ error ("invalid integer constant in parameter list, did you forget to give parameter name?");
+ continue;
+ }
- if (TREE_CODE (decl) == VOID_TYPE)
- {
- if (result == NULL_TREE)
- {
- result = void_list_node;
- last_result = result;
- }
- else
- {
- TREE_CHAIN (last_result) = void_list_node;
- last_result = void_list_node;
- }
- if (chain
- && (chain != void_list_node || TREE_CHAIN (chain)))
- error ("`void' in parameter list must be entire list");
- break;
- }
+ if (parm == void_list_node)
+ break;
- /* Since there is a prototype, args are passed in their own types. */
- DECL_ARG_TYPE (decl) = TREE_TYPE (decl);
- if (PROMOTE_PROTOTYPES
- && (TREE_CODE (type) == INTEGER_TYPE
- || TREE_CODE (type) == ENUMERAL_TYPE)
- && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
- DECL_ARG_TYPE (decl) = integer_type_node;
- if (!any_error && init)
- {
- any_init++;
- init = check_default_argument (decl, init);
- }
- else
- init = NULL_TREE;
+ decl = grokdeclarator (TREE_VALUE (decl), TREE_PURPOSE (decl),
+ PARM, init != NULL_TREE, NULL_TREE);
+ if (! decl || TREE_TYPE (decl) == error_mark_node)
+ continue;
+
+ type = TREE_TYPE (decl);
+ if (VOID_TYPE_P (type))
+ {
+ if (same_type_p (type, void_type_node)
+ && !DECL_NAME (decl) && !result && !chain && !ellipsis)
+ /* this is a parmlist of `(void)', which is ok. */
+ break;
+ incomplete_type_error (decl, type);
+ /* It's not a good idea to actually create parameters of
+ type `void'; other parts of the compiler assume that a
+ void type terminates the parameter list. */
+ type = error_mark_node;
+ TREE_TYPE (decl) = error_mark_node;
+ }
- if (decls == NULL_TREE)
- {
- decls = decl;
- last_decl = decls;
- }
- else
- {
- TREE_CHAIN (last_decl) = decl;
- last_decl = decl;
- }
- list_node = tree_cons (init, type, NULL_TREE);
- if (result == NULL_TREE)
- {
- result = list_node;
- last_result = result;
- }
- else
- {
- TREE_CHAIN (last_result) = list_node;
- last_result = list_node;
- }
+ if (type != error_mark_node)
+ {
+ /* Top-level qualifiers on the parameters are
+ ignored for function types. */
+ type = TYPE_MAIN_VARIANT (type);
+ if (TREE_CODE (type) == METHOD_TYPE)
+ {
+ cp_error ("parameter `%D' invalidly declared method type", decl);
+ type = build_pointer_type (type);
+ TREE_TYPE (decl) = type;
+ }
+ else if (TREE_CODE (type) == OFFSET_TYPE)
+ {
+ cp_error ("parameter `%D' invalidly declared offset type", decl);
+ type = build_pointer_type (type);
+ TREE_TYPE (decl) = type;
}
- if (last_result)
- TREE_CHAIN (last_result) = NULL_TREE;
- /* If there are no parameters, and the function does not end
- with `...', then last_decl will be NULL_TREE. */
- if (last_decl != NULL_TREE)
- TREE_CHAIN (last_decl) = NULL_TREE;
+ else if (abstract_virtuals_error (decl, type))
+ any_error = 1; /* Seems like a good idea. */
+ else if (POINTER_TYPE_P (type))
+ {
+ /* [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);
+ 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_ARG_TYPE (decl) = TREE_TYPE (decl);
+ if (PROMOTE_PROTOTYPES
+ && (TREE_CODE (type) == INTEGER_TYPE
+ || TREE_CODE (type) == ENUMERAL_TYPE)
+ && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+ DECL_ARG_TYPE (decl) = integer_type_node;
+ if (!any_error && init)
+ init = check_default_argument (decl, init);
+ else
+ init = NULL_TREE;
}
- }
+ TREE_CHAIN (decl) = decls;
+ decls = decl;
+ result = tree_cons (init, type, result);
+ }
+ decls = nreverse (decls);
+ result = nreverse (result);
+ if (!ellipsis)
+ result = chainon (result, void_list_node);
last_function_parms = decls;
return result;
other parameters have default arguments. */
if (TREE_CODE (parmtype) == REFERENCE_TYPE
&& TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == ctype
- && (TREE_CHAIN (parmtypes) == NULL_TREE
- || TREE_CHAIN (parmtypes) == void_list_node
- || TREE_PURPOSE (TREE_CHAIN (parmtypes)))
+ && sufficient_parms_p (TREE_CHAIN (parmtypes))
&& !(DECL_TEMPLATE_INSTANTIATION (decl)
&& is_member_template (DECL_TI_TEMPLATE (decl))))
{
existence. Theoretically, they should never even be
instantiated, but that's hard to forestall. */
else if (TYPE_MAIN_VARIANT (parmtype) == ctype
- && (TREE_CHAIN (parmtypes) == NULL_TREE
- || TREE_CHAIN (parmtypes) == void_list_node
- || TREE_PURPOSE (TREE_CHAIN (parmtypes)))
+ && sufficient_parms_p (TREE_CHAIN (parmtypes))
&& !(DECL_TEMPLATE_INSTANTIATION (decl)
&& is_member_template (DECL_TI_TEMPLATE (decl))))
{
case CALL_EXPR:
TYPE_OVERLOADS_CALL_EXPR (current_class_type) = 1;
break;
-
+
case ARRAY_REF:
TYPE_OVERLOADS_ARRAY_REF (current_class_type) = 1;
break;
case MEMBER_REF:
TYPE_OVERLOADS_ARROW (current_class_type) = 1;
break;
-
+
case NEW_EXPR:
TYPE_HAS_NEW_OPERATOR (current_class_type) = 1;
break;
-
+
case DELETE_EXPR:
TYPE_GETS_DELETE (current_class_type) |= 1;
break;
-
+
case VEC_NEW_EXPR:
TYPE_HAS_ARRAY_NEW_OPERATOR (current_class_type) = 1;
break;
-
+
case VEC_DELETE_EXPR:
TYPE_GETS_DELETE (current_class_type) |= 2;
break;
if (methodp)
revert_static_member_fn (decl);
- /* Take care of function decl if we had syntax errors. */
- if (argtypes == NULL_TREE)
- TREE_TYPE (decl)
- = build_function_type (ptr_type_node,
- hash_tree_chain (integer_type_node,
- void_list_node));
- else
- TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
+ TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
}
else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR)
{
if (methodp)
revert_static_member_fn (decl);
- if (argtypes == NULL_TREE)
- TREE_TYPE (decl)
- = build_function_type (void_type_node,
- hash_tree_chain (ptr_type_node,
- void_list_node));
- else
- TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
+ TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
}
else
{
{
int ref = (TREE_CODE (t) == REFERENCE_TYPE);
const char *what = 0;
-
+
if (ref)
t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
}
}
- if (DECL_ASSIGNMENT_OPERATOR_P (decl)
+ if (DECL_ASSIGNMENT_OPERATOR_P (decl)
&& operator_code == NOP_EXPR)
{
tree parmtype;
if (CLASS_TYPE_P (basetype))
{
- TYPE_HAS_NEW_OPERATOR (ref)
+ TYPE_HAS_NEW_OPERATOR (ref)
|= TYPE_HAS_NEW_OPERATOR (basetype);
- TYPE_HAS_ARRAY_NEW_OPERATOR (ref)
+ 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. */
/* Initialize RTL machinery. We cannot do this until
CURRENT_FUNCTION_DECL and DECL_RESULT are set up. We do this
even when processing a template; this is how we get
- CFUN set up, and our per-function variables initialized. */
+ CFUN set up, and our per-function variables initialized.
+ FIXME factor out the non-RTL stuff. */
bl = current_binding_level;
init_function_start (decl1, input_filename, lineno);
current_binding_level = bl;
/* If we are (erroneously) defining a function that we have already
defined before, wipe out what we knew before. */
- if (!DECL_PENDING_INLINE_P (decl1)
+ if (!DECL_PENDING_INLINE_P (decl1)
&& DECL_SAVED_FUNCTION_DATA (decl1))
{
free (DECL_SAVED_FUNCTION_DATA (decl1));
else
cp_error ("parameter `%D' declared void", parm);
- cleanup = (processing_template_decl
+ cleanup = (processing_template_decl
? NULL_TREE
: maybe_build_cleanup (parm));
/* Make a copy. */
f = ((struct cp_language_function *)
xmalloc (sizeof (struct cp_language_function)));
- bcopy ((char *) cp_function_chain, (char *) f,
- sizeof (struct cp_language_function));
+ memcpy (f, cp_function_chain, sizeof (struct cp_language_function));
DECL_SAVED_FUNCTION_DATA (decl) = f;
/* Clear out the bits we don't need. */
if (CP_TYPE_QUALS (TREE_TYPE (TREE_VALUE (args)))
!= TYPE_UNQUALIFIED)
cp_error ("static member function `%#D' declared with type qualifiers",
- *decl);
+ decl);
args = TREE_CHAIN (args);
tmp = build_function_type (TREE_TYPE (function), args);
{
ggc_mark (ld);
c_mark_lang_decl (&ld->decl_flags.base);
- if (!DECL_GLOBAL_CTOR_P (t)
+ if (!DECL_GLOBAL_CTOR_P (t)
&& !DECL_GLOBAL_DTOR_P (t)
&& !DECL_THUNK_P (t))
ggc_mark_tree (ld->decl_flags.u2.access);
ggc_mark_tree ((tree) lt);
}
}
+
+/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
+ the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++. */
+
+tree
+identifier_global_value (t)
+ tree t;
+{
+ return IDENTIFIER_GLOBAL_VALUE (t);
+}