aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMike Stump <mrs@gcc.gnu.org>1997-04-02 03:58:33 +0000
committerMike Stump <mrs@gcc.gnu.org>1997-04-02 03:58:33 +0000
commitbd6dd8453c857d8ee420c960503d8eb72de1aa75 (patch)
tree06738d9c5eb08b5bba7232faeef34e816727c0b2 /gcc/cp
parent70e06f23df998477ef7b1b906968aef1f2afc388 (diff)
downloadgcc-bd6dd8453c857d8ee420c960503d8eb72de1aa75.zip
gcc-bd6dd8453c857d8ee420c960503d8eb72de1aa75.tar.gz
gcc-bd6dd8453c857d8ee420c960503d8eb72de1aa75.tar.bz2
90th Cygnus<->FSF quick merge
From-SVN: r13831
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog191
-rw-r--r--gcc/cp/Make-lang.in5
-rw-r--r--gcc/cp/Makefile.in3
-rw-r--r--gcc/cp/call.c49
-rw-r--r--gcc/cp/class.c17
-rw-r--r--gcc/cp/cp-tree.h53
-rw-r--r--gcc/cp/cvt.c4
-rw-r--r--gcc/cp/decl.c95
-rw-r--r--gcc/cp/decl2.c3
-rw-r--r--gcc/cp/friend.c414
-rw-r--r--gcc/cp/init.c582
-rw-r--r--gcc/cp/lex.c48
-rw-r--r--gcc/cp/method.c137
-rw-r--r--gcc/cp/parse.y5
-rw-r--r--gcc/cp/pt.c22
-rw-r--r--gcc/cp/search.c26
-rw-r--r--gcc/cp/sig.c4
-rw-r--r--gcc/cp/tree.c37
-rw-r--r--gcc/cp/typeck.c45
19 files changed, 914 insertions, 826 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 78ca954..d945770 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,194 @@
+Wed Mar 19 14:14:45 1997 Mike Stump <mrs@cygnus.com>
+
+ * parse.y (left_curly): Avoid trying to use any fields of
+ error_mark_node, as there aren't any.
+
+Thu Mar 13 16:33:22 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lex.c (do_identifier): Avoid breaking on overloaded methods
+ as default arguments.
+
+Wed Mar 12 13:55:10 1997 Hans-Peter Nilsson <Hans-Peter.Nilsson@axis.se>
+
+ * call.c (add_template_candidate): Initialize the variable "dummy".
+
+Mon Mar 10 15:13:14 1997 Brendan Kehoe <brendan@canuck.cygnus.com>
+
+ * decl.c (start_decl): Make sure TYPE isn't an error_mark_node
+ before we try to use TYPE_SIZE and TREE_CONSTANT on it.
+
+Fri Mar 7 13:19:36 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * cp-tree.h (comp_ptr_ttypes, more_specialized): Add decl.
+ (debug_binfo): Delete decl, not needed.
+
+ * tree.c (fnaddr_from_vtable_entry, function_arg_chain,
+ promotes_to_aggr_type): Delete fns.
+ * cp-tree.h (FNADDR_FROM_VTABLE_ENTRY,
+ SET_FNADDR_FROM_VTABLE_ENTRY, FUNCTION_ARG_CHAIN,
+ PROMOTES_TO_AGGR_TYPE): Delete alternates to #if 1.
+
+ * decl.c (pending_invalid_xref{,_file,_line}): Delete unused vars.
+
+ * friend.c (is_friend_type): Delete fn.
+ * cp-tree.h (is_friend_type): Delete decl.
+
+ * decl.c (original_result_rtx, double_ftype_double,
+ double_ftype_double_double, int_ftype_int, long_ftype_long,
+ float_ftype_float, ldouble_ftype_ldouble, last_dtor_insn): Make static.
+ * typeck.c (original_result_rtx, warn_synth): Delete extern decls.
+
+ * decl.c (push_overloaded_decl{,_top_level}): Make static, adding
+ fwd decls.
+ * cp-tree.h (push_overloaded_decl{,_top_level}): Delete decls.
+
+ * decl.c (pushdecl_nonclass_level): #if 0, unused.
+ * cp-tree.h (pushdecl_nonclass_level): #if 0 decl.
+
+ * lex.c (reinit_lang_specific): #if 0, unused.
+ * cp-tree.h (reinit_lang_specific): #if 0 decl.
+
+ * decl.c (revert_static_member_fn): Make static, adding fwd decl.
+ * cp-tree.h (revert_static_member_fn): Delete decl.
+
+ * class.c (root_lang_context_p): Delete fn.
+ * cp-tree.h (root_lang_context_p): Delete decl.
+
+ * decl.c (set_current_level_tags_transparency): #if 0, unused.
+ * cp-tree.h (set_current_level_tags_transparency): #if 0 decl.
+
+ * lex.c (set_vardecl_interface_info): Make static.
+ * cp-tree.h (set_vardecl_interface_info): Delete decl.
+
+ * call.c (find_scoped_type): Make static.
+ * cp-tree.h (find_scoped_type): Delete decl.
+
+ * search.c (convert_pointer_to_vbase): Make static.
+ * cp-tree.h (convert_pointer_to_vbase): Delete decl.
+
+ * decl.c (const_ptr_type_node): Likewise.
+ * cp-tree.h (const_ptr_type_node): Delete decl.
+
+ * typeck.c (common_base_type): Make static.
+ * cp-tree.h (common_base_types): Delete erroneous decl.
+
+ * pt.c (classtype_mangled_name): Make static.
+ * cp-tree.h (classtype_mangled_name): Delete decl.
+
+ * lex.c (check_newline): Make static.
+ * cp-tree.h (check_newline): Delete decl.
+
+ * typeck.c (build_x_array_ref): Delete fn, same idea as
+ grok_array_decl.
+ * cp-tree.h (build_x_array_ref): Delete decl.
+
+ * lex.c (copy_decl_lang_specific): Delete fn, same idea as
+ copy_lang_decl.
+ * cp-tree.h (copy_decl_lang_specific): #if 0 decl.
+
+ * class.c (build_vtable_entry): Make static.
+ * cp-tree.h (build_vtable_entry): Delete decl.
+
+ * class.c (build_vbase_pointer): Make static.
+ * cp-tree.h (build_vbase_pointer): Delete decl.
+
+ * sig.c (build_sptr_ref): Add forward decl and make static.
+ * cp-tree.h (build_sptr_ref): Delete decl.
+
+ * call.c (build_new_method_call): Add forward decl and make static.
+ * cp-tree.h (build_new_method_call): Delete decl.
+
+ * call.c (build_object_call): Make static.
+ * class.c (check_for_override, complete_type_p, mark_overriders):
+ Likewise.
+ * decl.c (cp_function_chain): Likewise.
+ * lex.c (set_typedecl_interface_info, reinit_parse_for_block):
+ Likewise.
+ * pt.c (comp_template_args, get_class_bindings, push_tinst_level):
+ Likewise.
+ * tree.c (build_cplus_array_type_1): Likewise.
+ * typeck.c (comp_ptr_ttypes_{const,real,reinterpret}): Likewise.
+ (comp_target_parms): Likewise.
+
+ * init.c (build_builtin_call): Make static.
+ * cp-tree.h (build_builtin_call): Delete decl.
+
+ * typeck.c (binary_op_error): Delete decl.
+ * cp-tree.h (binary_op_error): Likewise.
+
+Thu Mar 6 16:13:52 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * call.c (build_method_call): Compare against error_mark_node
+ directly, rather than the ERROR_MARK tree code.
+ * cvt.c (cp_convert): Likewise.
+ * decl.c (print_binding_level): Likewise.
+ (duplicate_decls): Likewise.
+ (grokdeclarator): Likewise.
+ (grokdeclarator): Likewise.
+ * init.c (expand_aggr_init_1): Likewise.
+ (decl_constant_value): Likewise.
+ * method.c (build_opfncall): Likewise.
+ (hack_identifier): Likewise.
+ * typeck.c (build_modify_expr): Likewise.
+
+ * typeck.c (build_c_cast): Don't decl TYPE as register tree.
+
+Sun Mar 2 02:54:36 1997 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
+
+ * pt.c (unify): Strip NOP_EXPR wrappers before unifying integer values.
+
+ * pt.c (coerce_template_parms): Add new error message.
+
+ * method.c (build_overload_value): Implement name mangling for
+ floating-point template arguments.
+
+ * method.c (build_overload_int, icat, dicat): Fix mangling of template
+ arguments whose absolute value doesn't fit in a signed word.
+
+Mon Mar 3 12:14:54 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * friend.c: New file; put all of the friend stuff in here.
+ * init.c: Instead of here.
+ * Makefile.in (CXX_OBJS): Add friend.o.
+ (friend.o): Add dependencies.
+ * Make-lang.in (CXX_SRCS): Add $(srcdir)/cp/friend.c.
+
+Sun Mar 2 11:04:43 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_scoped_method_call): Complain if the scope isn't a
+ base.
+
+Wed Feb 26 11:31:06 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * parse.y (left_curly): Don't crash on erroneous type.
+
+ * init.c (build_delete): Fix type of ref.
+
+Tue Feb 25 12:41:48 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * search.c (get_vbase_1): Renamed from get_vbase.
+ (get_vbase): Wrapper, now non-static.
+ (convert_pointer_to_vbase): Now static.
+
+ * call.c (build_scoped_method_call): Accept a binfo for BASETYPE.
+ * init.c (build_delete): Pass one.
+ (build_partial_cleanup_for): Use build_scoped_method_call.
+ * decl.c (finish_function): Pass a binfo.
+
+Mon Feb 24 15:00:12 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (build_over_call): Only synthesize non-trivial copy ctors.
+
+ * typeck.c (build_c_cast): Lose other reference to flag.
+
+ * call.c (build_field_call): Don't look for [cd]tor_identifier.
+ * decl2.c (delete_sanity): Remove meaningless use of
+ LOOKUP_HAS_IN_CHARGE.
+ * decl.c (finish_function): Use build_scoped_method_call instead
+ of build_delete for running vbase dtors.
+ * init.c (build_delete): Call overload resolution code instead of
+ duplicating it badly.
+
Thu Feb 20 15:12:15 1997 Jason Merrill <jason@yorick.cygnus.com>
* call.c (build_over_call): Call mark_used before trying to elide
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 00551a3..2dcfe43 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -118,8 +118,9 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.c \
$(srcdir)/cp/ptree.c $(srcdir)/cp/tree.c $(srcdir)/cp/cvt.c \
$(srcdir)/cp/errfn.c $(srcdir)/cp/rtti.c $(srcdir)/cp/method.c \
$(srcdir)/cp/search.c $(srcdir)/cp/typeck.c $(srcdir)/cp/decl.c \
- $(srcdir)/cp/error.c $(srcdir)/cp/init.c $(srcdir)/cp/parse.y \
- $(srcdir)/cp/sig.c $(srcdir)/cp/typeck2.c $(srcdir)/cp/repo.c
+ $(srcdir)/cp/error.c $(srcdir)/cp/friend.c $(srcdir)/cp/init.c \
+ $(srcdir)/cp/parse.y $(srcdir)/cp/sig.c $(srcdir)/cp/typeck2.c \
+ $(srcdir)/cp/repo.c
cc1plus: $(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o c-pragma.o
cd cp; $(MAKE) $(FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) ../cc1plus
diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in
index dc86dc3..03ba91a 100644
--- a/gcc/cp/Makefile.in
+++ b/gcc/cp/Makefile.in
@@ -160,7 +160,7 @@ INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config
CXX_OBJS = call.o decl.o errfn.o expr.o pt.o sig.o typeck2.o \
class.o decl2.o error.o lex.o parse.o ptree.o rtti.o spew.o typeck.o cvt.o \
- except.o init.o method.o search.o tree.o xref.o repo.o
+ except.o friend.o init.o method.o search.o tree.o xref.o repo.o
# Language-independent object files.
OBJS = `cat ../stamp-objlist` ../c-common.o ../c-pragma.o
@@ -231,6 +231,7 @@ typeck2.o : typeck2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h
typeck.o : typeck.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H)
class.o : class.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h
call.o : call.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h class.h
+friend.o : friend.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H)
init.o : init.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H)
method.o : method.c $(CONFIG_H) $(CXX_TREE_H) class.h
cvt.o : cvt.c $(CONFIG_H) $(CXX_TREE_H) class.h
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 75e7b56..df4ced9 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -44,6 +44,7 @@ extern tree ctor_label, dtor_label;
between an expected and the given type. */
static struct harshness_code convert_harshness PROTO((register tree, register tree, tree));
+static tree build_new_method_call PROTO((tree, tree, tree, tree, int));
#define EVIL_RETURN(ARG) ((ARG).code = EVIL_CODE, (ARG))
#define STD_RETURN(ARG) ((ARG).code = STD_CODE, (ARG))
@@ -1175,6 +1176,9 @@ build_field_call (basetype_path, instance_ptr, name, parms)
{
tree field, instance;
+ if (name == ctor_identifier || name == dtor_identifier)
+ return NULL_TREE;
+
if (instance_ptr == current_class_ptr)
{
/* Check to see if we really have a reference to an instance variable
@@ -1266,7 +1270,7 @@ build_field_call (basetype_path, instance_ptr, name, parms)
return NULL_TREE;
}
-tree
+static tree
find_scoped_type (type, inner_name, inner_types)
tree type, inner_name, inner_types;
{
@@ -1424,6 +1428,14 @@ build_scoped_method_call (exp, basetype, name, parms)
if (TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
+ if (TREE_CODE (basetype) == TREE_VEC)
+ {
+ binfo = basetype;
+ basetype = BINFO_TYPE (binfo);
+ }
+ else
+ binfo = NULL_TREE;
+
/* Destructors can be "called" for simple types; see 5.2.4 and 12.4 Note
that explicit ~int is caught in the parser; this deals with typedefs
and template parms. */
@@ -1449,13 +1461,21 @@ build_scoped_method_call (exp, basetype, name, parms)
return error_mark_node;
}
- if ((binfo = binfo_or_else (basetype, type)))
+ if (! binfo)
{
+ binfo = get_binfo (basetype, type, 1);
if (binfo == error_mark_node)
return error_mark_node;
+ if (! binfo)
+ error_not_base_type (basetype, type);
+ }
+
+ if (binfo)
+ {
if (TREE_CODE (exp) == INDIRECT_REF)
- decl = build_indirect_ref (convert_pointer_to (binfo,
- build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR);
+ decl = build_indirect_ref
+ (convert_pointer_to_real
+ (binfo, build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR);
else
decl = build_scoped_ref (exp, basetype);
@@ -1820,7 +1840,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (! IS_AGGR_TYPE (basetype))
{
non_aggr_error:
- if ((flags & LOOKUP_COMPLAIN) && TREE_CODE (basetype) != ERROR_MARK)
+ if ((flags & LOOKUP_COMPLAIN) && basetype != error_mark_node)
cp_error ("request for member `%D' in `%E', which is of non-aggregate type `%T'",
name, instance, basetype);
@@ -2568,7 +2588,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
&& TREE_OPERAND (TREE_OPERAND (instance_ptr, 0), 0) == instance)
;
/* The call to `convert_pointer_to' may return error_mark_node. */
- else if (TREE_CODE (instance_ptr) == ERROR_MARK)
+ else if (instance_ptr == error_mark_node)
return instance_ptr;
else if (instance == NULL_TREE
|| TREE_CODE (instance) != INDIRECT_REF
@@ -4074,7 +4094,7 @@ add_template_candidate (candidates, tmpl, arglist, flags)
int ntparms = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (tmpl));
tree *targs = (tree *) alloca (sizeof (tree) * ntparms);
struct z_candidate *cand;
- int i, dummy;
+ int i, dummy = 0;
tree fn;
i = type_unification (DECL_TEMPLATE_PARMS (tmpl), targs,
@@ -4356,7 +4376,7 @@ build_new_function_call (fn, args, obj)
return build_function_call (fn, args);
}
-tree
+static tree
build_object_call (obj, args)
tree obj, args;
{
@@ -5092,10 +5112,6 @@ build_over_call (fn, convs, args, flags)
converted_args = nreverse (converted_args);
- /* [class.copy]: the copy constructor is implicitly defined even if the
- implementation elided its use. */
- mark_used (fn);
-
/* Avoid actually calling copy constructors and copy assignment operators,
if possible. */
if (DECL_CONSTRUCTOR_P (fn)
@@ -5119,6 +5135,11 @@ build_over_call (fn, convs, args, flags)
else
arg = build_indirect_ref (arg, 0);
+ /* [class.copy]: the copy constructor is implicitly defined even if
+ the implementation elided its use. */
+ if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn)))
+ mark_used (fn);
+
/* If we're creating a temp and we already have one, don't create a
new one. If we're not creating a temp but we get one, use
INIT_EXPR to collapse the temp into our target. Otherwise, if the
@@ -5159,6 +5180,8 @@ build_over_call (fn, convs, args, flags)
return val;
}
+ mark_used (fn);
+
if (DECL_CONTEXT (fn) && IS_SIGNATURE (DECL_CONTEXT (fn)))
return build_signature_method_call (fn, converted_args);
else if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0)
@@ -5186,7 +5209,7 @@ build_over_call (fn, convs, args, flags)
return convert_from_reference (require_complete_type (fn));
}
-tree
+static tree
build_new_method_call (instance, name, args, basetype_path, flags)
tree instance, name, args, basetype_path;
int flags;
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index dc179d0..5ada32b 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -121,7 +121,7 @@ int n_inner_fields_searched = 0;
/* Virtual baseclass things. */
-tree
+static tree
build_vbase_pointer (exp, type)
tree exp, type;
{
@@ -135,7 +135,7 @@ build_vbase_pointer (exp, type)
/* Is the type of the EXPR, the complete type of the object?
If we are going to be wrong, we must be conservative, and return 0. */
-int
+static int
complete_type_p (expr)
tree expr;
{
@@ -372,11 +372,10 @@ static tree pending_hard_virtuals;
Note that the index (DELTA2) in the virtual function table
is always 0. */
-tree
+static tree
build_vtable_entry (delta, pfn)
tree delta, pfn;
{
-
if (flag_vtable_thunks)
{
HOST_WIDE_INT idelta = TREE_INT_CST_LOW (delta);
@@ -2755,7 +2754,7 @@ get_basefndecls (fndecl, t)
Since we start out with all functions already marked with a hider,
no need to mark functions that are just hidden. */
-void
+static void
mark_overriders (fndecl, base_fndecls)
tree fndecl, base_fndecls;
{
@@ -2772,7 +2771,7 @@ mark_overriders (fndecl, base_fndecls)
a method declared virtual in the base class, then
mark this field as being virtual as well. */
-void
+static void
check_for_override (decl, ctype)
tree decl, ctype;
{
@@ -4821,12 +4820,6 @@ pop_lang_context ()
else if (current_lang_name == lang_name_c)
strict_prototype = strict_prototypes_lang_c;
}
-
-int
-root_lang_context_p ()
-{
- return current_lang_stack == current_lang_base;
-}
/* Type instantiation routines. */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9bd73ab..31cc776 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -325,14 +325,12 @@ enum languages { lang_c, lang_cplusplus };
/* In a *_TYPE, nonzero means a built-in type. */
#define TYPE_BUILT_IN(NODE) TYPE_LANG_FLAG_6(NODE)
-/* Macros which might want to be replaced by function calls. */
-
#define DELTA_FROM_VTABLE_ENTRY(ENTRY) \
(!flag_vtable_thunks ? \
TREE_VALUE (CONSTRUCTOR_ELTS (ENTRY)) \
: TREE_CODE (TREE_OPERAND ((ENTRY), 0)) != THUNK_DECL ? integer_zero_node \
: build_int_2 (THUNK_DELTA (TREE_OPERAND ((ENTRY), 0)), 0))
-#if 1
+
/* Virtual function addresses can be gotten from a virtual function
table entry using this macro. */
#define FNADDR_FROM_VTABLE_ENTRY(ENTRY) \
@@ -348,14 +346,6 @@ enum languages { lang_c, lang_cplusplus };
&& IS_AGGR_TYPE (TREE_TYPE (NODE))) \
|| IS_AGGR_TYPE (NODE))
-#else
-#define FNADDR_FROM_VTABLE_ENTRY(ENTRY) (fnaddr_from_vtable_entry (ENTRY))
-#define SET_FNADDR_FROM_VTABLE_ENTRY(ENTRY,VALUE) \
- (set_fnaddr_from_vtable_entry (ENTRY, VALUE))
-/* #define TYPE_NAME_STRING(NODE) (type_name_string (NODE)) */
-#define FUNCTION_ARG_CHAIN(NODE) (function_arg_chain (NODE))
-#define PROMOTES_TO_AGGR_TYPE(NODE,CODE) (promotes_to_aggr_type (NODE, CODE))
-#endif
/* Nonzero iff TYPE is uniquely derived from PARENT. Under MI, PARENT can
be an ambiguous base class of TYPE, and this macro will be false. */
#define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) >= 0)
@@ -1499,7 +1489,7 @@ extern tree vt_off_identifier;
/* A node that is a list (length 1) of error_mark_nodes. */
extern tree error_mark_list;
-extern tree ptr_type_node, const_ptr_type_node;
+extern tree ptr_type_node;
extern tree class_type_node, record_type_node, union_type_node, enum_type_node;
extern tree unknown_type_node;
extern tree opaque_type_node, signature_type_node;
@@ -1927,7 +1917,6 @@ extern int get_arglist_len_in_bytes PROTO((tree));
extern int rank_for_overload PROTO((struct candidate *, struct candidate *));
extern void compute_conversion_costs PROTO((tree, tree, struct candidate *, int));
extern tree build_vfield_ref PROTO((tree, tree));
-extern tree find_scoped_type PROTO((tree, tree, tree));
extern tree resolve_scope_to_name PROTO((tree, tree));
extern tree build_scoped_method_call PROTO((tree, tree, tree, tree));
extern tree build_addr_func PROTO((tree));
@@ -1939,16 +1928,12 @@ extern int null_ptr_cst_p PROTO((tree));
extern tree type_decays_to PROTO((tree));
extern tree build_user_type_conversion PROTO((tree, tree, int));
extern tree build_new_function_call PROTO((tree, tree, tree));
-extern tree build_object_call PROTO((tree, tree));
extern tree build_new_op PROTO((enum tree_code, int, tree, tree, tree));
-extern tree build_new_method_call PROTO((tree, tree, tree, tree, int));
extern int can_convert PROTO((tree, tree));
extern int can_convert_arg PROTO((tree, tree, tree));
/* in class.c */
-extern tree build_vbase_pointer PROTO((tree, tree));
extern tree build_vbase_path PROTO((enum tree_code, tree, tree, tree, int));
-extern tree build_vtable_entry PROTO((tree, tree));
extern tree build_vtbl_ref PROTO((tree, tree));
extern tree build_vfn_ref PROTO((tree *, tree, tree));
extern void add_method PROTO((tree, tree *, tree));
@@ -1965,7 +1950,6 @@ extern void push_nested_class PROTO((tree, int));
extern void pop_nested_class PROTO((int));
extern void push_lang_context PROTO((tree));
extern void pop_lang_context PROTO((void));
-extern int root_lang_context_p PROTO((void));
extern tree instantiate_type PROTO((tree, tree, int));
extern void print_class_statistics PROTO((void));
extern void maybe_push_cache_obstack PROTO((void));
@@ -2023,12 +2007,12 @@ extern int decls_match PROTO((tree, tree));
extern int duplicate_decls PROTO((tree, tree));
extern tree pushdecl PROTO((tree));
extern tree pushdecl_top_level PROTO((tree));
-extern void push_overloaded_decl_top_level PROTO((tree, int));
extern tree pushdecl_class_level PROTO((tree));
+#if 0
extern void pushdecl_nonclass_level PROTO((tree));
+#endif
extern void push_class_level_binding PROTO((tree, tree));
extern int overloaded_globals_p PROTO((tree));
-extern tree push_overloaded_decl PROTO((tree, int));
extern tree implicitly_declare PROTO((tree));
extern tree lookup_label PROTO((tree));
extern tree shadow_label PROTO((tree));
@@ -2038,7 +2022,9 @@ extern void pop_switch PROTO((void));
extern void define_case_label PROTO((tree));
extern tree getdecls PROTO((void));
extern tree gettags PROTO((void));
+#if 0
extern void set_current_level_tags_transparency PROTO((int));
+#endif
extern tree lookup_namespace_name PROTO((tree, tree));
extern tree make_typename_type PROTO((tree, tree));
extern tree lookup_name_nonclass PROTO((tree));
@@ -2082,7 +2068,6 @@ extern tree maybe_build_cleanup_and_delete PROTO((tree));
extern tree maybe_build_cleanup PROTO((tree));
extern void cplus_expand_expr_stmt PROTO((tree));
extern void finish_stmt PROTO((void));
-extern void revert_static_member_fn PROTO((tree *, tree *, tree *));
extern int id_in_current_class PROTO((tree));
extern void push_cp_function_context PROTO((tree));
extern void pop_cp_function_context PROTO((tree));
@@ -2184,6 +2169,11 @@ extern void fixup_result_decl PROTO((tree, struct rtx_def *));
extern int extract_init PROTO((tree, tree));
extern void do_case PROTO((tree, tree));
+/* friend.c */
+extern int is_friend PROTO((tree, tree));
+extern void make_friend_class PROTO((tree, tree));
+extern tree do_friend PROTO((tree, tree, tree, tree, enum overload_flags, tree, int));
+
/* in init.c */
extern void init_init_processing PROTO((void));
extern void expand_direct_vtbls_init PROTO((tree, tree, int, int, tree));
@@ -2200,11 +2190,6 @@ extern tree build_member_call PROTO((tree, tree, tree));
extern tree build_offset_ref PROTO((tree, tree));
extern tree resolve_offset_ref PROTO((tree));
extern tree decl_constant_value PROTO((tree));
-extern int is_friend_type PROTO((tree, tree));
-extern int is_friend PROTO((tree, tree));
-extern void make_friend_class PROTO((tree, tree));
-extern tree do_friend PROTO((tree, tree, tree, tree, enum overload_flags, tree, int));
-extern tree build_builtin_call PROTO((tree, tree, tree));
extern tree build_new PROTO((tree, tree, tree, int));
extern tree expand_vec_init PROTO((tree, tree, tree, tree, int));
extern tree build_x_delete PROTO((tree, tree, int, tree));
@@ -2223,13 +2208,14 @@ extern char *operator_name_string PROTO((tree));
extern void lang_init PROTO((void));
extern void lang_finish PROTO((void));
extern void init_filename_times PROTO((void));
+#if 0
extern void reinit_lang_specific PROTO((void));
+#endif
extern void init_lex PROTO((void));
extern void reinit_parse_for_function PROTO((void));
extern int *init_parse PROTO((void));
extern void print_parse_statistics PROTO((void));
extern void extract_interface_info PROTO((void));
-extern int set_vardecl_interface_info PROTO((tree, tree));
extern void do_pending_inlines PROTO((void));
extern void process_next_inline PROTO((tree));
/* skip save_pending_input */
@@ -2237,13 +2223,12 @@ extern void process_next_inline PROTO((tree));
extern void yyungetc PROTO((int, int));
extern void reinit_parse_for_method PROTO((int, tree));
#if 0
-extern void reinit_parse_for_block PROTO((int, struct obstack *, int));
+extern void reinit_parse_for_block PROTO((int, struct obstack *));
#endif
extern tree cons_up_default_function PROTO((tree, tree, int));
extern void check_for_missing_semicolon PROTO((tree));
extern void note_got_semicolon PROTO((tree));
extern void note_list_got_semicolon PROTO((tree));
-extern int check_newline PROTO((void));
extern void do_pending_lang_change PROTO((void));
extern int identifier_type PROTO((tree));
extern void see_typename PROTO((void));
@@ -2256,7 +2241,6 @@ extern tree build_lang_decl PROTO((enum tree_code, tree, tree));
extern tree build_lang_field_decl PROTO((enum tree_code, tree, tree));
extern void copy_lang_decl PROTO((tree));
extern tree make_lang_type PROTO((enum tree_code));
-extern void copy_decl_lang_specific PROTO((tree));
extern void dump_time_statistics PROTO((void));
/* extern void compiler_error PROTO((char *, HOST_WIDE_INT, HOST_WIDE_INT)); */
extern void yyerror PROTO((char *));
@@ -2295,11 +2279,11 @@ extern void overload_template_name PROTO((tree));
extern int type_unification PROTO((tree, tree *, tree, tree, int *, int, int));
struct tinst_level *tinst_for_decl PROTO((void));
extern void mark_decl_instantiated PROTO((tree, int));
+extern int more_specialized PROTO((tree, tree));
extern void mark_class_instantiated PROTO((tree, int));
extern void do_function_instantiation PROTO((tree, tree, tree));
extern void do_type_instantiation PROTO((tree, tree));
extern tree instantiate_decl PROTO((tree));
-extern tree classtype_mangled_name PROTO((tree));
extern tree lookup_nested_type_by_name PROTO((tree, tree));
extern tree do_poplevel PROTO((void));
extern tree *get_bindings PROTO((tree, tree));
@@ -2326,7 +2310,7 @@ extern void synthesize_tinfo_fn PROTO((tree));
/* in search.c */
extern void push_memoized_context PROTO((tree, int));
extern void pop_memoized_context PROTO((int));
-extern tree convert_pointer_to_vbase PROTO((tree, tree));
+extern tree get_vbase PROTO((tree, tree));
extern tree get_binfo PROTO((tree, tree, int));
extern int get_base_distance PROTO((tree, tree, int, tree *));
extern tree compute_access PROTO((tree, tree));
@@ -2365,7 +2349,6 @@ extern tree build_signature_reference_type PROTO((tree, int, int));
extern tree build_signature_pointer_constructor PROTO((tree, tree));
extern tree build_signature_method_call PROTO((tree, tree));
extern tree build_optr_ref PROTO((tree));
-extern tree build_sptr_ref PROTO((tree));
extern void append_signature_fields PROTO((tree));
/* in spew.c */
@@ -2401,7 +2384,6 @@ extern tree get_decl_list PROTO((tree));
extern tree make_binfo PROTO((tree, tree, tree, tree, tree));
extern tree binfo_value PROTO((tree, tree));
extern tree reverse_path PROTO((tree));
-extern void debug_binfo PROTO((tree));
extern int decl_list_length PROTO((tree));
extern int count_functions PROTO((tree));
extern int is_overloaded_fn PROTO((tree));
@@ -2438,7 +2420,6 @@ extern tree common_type PROTO((tree, tree));
extern int compexcepttypes PROTO((tree, tree));
extern int comptypes PROTO((tree, tree, int));
extern int comp_target_types PROTO((tree, tree, int));
-extern tree common_base_types PROTO((tree, tree));
extern int compparms PROTO((tree, tree, int));
extern int comp_target_types PROTO((tree, tree, int));
extern int self_promoting_args_p PROTO((tree));
@@ -2458,7 +2439,6 @@ extern tree build_component_ref PROTO((tree, tree, tree, int));
extern tree build_x_component_ref PROTO((tree, tree, tree, int));
extern tree build_x_indirect_ref PROTO((tree, char *));
extern tree build_indirect_ref PROTO((tree, char *));
-extern tree build_x_array_ref PROTO((tree, tree));
extern tree build_array_ref PROTO((tree, tree));
extern tree build_x_function_call PROTO((tree, tree, tree));
extern tree get_member_function_from_ptrfunc PROTO((tree *, tree));
@@ -2490,6 +2470,7 @@ extern tree convert_for_initialization PROTO((tree, tree, tree, int, char *, tr
extern void c_expand_asm_operands PROTO((tree, tree, tree, tree, int, char *, int));
extern void c_expand_return PROTO((tree));
extern tree c_expand_start_case PROTO((tree));
+extern int comp_ptr_ttypes PROTO((tree, tree));
extern int ptr_reasonably_similar PROTO((tree, tree));
extern tree build_ptrmemfunc PROTO((tree, tree, int));
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 1c40640..cf96115 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -1153,8 +1153,8 @@ cp_convert (type, expr, convtype, flags)
register tree e = expr;
register enum tree_code code = TREE_CODE (type);
- if (TREE_CODE (e) == ERROR_MARK
- || TREE_CODE (TREE_TYPE (e)) == ERROR_MARK)
+ if (e == error_mark_node
+ || TREE_TYPE (e) == error_mark_node)
return error_mark_node;
if (IS_AGGR_TYPE (type) && (convtype & CONV_FORCE_TEMP))
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 77dce5b..1fd2026 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -126,6 +126,9 @@ static struct stack_level *decl_stack;
static tree grokparms PROTO((tree, int));
static tree lookup_nested_type PROTO((tree, tree));
static char *redeclaration_error_message PROTO((tree, tree));
+static void revert_static_member_fn PROTO((tree *, tree *, tree *));
+static tree push_overloaded_decl PROTO((tree, int));
+static void push_overloaded_decl_top_level PROTO((tree, int));
tree define_function
PROTO((char *, tree, enum built_in_function, void (*)(), char *));
@@ -185,7 +188,8 @@ tree void_zero_node;
/* Nodes for types `void *' and `const void *'. */
-tree ptr_type_node, const_ptr_type_node;
+tree ptr_type_node;
+static tree const_ptr_type_node;
/* Nodes for types `char *' and `const char *'. */
@@ -215,10 +219,10 @@ tree default_function_type;
/* function types `double (double)' and `double (double, double)', etc. */
-tree double_ftype_double, double_ftype_double_double;
-tree int_ftype_int, long_ftype_long;
-tree float_ftype_float;
-tree ldouble_ftype_ldouble;
+static tree double_ftype_double, double_ftype_double_double;
+static tree int_ftype_int, long_ftype_long;
+static tree float_ftype_float;
+static tree ldouble_ftype_ldouble;
/* Function type `int (const void *, const void *, size_t)' */
static tree int_ftype_cptr_cptr_sizet;
@@ -264,7 +268,7 @@ tree dtor_label;
/* In a destructor, the last insn emitted after the start of the
function and the parms. */
-rtx last_dtor_insn;
+static rtx last_dtor_insn;
/* In a constructor, the point at which we are ready to return
the pointer to the initialized object. */
@@ -283,7 +287,7 @@ extern rtx cleanup_label, return_label;
but due to being an addressable named return value, would up
on the stack, this variable holds the named return value's
original location. */
-rtx original_result_rtx;
+static rtx original_result_rtx;
/* Sequence of insns which represents base initialization. */
tree base_init_expr;
@@ -350,14 +354,6 @@ tree null_node;
tree integer_one_node, integer_two_node, integer_three_node;
-/* Nonzero if we have seen an invalid cross reference
- to a struct, union, or enum, but not yet printed the message. */
-
-tree pending_invalid_xref;
-/* File and line to appear in the eventual error message. */
-char *pending_invalid_xref_file;
-int pending_invalid_xref_line;
-
/* While defining an enum type, this is 1 plus the last enumerator
constant value. */
@@ -1507,7 +1503,7 @@ print_binding_level (lvl)
i = len;
}
print_node_brief (stderr, "", t, 0);
- if (TREE_CODE (t) == ERROR_MARK)
+ if (t == error_mark_node)
break;
}
if (i)
@@ -2375,10 +2371,8 @@ duplicate_decls (newdecl, olddecl)
error (earlier) for some bogus type specification, and in that case,
it is rather pointless to harass the user with yet more error message
about the same declaration, so well just pretent the types match here. */
- if ((TREE_TYPE (newdecl)
- && TREE_CODE (TREE_TYPE (newdecl)) == ERROR_MARK)
- || (TREE_TYPE (olddecl)
- && TREE_CODE (TREE_TYPE (olddecl)) == ERROR_MARK))
+ if (TREE_TYPE (newdecl) == error_mark_node
+ || TREE_TYPE (olddecl) == error_mark_node)
types_match = 1;
if (TREE_CODE (olddecl) == FUNCTION_DECL
@@ -2897,7 +2891,7 @@ duplicate_decls (newdecl, olddecl)
}
else
{
- /* Storage leak. */
+ /* Storage leak. */;
}
}
}
@@ -3350,7 +3344,7 @@ pushdecl_top_level (x)
/* Like push_overloaded_decl, only it places X in GLOBAL_BINDING_LEVEL,
if appropriate. */
-void
+static void
push_overloaded_decl_top_level (x, forget)
tree x;
int forget;
@@ -3403,6 +3397,7 @@ pushdecl_class_level (x)
return x;
}
+#if 0
/* This function is used to push the mangled decls for nested types into
the appropriate scope. Previously pushdecl_top_level was used, but that
is incorrect for members of local classes. */
@@ -3423,6 +3418,7 @@ pushdecl_nonclass_level (x)
pushdecl_with_scope (x, b);
}
+#endif
/* Make the declaration(s) of X appear in CLASS scope
under the name NAME. */
@@ -3477,7 +3473,7 @@ overloaded_globals_p (list)
about what language DECL should belong to (C or C++). Otherwise,
it's always DECL (and never something that's not a _DECL). */
-tree
+static tree
push_overloaded_decl (decl, forgettable)
tree decl;
int forgettable;
@@ -4118,12 +4114,14 @@ lookup_tag (form, name, binding_level, thislevel_only)
return NULL_TREE;
}
+#if 0
void
set_current_level_tags_transparency (tags_transparent)
int tags_transparent;
{
current_binding_level->tag_transparent = tags_transparent;
}
+#endif
/* Given a type, find the tag that was defined for it and return the tag name.
Otherwise return 0. However, the value can never be 0
@@ -5744,20 +5742,24 @@ start_decl (declarator, declspecs, initialized)
default:
if (! processing_template_decl)
{
- if (TYPE_SIZE (type) != NULL_TREE
- && ! TREE_CONSTANT (TYPE_SIZE (type)))
+ if (type != error_mark_node)
{
- cp_error
- ("variable-sized object `%D' may not be initialized", decl);
- initialized = 0;
- }
+ if (TYPE_SIZE (type) != NULL_TREE
+ && ! TREE_CONSTANT (TYPE_SIZE (type)))
+ {
+ cp_error
+ ("variable-sized object `%D' may not be initialized",
+ decl);
+ initialized = 0;
+ }
- if (TREE_CODE (type) == ARRAY_TYPE
- && TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
- {
- cp_error
- ("elements of array `%#D' have incomplete type", decl);
- initialized = 0;
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
+ {
+ cp_error
+ ("elements of array `%#D' have incomplete type", decl);
+ initialized = 0;
+ }
}
}
}
@@ -7799,7 +7801,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
typedef_decl = t;
}
}
- else if (TREE_CODE (id) != ERROR_MARK)
+ else if (id != error_mark_node)
/* Can't change CLASS nodes into RECORD nodes here! */
type = id;
@@ -8207,7 +8209,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
array or function or pointer, and DECLARATOR has had its
outermost layer removed. */
- if (TREE_CODE (type) == ERROR_MARK)
+ if (type == error_mark_node)
{
if (TREE_CODE (declarator) == SCOPE_REF)
declarator = TREE_OPERAND (declarator, 1);
@@ -11661,14 +11663,13 @@ finish_function (lineno, call_poplevel, nested)
{
if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (vbases)))
{
- tree ptr = convert_pointer_to_vbase (BINFO_TYPE (vbases), current_class_ptr);
+ tree vb = get_vbase
+ (BINFO_TYPE (vbases),
+ TYPE_BINFO (current_class_type));
expand_expr_stmt
- (build_delete
- (build_pointer_type (BINFO_TYPE (vbases)),
- ptr, integer_zero_node,
- (LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR
- |LOOKUP_HAS_IN_CHARGE|LOOKUP_NORMAL),
- 0));
+ (build_scoped_method_call
+ (current_class_ref, vb, dtor_identifier,
+ build_tree_list (NULL_TREE, integer_zero_node)));
}
vbases = TREE_CHAIN (vbases);
}
@@ -12460,7 +12461,7 @@ finish_stmt ()
(TREE_TYPE (decl)) to ARGTYPES, as doing so will corrupt the types of
other decls. Either pass the addresses of local variables or NULL. */
-void
+static void
revert_static_member_fn (decl, fn, argtypes)
tree *decl, *fn, *argtypes;
{
@@ -12520,9 +12521,7 @@ struct cp_function
struct binding_level *binding_level;
};
-
-
-struct cp_function *cp_function_chain;
+static struct cp_function *cp_function_chain;
extern int temp_name_counter;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index fe4228d..60a27a4 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1245,8 +1245,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
}
return build_delete (type, t, integer_three_node,
- LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE,
- use_global_delete);
+ LOOKUP_NORMAL, use_global_delete);
}
}
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
new file mode 100644
index 0000000..6d7d9d5
--- /dev/null
+++ b/gcc/cp/friend.c
@@ -0,0 +1,414 @@
+/* Help friends in C++.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "tree.h"
+#include "rtl.h"
+#include "cp-tree.h"
+#include "flags.h"
+#include "output.h"
+
+/* Friend data structures:
+
+ Lists of friend functions come from TYPE_DECL nodes. Since all
+ aggregate types are automatically typedef'd, these nodes are guaranteed
+ to exist.
+
+ The TREE_PURPOSE of a friend list is the name of the friend,
+ and its TREE_VALUE is another list.
+
+ For each element of that list, either the TREE_VALUE or the TREE_PURPOSE
+ will be filled in, but not both. The TREE_VALUE of that list is an
+ individual function which is a friend. The TREE_PURPOSE of that list
+ indicates a type in which all functions by that name are friends.
+
+ Lists of friend classes come from _TYPE nodes. Love that consistency
+ thang. */
+
+int
+is_friend (type, supplicant)
+ tree type, supplicant;
+{
+ int declp;
+ register tree list;
+
+ if (supplicant == NULL_TREE || type == NULL_TREE)
+ return 0;
+
+ declp = (TREE_CODE_CLASS (TREE_CODE (supplicant)) == 'd');
+
+ if (declp)
+ /* It's a function decl. */
+ {
+ tree list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type));
+ tree name = DECL_NAME (supplicant);
+ tree ctype;
+
+ if (DECL_FUNCTION_MEMBER_P (supplicant))
+ ctype = DECL_CLASS_CONTEXT (supplicant);
+ else
+ ctype = NULL_TREE;
+
+ for (; list ; list = TREE_CHAIN (list))
+ {
+ if (name == TREE_PURPOSE (list))
+ {
+ tree friends = TREE_VALUE (list);
+ for (; friends ; friends = TREE_CHAIN (friends))
+ {
+ if (ctype == TREE_PURPOSE (friends))
+ return 1;
+ if (comptypes (TREE_TYPE (supplicant),
+ TREE_TYPE (TREE_VALUE (friends)), 1))
+ return 1;
+ }
+ break;
+ }
+ }
+ }
+ else
+ /* It's a type. */
+ {
+ if (type == supplicant)
+ return 1;
+
+ list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
+ for (; list ; list = TREE_CHAIN (list))
+ if (supplicant == TREE_VALUE (list))
+ return 1;
+ }
+
+ {
+ tree context;
+
+ if (! declp)
+ {
+ /* Are we a nested or local class? If so, we aren't friends
+ with the CONTEXT. */
+ if (IS_AGGR_TYPE (supplicant))
+ context = NULL_TREE;
+ else
+ context = DECL_CONTEXT (TYPE_MAIN_DECL (supplicant));
+ }
+ else if (DECL_FUNCTION_MEMBER_P (supplicant))
+ context = DECL_CLASS_CONTEXT (supplicant);
+ else
+ context = NULL_TREE;
+
+ if (context)
+ return is_friend (type, context);
+ }
+
+ return 0;
+}
+
+/* Add a new friend to the friends of the aggregate type TYPE.
+ DECL is the FUNCTION_DECL of the friend being added. */
+
+static void
+add_friend (type, decl)
+ tree type, decl;
+{
+ tree typedecl = TYPE_MAIN_DECL (type);
+ tree list = DECL_FRIENDLIST (typedecl);
+ tree name = DECL_NAME (decl);
+
+ while (list)
+ {
+ if (name == TREE_PURPOSE (list))
+ {
+ tree friends = TREE_VALUE (list);
+ for (; friends ; friends = TREE_CHAIN (friends))
+ {
+ if (decl == TREE_VALUE (friends))
+ {
+ cp_warning ("`%D' is already a friend of class `%T'",
+ decl, type);
+ cp_warning_at ("previous friend declaration of `%D'",
+ TREE_VALUE (friends));
+ return;
+ }
+ }
+ TREE_VALUE (list) = tree_cons (error_mark_node, decl,
+ TREE_VALUE (list));
+ return;
+ }
+ list = TREE_CHAIN (list);
+ }
+ DECL_FRIENDLIST (typedecl)
+ = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
+ DECL_FRIENDLIST (typedecl));
+ if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR])
+ {
+ tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
+ if (parmtypes && TREE_CHAIN (parmtypes))
+ {
+ tree parmtype = TREE_VALUE (TREE_CHAIN (parmtypes));
+ if (TREE_CODE (parmtype) == REFERENCE_TYPE
+ && TREE_TYPE (parmtypes) == TREE_TYPE (typedecl))
+ TYPE_HAS_ASSIGN_REF (TREE_TYPE (typedecl)) = 1;
+ }
+ }
+}
+
+/* Declare that every member function NAME in FRIEND_TYPE
+ (which may be NULL_TREE) is a friend of type TYPE. */
+
+static void
+add_friends (type, name, friend_type)
+ tree type, name, friend_type;
+{
+ tree typedecl = TYPE_MAIN_DECL (type);
+ tree list = DECL_FRIENDLIST (typedecl);
+
+ while (list)
+ {
+ if (name == TREE_PURPOSE (list))
+ {
+ tree friends = TREE_VALUE (list);
+ while (friends && TREE_PURPOSE (friends) != friend_type)
+ friends = TREE_CHAIN (friends);
+ if (friends)
+ if (friend_type)
+ warning ("method `%s::%s' is already a friend of class",
+ TYPE_NAME_STRING (friend_type),
+ IDENTIFIER_POINTER (name));
+ else
+ warning ("function `%s' is already a friend of class `%s'",
+ IDENTIFIER_POINTER (name),
+ IDENTIFIER_POINTER (DECL_NAME (typedecl)));
+ else
+ TREE_VALUE (list) = tree_cons (friend_type, NULL_TREE,
+ TREE_VALUE (list));
+ return;
+ }
+ list = TREE_CHAIN (list);
+ }
+ DECL_FRIENDLIST (typedecl) =
+ tree_cons (name,
+ build_tree_list (friend_type, NULL_TREE),
+ DECL_FRIENDLIST (typedecl));
+ if (! strncmp (IDENTIFIER_POINTER (name),
+ IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]),
+ strlen (IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]))))
+ {
+ TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
+ sorry ("declaring \"friend operator =\" will not find \"operator = (X&)\" if it exists");
+ }
+}
+
+/* Make FRIEND_TYPE a friend class to TYPE. If FRIEND_TYPE has already
+ been defined, we make all of its member functions friends of
+ TYPE. If not, we make it a pending friend, which can later be added
+ when its definition is seen. If a type is defined, then its TYPE_DECL's
+ DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend
+ classes that are not defined. If a type has not yet been defined,
+ then the DECL_WAITING_FRIENDS contains a list of types
+ waiting to make it their friend. Note that these two can both
+ be in use at the same time! */
+
+void
+make_friend_class (type, friend_type)
+ tree type, friend_type;
+{
+ tree classes;
+
+ if (IS_SIGNATURE (type))
+ {
+ error ("`friend' declaration in signature definition");
+ return;
+ }
+ if (IS_SIGNATURE (friend_type))
+ {
+ error ("signature type `%s' declared `friend'",
+ IDENTIFIER_POINTER (TYPE_IDENTIFIER (friend_type)));
+ return;
+ }
+ if (type == friend_type)
+ {
+ pedwarn ("class `%s' is implicitly friends with itself",
+ TYPE_NAME_STRING (type));
+ return;
+ }
+
+ GNU_xref_hier (TYPE_NAME_STRING (type),
+ TYPE_NAME_STRING (friend_type), 0, 0, 1);
+
+ classes = CLASSTYPE_FRIEND_CLASSES (type);
+ while (classes && TREE_VALUE (classes) != friend_type)
+ classes = TREE_CHAIN (classes);
+ if (classes)
+ warning ("class `%s' is already friends with class `%s'",
+ TYPE_NAME_STRING (TREE_VALUE (classes)), TYPE_NAME_STRING (type));
+ else
+ {
+ CLASSTYPE_FRIEND_CLASSES (type)
+ = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
+ }
+}
+
+/* Main friend processor. This is large, and for modularity purposes,
+ has been removed from grokdeclarator. It returns `void_type_node'
+ to indicate that something happened, though a FIELD_DECL is
+ not returned.
+
+ CTYPE is the class this friend belongs to.
+
+ DECLARATOR is the name of the friend.
+
+ DECL is the FUNCTION_DECL that the friend is.
+
+ In case we are parsing a friend which is part of an inline
+ definition, we will need to store PARM_DECL chain that comes
+ with it into the DECL_ARGUMENTS slot of the FUNCTION_DECL.
+
+ FLAGS is just used for `grokclassfn'.
+
+ QUALS say what special qualifies should apply to the object
+ pointed to by `this'. */
+
+tree
+do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
+ tree ctype, declarator, decl, parmdecls;
+ enum overload_flags flags;
+ tree quals;
+ int funcdef_flag;
+{
+ /* Every decl that gets here is a friend of something. */
+ DECL_FRIEND_P (decl) = 1;
+
+ if (ctype)
+ {
+ tree cname = TYPE_NAME (ctype);
+ if (TREE_CODE (cname) == TYPE_DECL)
+ cname = DECL_NAME (cname);
+
+ /* A method friend. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ if (flags == NO_SPECIAL && ctype && declarator == cname)
+ DECL_CONSTRUCTOR_P (decl) = 1;
+
+ /* This will set up DECL_ARGUMENTS for us. */
+ grokclassfn (ctype, cname, decl, flags, quals);
+ if (TYPE_SIZE (ctype) != 0)
+ decl = check_classfn (ctype, decl);
+
+ if (TREE_TYPE (decl) != error_mark_node)
+ {
+ if (TYPE_SIZE (ctype))
+ add_friend (current_class_type, decl);
+ else
+ {
+ cp_error ("member `%D' declared as friend before type `%T' defined",
+ decl, ctype);
+ }
+ }
+ }
+ else
+ {
+ /* Possibly a bunch of method friends. */
+
+ /* Get the class they belong to. */
+ tree ctype = IDENTIFIER_TYPE_VALUE (cname);
+ tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0);
+
+ if (fields)
+ add_friends (current_class_type, declarator, ctype);
+ else
+ error ("method `%s' is not a member of class `%s'",
+ IDENTIFIER_POINTER (declarator),
+ IDENTIFIER_POINTER (cname));
+ decl = void_type_node;
+ }
+ }
+ else if (TREE_CODE (decl) == FUNCTION_DECL
+ && ((IDENTIFIER_LENGTH (declarator) == 4
+ && IDENTIFIER_POINTER (declarator)[0] == 'm'
+ && ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
+ || (IDENTIFIER_LENGTH (declarator) > 10
+ && IDENTIFIER_POINTER (declarator)[0] == '_'
+ && IDENTIFIER_POINTER (declarator)[1] == '_'
+ && strncmp (IDENTIFIER_POINTER (declarator)+2,
+ "builtin_", 8) == 0)))
+ {
+ /* raw "main", and builtin functions never gets overloaded,
+ but they can become friends. */
+ add_friend (current_class_type, decl);
+ DECL_FRIEND_P (decl) = 1;
+ decl = void_type_node;
+ }
+ /* A global friend.
+ @@ or possibly a friend from a base class ?!? */
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ /* Friends must all go through the overload machinery,
+ even though they may not technically be overloaded.
+
+ Note that because classes all wind up being top-level
+ in their scope, their friend wind up in top-level scope as well. */
+ DECL_ASSEMBLER_NAME (decl)
+ = build_decl_overload (declarator, TYPE_ARG_TYPES (TREE_TYPE (decl)),
+ TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE);
+ DECL_ARGUMENTS (decl) = parmdecls;
+ if (funcdef_flag)
+ DECL_CLASS_CONTEXT (decl) = current_class_type;
+
+ /* We can call pushdecl here, because the TREE_CHAIN of this
+ FUNCTION_DECL is not needed for other purposes. */
+ decl = pushdecl (decl);
+
+ make_decl_rtl (decl, NULL_PTR, 1);
+ add_friend (current_class_type, decl);
+
+ DECL_FRIEND_P (decl) = 1;
+ }
+ else
+ {
+ /* @@ Should be able to ingest later definitions of this function
+ before use. */
+ tree decl = lookup_name_nonclass (declarator);
+ if (decl == NULL_TREE)
+ {
+ warning ("implicitly declaring `%s' as struct",
+ IDENTIFIER_POINTER (declarator));
+ decl = xref_tag (record_type_node, declarator, NULL_TREE, 1);
+ decl = TYPE_MAIN_DECL (decl);
+ }
+
+ /* Allow abbreviated declarations of overloaded functions,
+ but not if those functions are really class names. */
+ if (TREE_CODE (decl) == TREE_LIST && TREE_TYPE (TREE_PURPOSE (decl)))
+ {
+ warning ("`friend %s' archaic, use `friend class %s' instead",
+ IDENTIFIER_POINTER (declarator),
+ IDENTIFIER_POINTER (declarator));
+ decl = TREE_TYPE (TREE_PURPOSE (decl));
+ }
+
+ if (TREE_CODE (decl) == TREE_LIST)
+ add_friends (current_class_type, TREE_PURPOSE (decl), NULL_TREE);
+ else
+ make_friend_class (current_class_type, TREE_TYPE (decl));
+ decl = void_type_node;
+ }
+ return decl;
+}
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 7da2d24..4e1785d 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -19,7 +19,6 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-
/* High-level class interface. */
#include "config.h"
@@ -52,8 +51,6 @@ static void expand_aggr_init_1 PROTO((tree, tree, tree, tree, int, int));
static void expand_virtual_init PROTO((tree, tree));
tree expand_vec_init ();
-static void add_friend (), add_friends ();
-
/* Cache _builtin_new and _builtin_delete exprs. */
static tree BIN, BID, BIVN, BIVD;
@@ -491,13 +488,9 @@ static tree
build_partial_cleanup_for (binfo)
tree binfo;
{
- tree expr = convert_pointer_to_real (binfo,
- build_unary_op (ADDR_EXPR, current_class_ref, 0));
-
- return build_delete (TREE_TYPE (expr),
- expr,
- integer_zero_node,
- LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
+ return build_scoped_method_call
+ (current_class_ref, binfo, dtor_identifier,
+ build_tree_list (NULL_TREE, integer_zero_node));
}
/* Perform whatever initializations have yet to be done on the base
@@ -1452,7 +1445,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags)
if (TREE_CODE (init) != TREE_LIST)
{
- if (TREE_CODE (init_type) == ERROR_MARK)
+ if (init_type == error_mark_node)
return;
/* This happens when we use C++'s functional cast notation.
@@ -2186,7 +2179,7 @@ decl_constant_value (decl)
&& ! pedantic
#endif /* 0 */
&& DECL_INITIAL (decl) != 0
- && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
+ && DECL_INITIAL (decl) != error_mark_node
/* This is invalid if initial value is not constant.
If it has either a function call, a memory reference,
or a variable, then re-evaluating it could give different results. */
@@ -2204,408 +2197,12 @@ decl_constant_value (decl)
return decl;
}
-/* Friend handling routines. */
-/* Friend data structures:
-
- Lists of friend functions come from TYPE_DECL nodes. Since all
- aggregate types are automatically typedef'd, these nodes are guaranteed
- to exist.
-
- The TREE_PURPOSE of a friend list is the name of the friend,
- and its TREE_VALUE is another list.
-
- For each element of that list, either the TREE_VALUE or the TREE_PURPOSE
- will be filled in, but not both. The TREE_VALUE of that list is an
- individual function which is a friend. The TREE_PURPOSE of that list
- indicates a type in which all functions by that name are friends.
-
- Lists of friend classes come from _TYPE nodes. Love that consistency
- thang. */
-
-int
-is_friend_type (type1, type2)
- tree type1, type2;
-{
- return is_friend (type1, type2);
-}
-
-int
-is_friend (type, supplicant)
- tree type, supplicant;
-{
- int declp;
- register tree list;
-
- if (supplicant == NULL_TREE || type == NULL_TREE)
- return 0;
-
- declp = (TREE_CODE_CLASS (TREE_CODE (supplicant)) == 'd');
-
- if (declp)
- /* It's a function decl. */
- {
- tree list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type));
- tree name = DECL_NAME (supplicant);
- tree ctype;
-
- if (DECL_FUNCTION_MEMBER_P (supplicant))
- ctype = DECL_CLASS_CONTEXT (supplicant);
- else
- ctype = NULL_TREE;
-
- for (; list ; list = TREE_CHAIN (list))
- {
- if (name == TREE_PURPOSE (list))
- {
- tree friends = TREE_VALUE (list);
- for (; friends ; friends = TREE_CHAIN (friends))
- {
- if (ctype == TREE_PURPOSE (friends))
- return 1;
- if (comptypes (TREE_TYPE (supplicant),
- TREE_TYPE (TREE_VALUE (friends)), 1))
- return 1;
- }
- break;
- }
- }
- }
- else
- /* It's a type. */
- {
- if (type == supplicant)
- return 1;
-
- list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
- for (; list ; list = TREE_CHAIN (list))
- if (supplicant == TREE_VALUE (list))
- return 1;
- }
-
- {
- tree context;
-
- if (! declp)
- {
- /* Are we a nested or local class? If so, we aren't friends
- with the CONTEXT. */
- if (IS_AGGR_TYPE (supplicant))
- context = NULL_TREE;
- else
- context = DECL_CONTEXT (TYPE_MAIN_DECL (supplicant));
- }
- else if (DECL_FUNCTION_MEMBER_P (supplicant))
- context = DECL_CLASS_CONTEXT (supplicant);
- else
- context = NULL_TREE;
-
- if (context)
- return is_friend (type, context);
- }
-
- return 0;
-}
-
-/* Add a new friend to the friends of the aggregate type TYPE.
- DECL is the FUNCTION_DECL of the friend being added. */
-
-static void
-add_friend (type, decl)
- tree type, decl;
-{
- tree typedecl = TYPE_MAIN_DECL (type);
- tree list = DECL_FRIENDLIST (typedecl);
- tree name = DECL_NAME (decl);
-
- while (list)
- {
- if (name == TREE_PURPOSE (list))
- {
- tree friends = TREE_VALUE (list);
- for (; friends ; friends = TREE_CHAIN (friends))
- {
- if (decl == TREE_VALUE (friends))
- {
- cp_warning ("`%D' is already a friend of class `%T'",
- decl, type);
- cp_warning_at ("previous friend declaration of `%D'",
- TREE_VALUE (friends));
- return;
- }
- }
- TREE_VALUE (list) = tree_cons (error_mark_node, decl,
- TREE_VALUE (list));
- return;
- }
- list = TREE_CHAIN (list);
- }
- DECL_FRIENDLIST (typedecl)
- = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
- DECL_FRIENDLIST (typedecl));
- if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR])
- {
- tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
- TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
- if (parmtypes && TREE_CHAIN (parmtypes))
- {
- tree parmtype = TREE_VALUE (TREE_CHAIN (parmtypes));
- if (TREE_CODE (parmtype) == REFERENCE_TYPE
- && TREE_TYPE (parmtypes) == TREE_TYPE (typedecl))
- TYPE_HAS_ASSIGN_REF (TREE_TYPE (typedecl)) = 1;
- }
- }
-}
-
-/* Declare that every member function NAME in FRIEND_TYPE
- (which may be NULL_TREE) is a friend of type TYPE. */
-
-static void
-add_friends (type, name, friend_type)
- tree type, name, friend_type;
-{
- tree typedecl = TYPE_MAIN_DECL (type);
- tree list = DECL_FRIENDLIST (typedecl);
-
- while (list)
- {
- if (name == TREE_PURPOSE (list))
- {
- tree friends = TREE_VALUE (list);
- while (friends && TREE_PURPOSE (friends) != friend_type)
- friends = TREE_CHAIN (friends);
- if (friends)
- if (friend_type)
- warning ("method `%s::%s' is already a friend of class",
- TYPE_NAME_STRING (friend_type),
- IDENTIFIER_POINTER (name));
- else
- warning ("function `%s' is already a friend of class `%s'",
- IDENTIFIER_POINTER (name),
- IDENTIFIER_POINTER (DECL_NAME (typedecl)));
- else
- TREE_VALUE (list) = tree_cons (friend_type, NULL_TREE,
- TREE_VALUE (list));
- return;
- }
- list = TREE_CHAIN (list);
- }
- DECL_FRIENDLIST (typedecl) =
- tree_cons (name,
- build_tree_list (friend_type, NULL_TREE),
- DECL_FRIENDLIST (typedecl));
- if (! strncmp (IDENTIFIER_POINTER (name),
- IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]),
- strlen (IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]))))
- {
- TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
- sorry ("declaring \"friend operator =\" will not find \"operator = (X&)\" if it exists");
- }
-}
-
-/* Make FRIEND_TYPE a friend class to TYPE. If FRIEND_TYPE has already
- been defined, we make all of its member functions friends of
- TYPE. If not, we make it a pending friend, which can later be added
- when its definition is seen. If a type is defined, then its TYPE_DECL's
- DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend
- classes that are not defined. If a type has not yet been defined,
- then the DECL_WAITING_FRIENDS contains a list of types
- waiting to make it their friend. Note that these two can both
- be in use at the same time! */
-
-void
-make_friend_class (type, friend_type)
- tree type, friend_type;
-{
- tree classes;
-
- if (IS_SIGNATURE (type))
- {
- error ("`friend' declaration in signature definition");
- return;
- }
- if (IS_SIGNATURE (friend_type))
- {
- error ("signature type `%s' declared `friend'",
- IDENTIFIER_POINTER (TYPE_IDENTIFIER (friend_type)));
- return;
- }
- if (type == friend_type)
- {
- pedwarn ("class `%s' is implicitly friends with itself",
- TYPE_NAME_STRING (type));
- return;
- }
-
- GNU_xref_hier (TYPE_NAME_STRING (type),
- TYPE_NAME_STRING (friend_type), 0, 0, 1);
-
- classes = CLASSTYPE_FRIEND_CLASSES (type);
- while (classes && TREE_VALUE (classes) != friend_type)
- classes = TREE_CHAIN (classes);
- if (classes)
- warning ("class `%s' is already friends with class `%s'",
- TYPE_NAME_STRING (TREE_VALUE (classes)), TYPE_NAME_STRING (type));
- else
- {
- CLASSTYPE_FRIEND_CLASSES (type)
- = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
- }
-}
-
-/* Main friend processor. This is large, and for modularity purposes,
- has been removed from grokdeclarator. It returns `void_type_node'
- to indicate that something happened, though a FIELD_DECL is
- not returned.
-
- CTYPE is the class this friend belongs to.
-
- DECLARATOR is the name of the friend.
-
- DECL is the FUNCTION_DECL that the friend is.
-
- In case we are parsing a friend which is part of an inline
- definition, we will need to store PARM_DECL chain that comes
- with it into the DECL_ARGUMENTS slot of the FUNCTION_DECL.
-
- FLAGS is just used for `grokclassfn'.
-
- QUALS say what special qualifies should apply to the object
- pointed to by `this'. */
-
-tree
-do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
- tree ctype, declarator, decl, parmdecls;
- enum overload_flags flags;
- tree quals;
- int funcdef_flag;
-{
- /* Every decl that gets here is a friend of something. */
- DECL_FRIEND_P (decl) = 1;
-
- if (ctype)
- {
- tree cname = TYPE_NAME (ctype);
- if (TREE_CODE (cname) == TYPE_DECL)
- cname = DECL_NAME (cname);
-
- /* A method friend. */
- if (TREE_CODE (decl) == FUNCTION_DECL)
- {
- if (flags == NO_SPECIAL && ctype && declarator == cname)
- DECL_CONSTRUCTOR_P (decl) = 1;
-
- /* This will set up DECL_ARGUMENTS for us. */
- grokclassfn (ctype, cname, decl, flags, quals);
- if (TYPE_SIZE (ctype) != 0)
- decl = check_classfn (ctype, decl);
-
- if (TREE_TYPE (decl) != error_mark_node)
- {
- if (TYPE_SIZE (ctype))
- add_friend (current_class_type, decl);
- else
- {
- cp_error ("member `%D' declared as friend before type `%T' defined",
- decl, ctype);
- }
- }
- }
- else
- {
- /* Possibly a bunch of method friends. */
-
- /* Get the class they belong to. */
- tree ctype = IDENTIFIER_TYPE_VALUE (cname);
- tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0);
-
- if (fields)
- add_friends (current_class_type, declarator, ctype);
- else
- error ("method `%s' is not a member of class `%s'",
- IDENTIFIER_POINTER (declarator),
- IDENTIFIER_POINTER (cname));
- decl = void_type_node;
- }
- }
- else if (TREE_CODE (decl) == FUNCTION_DECL
- && ((IDENTIFIER_LENGTH (declarator) == 4
- && IDENTIFIER_POINTER (declarator)[0] == 'm'
- && ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
- || (IDENTIFIER_LENGTH (declarator) > 10
- && IDENTIFIER_POINTER (declarator)[0] == '_'
- && IDENTIFIER_POINTER (declarator)[1] == '_'
- && strncmp (IDENTIFIER_POINTER (declarator)+2,
- "builtin_", 8) == 0)))
- {
- /* raw "main", and builtin functions never gets overloaded,
- but they can become friends. */
- add_friend (current_class_type, decl);
- DECL_FRIEND_P (decl) = 1;
- decl = void_type_node;
- }
- /* A global friend.
- @@ or possibly a friend from a base class ?!? */
- else if (TREE_CODE (decl) == FUNCTION_DECL)
- {
- /* Friends must all go through the overload machinery,
- even though they may not technically be overloaded.
-
- Note that because classes all wind up being top-level
- in their scope, their friend wind up in top-level scope as well. */
- DECL_ASSEMBLER_NAME (decl)
- = build_decl_overload (declarator, TYPE_ARG_TYPES (TREE_TYPE (decl)),
- TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE);
- DECL_ARGUMENTS (decl) = parmdecls;
- if (funcdef_flag)
- DECL_CLASS_CONTEXT (decl) = current_class_type;
-
- /* We can call pushdecl here, because the TREE_CHAIN of this
- FUNCTION_DECL is not needed for other purposes. */
- decl = pushdecl (decl);
-
- make_decl_rtl (decl, NULL_PTR, 1);
- add_friend (current_class_type, decl);
-
- DECL_FRIEND_P (decl) = 1;
- }
- else
- {
- /* @@ Should be able to ingest later definitions of this function
- before use. */
- tree decl = lookup_name_nonclass (declarator);
- if (decl == NULL_TREE)
- {
- warning ("implicitly declaring `%s' as struct",
- IDENTIFIER_POINTER (declarator));
- decl = xref_tag (record_type_node, declarator, NULL_TREE, 1);
- decl = TYPE_MAIN_DECL (decl);
- }
-
- /* Allow abbreviated declarations of overloaded functions,
- but not if those functions are really class names. */
- if (TREE_CODE (decl) == TREE_LIST && TREE_TYPE (TREE_PURPOSE (decl)))
- {
- warning ("`friend %s' archaic, use `friend class %s' instead",
- IDENTIFIER_POINTER (declarator),
- IDENTIFIER_POINTER (declarator));
- decl = TREE_TYPE (TREE_PURPOSE (decl));
- }
-
- if (TREE_CODE (decl) == TREE_LIST)
- add_friends (current_class_type, TREE_PURPOSE (decl), NULL_TREE);
- else
- make_friend_class (current_class_type, TREE_TYPE (decl));
- decl = void_type_node;
- }
- return decl;
-}
-
/* Common subroutines of build_new and build_vec_delete. */
/* Common interface for calling "builtin" functions that are not
really builtin. */
-tree
+static tree
build_builtin_call (type, node, arglist)
tree type;
tree node;
@@ -3661,11 +3258,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
else
addr = convert_force (build_pointer_type (type), addr, 0);
- if (TREE_CODE (addr) == NOP_EXPR
- && TREE_OPERAND (addr, 0) == current_class_ptr)
- ref = current_class_ref;
- else
- ref = build_indirect_ref (addr, NULL_PTR);
+ ref = build_indirect_ref (addr, NULL_PTR);
ptr = 0;
}
@@ -3699,6 +3292,8 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
tree dtor = DECL_MAIN_VARIANT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1));
tree passed_auto_delete;
tree do_delete = NULL_TREE;
+ tree ifexp;
+ int nonnull;
if (use_global_delete)
{
@@ -3718,108 +3313,29 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
else
passed_auto_delete = auto_delete;
- if (flags & LOOKUP_PROTECT)
- {
- tree access;
- tree basetypes = NULL_TREE;
- if (current_class_type != NULL_TREE)
- basetypes = get_binfo (type, current_class_type, 0);
- if (basetypes == NULL_TREE)
- basetypes = TYPE_BINFO (type);
- access = compute_access (basetypes, dtor);
-
- if (access == access_private_node)
- {
- if (flags & LOOKUP_COMPLAIN)
- cp_error ("destructor for type `%T' is private in this scope", type);
- return error_mark_node;
- }
- else if (access == access_protected_node)
- {
- if (flags & LOOKUP_COMPLAIN)
- cp_error ("destructor for type `%T' is protected in this scope", type);
- return error_mark_node;
- }
- }
-
- /* Once we are in a destructor, try not going through
- the virtual function table to find the next destructor. */
- if (DECL_VINDEX (dtor)
- && ! (flags & LOOKUP_NONVIRTUAL)
- && TREE_CODE (auto_delete) != PARM_DECL
- && (ptr == 1 || ! resolves_to_fixed_type_p (ref, 0)))
- {
- tree binfo, basetype;
- /* The code below is probably all broken. See call.c for the
- complete right way to do this. this offsets may not be right
- in the below. (mrs) */
- /* This destructor must be called via virtual function table. */
- dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (DECL_CONTEXT (dtor)), 1);
- basetype = DECL_CLASS_CONTEXT (dtor);
- binfo = get_binfo (basetype,
- TREE_TYPE (TREE_TYPE (TREE_VALUE (parms))),
- 0);
- expr = convert_pointer_to_real (binfo, TREE_VALUE (parms));
- if (expr != TREE_VALUE (parms))
- {
- expr = fold (expr);
- ref = build_indirect_ref (expr, NULL_PTR);
- TREE_VALUE (parms) = expr;
- }
- function = build_vfn_ref (&TREE_VALUE (parms), ref, DECL_VINDEX (dtor));
- if (function == error_mark_node)
- return error_mark_node;
- TREE_TYPE (function) = build_pointer_type (TREE_TYPE (dtor));
- TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete);
- expr = build_function_call (function, parms);
- if (do_delete)
- expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
- if (ptr && (flags & LOOKUP_DESTRUCTOR) == 0)
- {
- /* Handle the case where a virtual destructor is
- being called on an item that is 0.
+ expr = build_method_call
+ (ref, dtor_identifier, build_tree_list (NULL_TREE, passed_auto_delete),
+ NULL_TREE, flags);
- @@ Does this really need to be done? */
- tree ifexp = build_binary_op(NE_EXPR, addr, integer_zero_node,1);
+ if (do_delete)
+ expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
- expr = build (COND_EXPR, void_type_node,
- ifexp, expr, void_zero_node);
- }
- }
+ if (flags & LOOKUP_DESTRUCTOR)
+ /* Explicit destructor call; don't check for null pointer. */
+ ifexp = integer_one_node;
else
- {
- tree ifexp;
-
- if ((flags & LOOKUP_DESTRUCTOR)
- || TREE_CODE (ref) == VAR_DECL
- || TREE_CODE (ref) == PARM_DECL
- || TREE_CODE (ref) == COMPONENT_REF
- || TREE_CODE (ref) == ARRAY_REF)
- /* These can't be 0. */
- ifexp = integer_one_node;
- else
- /* Handle the case where a non-virtual destructor is
- being called on an item that is 0. */
- ifexp = build_binary_op (NE_EXPR, addr, integer_zero_node, 1);
+ /* Handle deleting a null pointer. */
+ ifexp = fold (build_binary_op (NE_EXPR, addr, integer_zero_node, 1));
- /* Used to mean that this destructor was known to be empty,
- but that's now obsolete. */
- my_friendly_assert (DECL_INITIAL (dtor) != void_type_node, 221);
+ if (ifexp != integer_one_node)
+ expr = build (COND_EXPR, void_type_node,
+ ifexp, expr, void_zero_node);
- TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete);
- expr = build_function_call (dtor, parms);
- if (do_delete)
- expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
-
- if (ifexp != integer_one_node)
- expr = build (COND_EXPR, void_type_node,
- ifexp, expr, void_zero_node);
- }
return expr;
}
else
{
- /* This can get visibilities wrong. */
+ /* We only get here from finish_function for a destructor. */
tree binfos = BINFO_BASETYPES (TYPE_BINFO (type));
int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
tree base_binfo = n_baseclasses > 0 ? TREE_VEC_ELT (binfos, 0) : NULL_TREE;
@@ -3827,39 +3343,12 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
tree parent_auto_delete = auto_delete;
tree cond;
- /* If this type does not have a destructor, but does have
- operator delete, call the parent parent destructor (if any),
- but let this node do the deleting. Otherwise, it is ok
- to let the parent destructor do the deleting. */
- if (TYPE_GETS_REG_DELETE (type) && !use_global_delete)
- {
- parent_auto_delete = integer_zero_node;
- if (auto_delete == integer_zero_node)
- cond = NULL_TREE;
- else
- {
- tree virtual_size;
-
- /* This is probably wrong. It should be the size of the
- virtual object being deleted. */
- virtual_size = c_sizeof_nowarn (type);
-
- expr = build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr,
- virtual_size, NULL_TREE);
- if (expr == error_mark_node)
- return error_mark_node;
- if (auto_delete != integer_one_node)
- cond = build (COND_EXPR, void_type_node,
- build (BIT_AND_EXPR, integer_type_node,
- auto_delete, integer_one_node),
- expr, void_zero_node);
- else
- cond = expr;
- }
- }
+ /* If we have member delete or vbases, we call delete in
+ finish_function. */
+ if (auto_delete == integer_zero_node)
+ cond = NULL_TREE;
else if (base_binfo == NULL_TREE
- || (TREE_VIA_VIRTUAL (base_binfo) == 0
- && ! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))))
+ || ! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)))
{
cond = build (COND_EXPR, void_type_node,
build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_one_node),
@@ -3884,8 +3373,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
else
this_auto_delete = integer_zero_node;
- expr = build_delete (build_pointer_type (BINFO_TYPE (base_binfo)), addr,
- this_auto_delete, flags, 0);
+ expr = build_scoped_method_call
+ (ref, base_binfo, dtor_identifier,
+ build_tree_list (NULL_TREE, this_auto_delete));
exprstmt = tree_cons (NULL_TREE, expr, exprstmt);
}
@@ -3897,13 +3387,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
|| TREE_VIA_VIRTUAL (base_binfo))
continue;
- /* May be zero offset if other baseclasses are virtual. */
- expr = fold (build (PLUS_EXPR, build_pointer_type (BINFO_TYPE (base_binfo)),
- addr, BINFO_OFFSET (base_binfo)));
-
- expr = build_delete (build_pointer_type (BINFO_TYPE (base_binfo)), expr,
- integer_zero_node,
- flags, 0);
+ expr = build_scoped_method_call
+ (ref, base_binfo, dtor_identifier,
+ build_tree_list (NULL_TREE, integer_zero_node));
exprstmt = tree_cons (NULL_TREE, expr, exprstmt);
}
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 451f598..befb5a1 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -271,7 +271,7 @@ char *token_buffer; /* Pointer to token buffer.
#include "hash.h"
-int check_newline ();
+static int check_newline ();
/* Nonzero tells yylex to ignore \ in string constants. */
static int ignore_escape_flag = 0;
@@ -392,12 +392,14 @@ init_filename_times ()
Stuck this hack in to get the files open correctly; this is called
in place of init_lex if we are an unexec'd binary. */
+#if 0
void
reinit_lang_specific ()
{
init_filename_times ();
reinit_search_statistics ();
}
+#endif
int *init_parse ();
@@ -1091,7 +1093,7 @@ interface_strcmp (s)
return 1;
}
-void
+static void
set_typedecl_interface_info (prev, vars)
tree prev, vars;
{
@@ -1103,7 +1105,7 @@ set_typedecl_interface_info (prev, vars)
= interface_strcmp (FILE_NAME_NONDIRECTORY (DECL_SOURCE_FILE (vars)));
}
-int
+static int
set_vardecl_interface_info (prev, vars)
tree prev, vars;
{
@@ -1403,7 +1405,7 @@ store_pending_inline (decl, t)
pending_inlines = t;
}
-void reinit_parse_for_block ();
+static void reinit_parse_for_block PROTO((int, struct obstack *));
void
reinit_parse_for_method (yychar, decl)
@@ -1455,7 +1457,7 @@ reinit_parse_for_method (yychar, decl)
/* Consume a block -- actually, a method beginning
with `:' or `{' -- and save it away on the specified obstack. */
-void
+static void
reinit_parse_for_block (pyychar, obstackp)
int pyychar;
struct obstack *obstackp;
@@ -1900,7 +1902,7 @@ static int handle_sysv_pragma ();
#endif
static int handle_cp_pragma ();
-int
+static int
check_newline ()
{
register int c;
@@ -2517,7 +2519,12 @@ do_identifier (token, parsing)
[class.scope0] */
if (id && current_class_type && parsing
&& TYPE_BEING_DEFINED (current_class_type)
- && ! IDENTIFIER_CLASS_VALUE (token))
+ && ! IDENTIFIER_CLASS_VALUE (token)
+ /* Avoid breaking if we get called for a default argument that
+ refers to an overloaded method. Eventually this will not be
+ necessary, since default arguments shouldn't be parsed until
+ after the class is complete. (jason 3/12/97) */
+ && TREE_CODE (id) != TREE_LIST)
pushdecl_class_level (id);
if (!id || id == error_mark_node)
@@ -4158,33 +4165,6 @@ make_lang_type (code)
}
void
-copy_decl_lang_specific (decl)
- tree decl;
-{
- extern struct obstack *current_obstack, *saveable_obstack;
- register int *old = (int *)DECL_LANG_SPECIFIC (decl);
- struct obstack *obstack = current_obstack;
- register int i = sizeof (struct lang_decl) / sizeof (int);
- register int *pi;
-
- if (! TREE_PERMANENT (decl))
- obstack = saveable_obstack;
- else
- my_friendly_assert (obstack == &permanent_obstack, 237);
-
- pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
- while (i-- > 0)
- pi[i] = old[i];
-
- DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi;
-
-#ifdef GATHER_STATISTICS
- tree_node_counts[(int)lang_decl] += 1;
- tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
-#endif
-}
-
-void
dump_time_statistics ()
{
register tree prev = 0, decl, next;
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 4600c5c..a9dd9d5 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -261,28 +261,67 @@ __inline
#endif
void
icat (i)
- int i;
+ HOST_WIDE_INT i;
{
+ unsigned HOST_WIDE_INT ui;
+
/* Handle this case first, to go really quickly. For many common values,
- the result of i/10 below is 1. */
+ the result of ui/10 below is 1. */
if (i == 1)
{
OB_PUTC ('1');
return;
}
- if (i < 0)
+ if (i >= 0)
+ ui = i;
+ else
{
OB_PUTC ('m');
- i = -i;
+ ui = -i;
+ }
+
+ if (ui >= 10)
+ icat (ui / 10);
+
+ OB_PUTC ('0' + (ui % 10));
+}
+
+static void
+dicat (lo, hi)
+ HOST_WIDE_INT lo, hi;
+{
+ unsigned HOST_WIDE_INT ulo, uhi, qlo, qhi;
+
+ if (hi >= 0)
+ {
+ uhi = hi;
+ ulo = lo;
}
- if (i < 10)
- OB_PUTC ('0' + i);
else
{
- icat (i / 10);
- OB_PUTC ('0' + (i % 10));
+ uhi = (lo == 0 ? -hi : -hi-1);
+ ulo = -lo;
+ }
+ if (uhi == 0
+ && ulo < ((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)))
+ {
+ icat (ulo);
+ return;
}
+ /* Divide 2^HOST_WIDE_INT*uhi+ulo by 10. */
+ qhi = uhi / 10;
+ uhi = uhi % 10;
+ qlo = uhi * (((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)) / 5);
+ qlo += ulo / 10;
+ ulo = ulo % 10;
+ ulo += uhi * (((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)) % 5)
+ * 2;
+ qlo += ulo / 10;
+ ulo = ulo % 10;
+ /* Quotient is 2^HOST_WIDE_INT*qhi+qlo, remainder is ulo. */
+ dicat (qlo, qhi);
+ OB_PUTC ('0' + ulo);
}
static
@@ -380,17 +419,12 @@ build_overload_int (value)
my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);
if (TYPE_PRECISION (TREE_TYPE (value)) == 2 * HOST_BITS_PER_WIDE_INT)
{
- if (tree_int_cst_lt (value, integer_zero_node))
- {
- OB_PUTC ('m');
- value = build_int_2 (~ TREE_INT_CST_LOW (value),
- - TREE_INT_CST_HIGH (value));
- }
if (TREE_INT_CST_HIGH (value)
!= (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1)))
{
/* need to print a DImode value in decimal */
- sorry ("conversion of long long as PT parameter");
+ dicat (TREE_INT_CST_LOW (value), TREE_INT_CST_HIGH (value));
+ return;
}
/* else fall through to print in smaller mode */
}
@@ -440,54 +474,73 @@ build_overload_value (type, value)
numeric_output_need_bar = 1;
return;
}
-#ifndef REAL_IS_NOT_DOUBLE
case REAL_TYPE:
{
REAL_VALUE_TYPE val;
char *bufp = digit_buffer;
extern char *index ();
+ pedwarn ("ANSI C++ forbids floating-point template arguments");
+
my_friendly_assert (TREE_CODE (value) == REAL_CST, 244);
val = TREE_REAL_CST (value);
- if (val < 0)
+ if (REAL_VALUE_ISNAN (val))
{
- val = -val;
- *bufp++ = 'm';
+ sprintf (bufp, "NaN");
}
- sprintf (bufp, "%e", val);
- bufp = (char *) index (bufp, 'e');
- if (!bufp)
- strcat (digit_buffer, "e0");
else
{
- char *p;
- bufp++;
- if (*bufp == '-')
+ if (REAL_VALUE_NEGATIVE (val))
{
+ val = REAL_VALUE_NEGATE (val);
*bufp++ = 'm';
}
- p = bufp;
- if (*p == '+')
- p++;
- while (*p == '0')
- p++;
- if (*p == 0)
+ if (REAL_VALUE_ISINF (val))
{
- *bufp++ = '0';
- *bufp = 0;
+ sprintf (bufp, "Infinity");
}
- else if (p != bufp)
+ else
{
- while (*p)
- *bufp++ = *p++;
- *bufp = 0;
+ ereal_to_decimal (val, bufp);
+ bufp = (char *) index (bufp, 'e');
+ if (!bufp)
+ strcat (digit_buffer, "e0");
+ else
+ {
+ char *p;
+ bufp++;
+ if (*bufp == '-')
+ {
+ *bufp++ = 'm';
+ }
+ p = bufp;
+ if (*p == '+')
+ p++;
+ while (*p == '0')
+ p++;
+ if (*p == 0)
+ {
+ *bufp++ = '0';
+ *bufp = 0;
+ }
+ else if (p != bufp)
+ {
+ while (*p)
+ *bufp++ = *p++;
+ *bufp = 0;
+ }
+ }
+#ifdef NO_DOT_IN_LABEL
+ bufp = (char *) index (bufp, '.');
+ if (bufp)
+ *bufp = '_';
+#endif
}
}
OB_PUTCP (digit_buffer);
numeric_output_need_bar = 1;
return;
}
-#endif
case POINTER_TYPE:
if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE
&& TREE_CODE (value) != ADDR_EXPR)
@@ -1151,8 +1204,8 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
if (code == COND_EXPR)
{
- if (TREE_CODE (xarg2) == ERROR_MARK
- || TREE_CODE (arg3) == ERROR_MARK)
+ if (xarg2 == error_mark_node
+ || arg3 == error_mark_node)
return error_mark_node;
}
if (code == COMPONENT_REF)
@@ -1468,7 +1521,7 @@ hack_identifier (value, name)
{
tree type;
- if (TREE_CODE (value) == ERROR_MARK)
+ if (value == error_mark_node)
{
if (current_class_name)
{
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index ff0a139..720c041 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -2478,10 +2478,11 @@ left_curly:
push_obstacks_nochange ();
end_temporary_allocation ();
- if (! IS_AGGR_TYPE (t))
+ if (t == error_mark_node
+ || ! IS_AGGR_TYPE (t))
{
t = $<ttype>0 = make_lang_type (RECORD_TYPE);
- TYPE_NAME (t) = get_identifier ("erroneous type");
+ pushtag (make_anon_name (), t, 0);
}
if (TYPE_SIZE (t))
duplicate_tag_error (t);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 89002d4..d0a6c76 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -65,11 +65,12 @@ static int unify ();
void pop_template_decls ();
-tree classtype_mangled_name ();
+static tree classtype_mangled_name ();
static char * mangle_class_name_for_template ();
static tree tsubst_expr_values ();
+static int comp_template_args PROTO((tree, tree));
tree most_specialized_class PROTO((tree, tree));
-tree get_class_bindings PROTO((tree, tree, tree));
+static tree get_class_bindings PROTO((tree, tree, tree));
tree make_temp_vec PROTO((int));
/* We've got a template header coming up; push to a new level for storing
@@ -448,6 +449,11 @@ coerce_template_parms (parms, arglist, in_decl)
/* 14.2: Other template-arguments must be constant-expressions,
addresses of objects or functions with external linkage, or of
static class members. */
+ else if (IS_AGGR_TYPE (TREE_TYPE (val)))
+ {
+ cp_error ("object `%E' cannot be used as template argument", arg);
+ val = error_mark_node;
+ }
else if (!TREE_CONSTANT (val))
{
cp_error ("non-const `%E' cannot be used as template argument",
@@ -504,7 +510,7 @@ coerce_template_parms (parms, arglist, in_decl)
return vec;
}
-int
+static int
comp_template_args (oldargs, newargs)
tree oldargs, newargs;
{
@@ -616,7 +622,7 @@ mangle_class_name_for_template (name, parms, arglist)
return NULL;
}
-tree
+static tree
classtype_mangled_name (t)
tree t;
{
@@ -968,7 +974,7 @@ extern int max_tinst_depth;
int depth_reached = 0;
#endif
-int
+static int
push_tinst_level (d)
tree d;
{
@@ -2808,7 +2814,11 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts, strict)
return 0;
/* Types INTEGER_CST and MINUS_EXPR can come from array bounds. */
+ /* Type INTEGER_CST can come from ordinary constant template args. */
case INTEGER_CST:
+ while (TREE_CODE (arg) == NOP_EXPR)
+ arg = TREE_OPERAND (arg, 0);
+
if (TREE_CODE (arg) != INTEGER_CST)
return 1;
return !tree_int_cst_equal (parm, arg);
@@ -2993,7 +3003,7 @@ get_bindings (fn, decl)
return 0;
}
-tree
+static tree
get_class_bindings (tparms, parms, args)
tree tparms, parms, args;
{
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index ec7a52b..f5f372c 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -412,10 +412,10 @@ pop_memoized_context (use_old)
/* Get a virtual binfo that is found inside BINFO's hierarchy that is
the same type as the type given in PARENT. To be optimal, we want
the first one that is found by going through the least number of
- virtual bases. DEPTH should be NULL_PTR. */
+ virtual bases. */
static tree
-get_vbase (parent, binfo, depth)
+get_vbase_1 (parent, binfo, depth)
tree parent, binfo;
unsigned int *depth;
{
@@ -423,12 +423,6 @@ get_vbase (parent, binfo, depth)
int i, n_baselinks;
tree rval = NULL_TREE;
- if (depth == 0)
- {
- unsigned int d = (unsigned int)-1;
- return get_vbase (parent, binfo, &d);
- }
-
if (BINFO_TYPE (binfo) == parent && TREE_VIA_VIRTUAL (binfo))
{
*depth = 0;
@@ -449,7 +443,7 @@ get_vbase (parent, binfo, depth)
if (*depth == 0)
break;
- nrval = get_vbase (parent, base_binfo, depth);
+ nrval = get_vbase_1 (parent, base_binfo, depth);
if (nrval)
rval = nrval;
}
@@ -457,16 +451,25 @@ get_vbase (parent, binfo, depth)
return rval;
}
+tree
+get_vbase (parent, binfo)
+ tree parent;
+ tree binfo;
+{
+ unsigned int d = (unsigned int)-1;
+ return get_vbase_1 (parent, binfo, &d);
+}
+
/* Convert EXPR to a virtual base class of type TYPE. We know that
EXPR is a non-null POINTER_TYPE to RECORD_TYPE. We also know that
the type of what expr points to has a virtual base of type TYPE. */
-tree
+static tree
convert_pointer_to_vbase (type, expr)
tree type;
tree expr;
{
- tree vb = get_vbase (type, TYPE_BINFO (TREE_TYPE (TREE_TYPE (expr))), NULL_PTR);
+ tree vb = get_vbase (type, TYPE_BINFO (TREE_TYPE (TREE_TYPE (expr))));
return convert_pointer_to_real (vb, expr);
}
@@ -3158,7 +3161,6 @@ note_debug_info_needed (type)
/* Subroutines of push_class_decls (). */
/* Add in a decl to the envelope. */
-
static void
envelope_add_decl (type, decl, values)
tree type, decl, *values;
diff --git a/gcc/cp/sig.c b/gcc/cp/sig.c
index 7e53de6..2a5efcd 100644
--- a/gcc/cp/sig.c
+++ b/gcc/cp/sig.c
@@ -37,6 +37,8 @@ extern void sorry ();
extern void compiler_error ();
extern void make_decl_rtl PROTO((tree, char *, int));
+static tree build_sptr_ref PROTO((tree));
+
/* Used to help generate globally unique names for signature tables. */
static int global_sigtable_name_counter;
@@ -1047,7 +1049,7 @@ build_optr_ref (instance)
/* Create a COMPONENT_REF expression for referencing the SPTR field
of a signature pointer or reference. */
-tree
+static tree
build_sptr_ref (instance)
tree instance;
{
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index df732f5..aefce65 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -404,7 +404,7 @@ build_cplus_method_type (basetype, rettype, argtypes)
return t;
}
-tree
+static tree
build_cplus_array_type_1 (elt_type, index_type)
tree elt_type;
tree index_type;
@@ -1319,41 +1319,6 @@ get_first_fn (from)
return TREE_VALUE (from);
}
-tree
-fnaddr_from_vtable_entry (entry)
- tree entry;
-{
- if (flag_vtable_thunks)
- {
- tree func = entry;
- if (TREE_CODE (func) == ADDR_EXPR)
- func = TREE_OPERAND (func, 0);
- if (TREE_CODE (func) == THUNK_DECL)
- return DECL_INITIAL (func);
- else
- return entry;
- }
- else
- return TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (entry))));
-}
-
-tree
-function_arg_chain (t)
- tree t;
-{
- return TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (t)));
-}
-
-int
-promotes_to_aggr_type (t, code)
- tree t;
- enum tree_code code;
-{
- if (TREE_CODE (t) == code)
- t = TREE_TYPE (t);
- return IS_AGGR_TYPE (t);
-}
-
int
is_aggr_type_2 (t1, t2)
tree t1, t2;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 10fbdef..a734c01 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -44,18 +44,17 @@ int mark_addressable PROTO((tree));
static tree convert_for_assignment PROTO((tree, tree, char*, tree, int));
/* static */ tree convert_for_initialization PROTO((tree, tree, tree, int, char*, tree, int));
extern tree shorten_compare ();
-extern void binary_op_error ();
static tree pointer_int_sum PROTO((enum tree_code, register tree, register tree));
static tree pointer_diff PROTO((register tree, register tree));
+static int comp_target_parms PROTO((tree, tree, int));
+static int comp_ptr_ttypes_const PROTO((tree, tree));
+static int comp_ptr_ttypes_reinterpret PROTO((tree, tree));
#if 0
static tree convert_sequence ();
#endif
/* static */ tree unary_complex_lvalue PROTO((enum tree_code, tree));
static tree get_delta_difference PROTO((tree, tree, int));
-extern rtx original_result_rtx;
-extern int warn_synth;
-
/* Return the target type of TYPE, which meas return T for:
T*, T&, T[], T (...), and otherwise, just T. */
@@ -942,7 +941,7 @@ comp_target_types (ttl, ttr, nptrs)
If there is not a unique most-derived base type, this function
returns ERROR_MARK_NODE. */
-tree
+static tree
common_base_type (tt1, tt2)
tree tt1, tt2;
{
@@ -1049,7 +1048,7 @@ compparms (parms1, parms2, strict)
/* This really wants return whether or not parameter type lists
would make their owning functions assignment compatible or not. */
-int
+static int
comp_target_parms (parms1, parms2, strict)
tree parms1, parms2;
int strict;
@@ -2071,16 +2070,6 @@ build_indirect_ref (ptr, errorstring)
will inherit the type of the array, which will be some pointer type. */
tree
-build_x_array_ref (array, idx)
- tree array, idx;
-{
- tree rval = build_opfncall (ARRAY_REF, LOOKUP_NORMAL, array, idx, NULL_TREE);
- if (rval)
- return rval;
- return build_array_ref (array, idx);
-}
-
-tree
build_array_ref (array, idx)
tree array, idx;
{
@@ -5365,8 +5354,7 @@ build_const_cast (type, expr)
tree
build_c_cast (type, expr)
- register tree type;
- tree expr;
+ tree type, expr;
{
register tree value = expr;
@@ -5436,7 +5424,6 @@ build_c_cast (type, expr)
else
{
tree otype;
- int flag;
/* Convert functions and arrays to pointers and
convert references to their expanded types,
@@ -5506,7 +5493,7 @@ build_c_cast (type, expr)
value = decl_constant_value (value);
ovalue = value;
- value = convert_force (type, value, flag);
+ value = convert_force (type, value, CONV_C_CAST);
/* Ignore any integer overflow caused by the cast. */
if (TREE_CODE (value) == INTEGER_CST)
@@ -5580,7 +5567,7 @@ build_modify_expr (lhs, modifycode, rhs)
tree olhs = lhs;
/* Avoid duplicate error messages from operands that had errors. */
- if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK)
+ if (lhs == error_mark_node || rhs == error_mark_node)
return error_mark_node;
/* Types that aren't fully specified cannot be used in assignments. */
@@ -5616,14 +5603,14 @@ build_modify_expr (lhs, modifycode, rhs)
case COMPOUND_EXPR:
newrhs = build_modify_expr (TREE_OPERAND (lhs, 1),
modifycode, rhs);
- if (TREE_CODE (newrhs) == ERROR_MARK)
+ if (newrhs == error_mark_node)
return error_mark_node;
return build (COMPOUND_EXPR, lhstype,
TREE_OPERAND (lhs, 0), newrhs);
case MODIFY_EXPR:
newrhs = build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs);
- if (TREE_CODE (newrhs) == ERROR_MARK)
+ if (newrhs == error_mark_node)
return error_mark_node;
return build (COMPOUND_EXPR, lhstype, lhs, newrhs);
@@ -5640,7 +5627,7 @@ build_modify_expr (lhs, modifycode, rhs)
modifycode, rhs),
build_modify_expr (convert (TREE_TYPE (lhs), TREE_OPERAND (lhs, 2)),
modifycode, rhs));
- if (TREE_CODE (cond) == ERROR_MARK)
+ if (cond == error_mark_node)
return cond;
/* Make sure the code to compute the rhs comes out
before the split. */
@@ -5796,7 +5783,7 @@ build_modify_expr (lhs, modifycode, rhs)
result = build_modify_expr (inner_lhs, NOP_EXPR,
convert (TREE_TYPE (inner_lhs),
convert (lhstype, newrhs)));
- if (TREE_CODE (result) == ERROR_MARK)
+ if (result == error_mark_node)
return result;
return convert (TREE_TYPE (lhs), result);
}
@@ -5983,7 +5970,7 @@ build_modify_expr (lhs, modifycode, rhs)
TREE_OPERAND (newrhs, 0));
}
- if (TREE_CODE (newrhs) == ERROR_MARK)
+ if (newrhs == error_mark_node)
return error_mark_node;
if (TREE_CODE (newrhs) == COND_EXPR)
@@ -7321,7 +7308,7 @@ c_expand_start_case (exp)
/* CONSTP remembers whether or not all the intervening pointers in the `to'
type have been const. */
-int
+static int
comp_ptr_ttypes_real (to, from, constp)
tree to, from;
int constp;
@@ -7392,7 +7379,7 @@ ptr_reasonably_similar (to, from)
/* Like comp_ptr_ttypes, for const_cast. */
-int
+static int
comp_ptr_ttypes_const (to, from)
tree to, from;
{
@@ -7413,7 +7400,7 @@ comp_ptr_ttypes_const (to, from)
/* Like comp_ptr_ttypes, for reinterpret_cast. */
-int
+static int
comp_ptr_ttypes_reinterpret (to, from)
tree to, from;
{