91th Cygnus<->FSF quick merge

From-SVN: r14253
This commit is contained in:
Mike Stump 1997-06-18 02:25:37 +00:00
parent 59ba1a3a60
commit 6633d6367f
18 changed files with 495 additions and 191 deletions

View File

@ -1,3 +1,125 @@
Tue Jun 17 18:35:57 1997 Mike Stump <mrs@cygnus.com>
* except.c (expand_builtin_throw): Add support
-fno-sjlj-exceptions -fPIC exception handling on the SPARC.
Mon Jun 16 01:24:37 1997 Jason Merrill <jason@yorick.cygnus.com>
* repo.c (extract_string): Null-terminate.
* cp-tree.h (TI_SPEC_INFO): New macro.
(CLASSTYPE_TI_SPEC_INFO): New macro.
* pt.c (push_template_decl): Correctly determine # of template parms
for partial specs.
* call.c (compare_ics): Really fix 'this' conversions.
* pt.c (do_decl_instantiation): Don't crash on explicit inst of
non-template fn.
* pt.c (push_template_decl): Complain about mismatch in # of
template parms between a class template and a member template.
Sun Jun 15 02:38:20 1997 Jason Merrill <jason@yorick.cygnus.com>
* method.c (synthesize_method): You can't call
function_cannot_inline_p after finish_function.
* decl.c (finish_function): Turn on flag_inline_functions and turn
off DECL_INLINE before handing a synthesized method to the
backend.
Thu Jun 12 17:35:28 1997 Jason Merrill <jason@yorick.cygnus.com>
* method.c (synthesize_method): Remove July 30 change to never set
DECL_INLINE if at_eof.
Thu Jun 12 15:25:08 1997 Mike Stump <mrs@cygnus.com>
* xref.c (GNU_xref_member): Ensure that the node has a
decl_lang_specific part before checking DECL_FRIEND_P.
Thu Jun 12 12:36:05 1997 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (instantiate_class_template): Diagnose non-class types used
as bases.
Wed Jun 11 17:33:40 1997 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (build_conditional_expr): Use convert_for_initialization
instead of convert_and_check.
Wed Jun 11 12:31:33 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
* parse.y (typespec): Don't pedwarn for typeof.
Tue Jun 10 00:22:09 1997 Jason Merrill <jason@yorick.cygnus.com>
* repo.c (finish_repo): Only check changes if we would write a
repo file.
* call.c (compare_ics): Fix handling of 'this' conversions.
* pt.c (do_decl_instantiation): Support static data too. Rename
from do_function_instantiation.
* cp-tree.h: Adjust.
* parse.y: Adjust.
* repo.c (extract_string): New fn.
(get_base_filename): Use it.
(init_repo): Compare old args with current args.
Mon Jun 9 14:25:30 1997 Mike Stump <mrs@cygnus.com>
* Makefile.in, Make-lang.in: Protect C-ls with a comment
character, idea from Paul Eggert <eggert@twinsun.com>.
Mon Jun 9 01:52:03 1997 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (c_expand_return): Be more persistent in looking for
returned temps.
* cvt.c (build_up_reference): Use NOP_EXPR for switching from
pointer to reference.
* class.c (build_vbase_path): Don't do anything if PATH has no steps.
Sun Jun 8 03:07:05 1997 Jason Merrill <jason@yorick.cygnus.com>
* init.c (build_member_call, build_offset_ref):
Use do_scoped_id instead of do_identifier.
* cvt.c (convert): Remove bogosity.
Sat Jun 7 20:50:17 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
* cvt.c (build_up_reference): Do checks of ARGTYPE and
TARGET_TYPE before trying to use get_binfo.
Fri Jun 6 17:36:39 1997 Jason Merrill <jason@yorick.cygnus.com>
* cvt.c (build_up_reference): Call get_binfo to get access control.
* decl2.c (import_export_decl): If we don't support weaks, leave
statics undefined.
Fri Jun 6 15:55:49 1997 Mike Stump <mrs@cygnus.com>
* except.c (expand_builtin_throw): Add support for machines that
cannot access globals after throw's epilogue when
-fno-sjlj-exceptions is used.
Thu Jun 5 16:28:43 1997 Jason Merrill <jason@yorick.cygnus.com>
* parse.y: 'std::' becomes '::'.
* lex.c (real_yylex): Remove 'namespace' warning.
* init.c (build_member_call): Ignore 'std::'.
(build_offset_ref): Likewise.
* decl2.c (do_using_directive): Ignore 'using namespace std;'.
(do_toplevel_using_decl): Ignore 'using std::whatever'.
* decl.c (push_namespace): Just sorry.
(pop_namespace): Nop.
(init_decl_processing): Declare std namespace.
Tue Jun 3 18:08:23 1997 Jason Merrill <jason@yorick.cygnus.com>
* search.c (push_class_decls): A name which ambiguously refers to

View File

@ -35,7 +35,7 @@
# - making any compiler driver (eg: g++)
# - the compiler proper (eg: cc1plus)
# - define the names for selecting the language in LANGUAGES.
#
# Extra flags to pass to recursive makes.
CXX_FLAGS_TO_PASS = \
"CXX_FOR_BUILD=$(CXX_FOR_BUILD)" \
@ -62,7 +62,7 @@ CXX_LIB2FUNCS = tinfo.o tinfo2.o new.o new1.o new2.o exception.o
CXX_LIB2SRCS = $(srcdir)/cp/new.cc $(srcdir)/cp/new1.cc $(srcdir)/cp/new2.cc \
$(srcdir)/cp/exception.cc $(srcdir)/cp/tinfo.cc \
$(srcdir)/cp/tinfo2.cc $(srcdir)/cp/tinfo.h
#
# Define the names for selecting c++ in LANGUAGES.
# Note that it would be nice to move the dependency on g++
# into the C++ rule, but that needs a little bit of work
@ -124,7 +124,7 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.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
#
# Build hooks:
c++.all.build: g++$(exeext) $(DEMANGLER_PROG)
@ -181,7 +181,7 @@ cplib2.ready: $(GCC_PASSES) $(LIBGCC2_DEPS) stmp-int-hdrs
@if [ -f cplib2.ready ]; then true; else \
touch cplib2.ready; \
fi
#
# Install hooks:
# cc1plus is installed elsewhere as part of $(COMPILERS).
@ -233,7 +233,7 @@ c++.uninstall:
-rm -rf $(bindir)/$(GXX_CROSS_NAME)$(exeext)
-rm -rf $(mandir)/$(GXX_INSTALL_NAME)$(manext)
-rm -rf $(mandir)/$(GXX_CROSS_NAME)$(manext)
#
# Clean hooks:
# A lot of the ancillary files are deleted by the main makefile.
# We just have to delete files specific to us.
@ -248,7 +248,7 @@ c++.distclean:
c++.extraclean:
c++.maintainer-clean:
-rm -f cp/parse.c cp/parse.h
#
# Stage hooks:
# The main makefile has already created stage?/cp.
@ -260,7 +260,7 @@ c++.stage3: stage3-start
-mv cp/*$(objext) stage3/cp
c++.stage4: stage4-start
-mv cp/*$(objext) stage4/cp
#
# Maintenance hooks:
# This target creates the files that can be rebuilt, but go in the

View File

@ -116,7 +116,7 @@ all: all.indirect
####host overrides
####cross overrides
####build overrides
#
# Now figure out from those variables how to compile and link.
all.indirect: Makefile ../cc1plus
@ -153,7 +153,7 @@ INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config
# This tells GNU make version 3 not to export all the variables
# defined in this file into the environment.
.NOEXPORT:
#
# Lists of files for various purposes.
# Language-specific object files for g++
@ -175,7 +175,7 @@ Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure
cd ..; $(SHELL) config.status
native: config.status ../cc1plus
#
# Compiling object files from source files.
# Note that dependencies on obstack.h are not written
@ -248,7 +248,7 @@ error.o : error.c $(CONFIG_H) $(CXX_TREE_H)
errfn.o : errfn.c $(CONFIG_H) $(CXX_TREE_H)
sig.o : sig.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h
repo.o : repo.c $(CONFIG_H) $(CXX_TREE_H)
#
# These exist for maintenance purposes.
# Update the tags table.

View File

@ -5452,15 +5452,23 @@ compare_ics (ics1, ics2)
they were REF_BINDs. */
if (ICS_THIS_FLAG (ics1))
{
ics1 = build_conv (REF_BIND, TREE_TYPE (ics1), main1);
TREE_OPERAND (ics1, 0) = TREE_OPERAND (main1, 0);
main1 = ics1;
tree t = main1;
if (TREE_CODE (t) == PTR_CONV)
t = TREE_OPERAND (t, 0);
t = build1 (IDENTITY_CONV, TREE_TYPE (TREE_TYPE (t)), NULL_TREE);
t = build_conv (REF_BIND, TREE_TYPE (ics1), t);
ICS_STD_RANK (t) = ICS_STD_RANK (main1);
main1 = ics1 = t;
}
if (ICS_THIS_FLAG (ics2))
{
ics2 = build_conv (REF_BIND, TREE_TYPE (ics2), main2);
TREE_OPERAND (ics2, 0) = TREE_OPERAND (main2, 0);
main2 = ics2;
tree t = main2;
if (TREE_CODE (t) == PTR_CONV)
t = TREE_OPERAND (t, 0);
t = build1 (IDENTITY_CONV, TREE_TYPE (TREE_TYPE (t)), NULL_TREE);
t = build_conv (REF_BIND, TREE_TYPE (ics2), t);
ICS_STD_RANK (t) = ICS_STD_RANK (main2);
main2 = ics2 = t;
}
if (ICS_RANK (ics1) > ICS_RANK (ics2))

View File

@ -196,21 +196,28 @@ build_vbase_path (code, type, expr, path, alias_this)
register int changed = 0;
tree last = NULL_TREE, last_virtual = NULL_TREE;
int nonnull = 0;
int fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
int fixed_type_p;
tree null_expr = 0, nonnull_expr;
tree basetype;
tree offset = integer_zero_node;
if (BINFO_INHERITANCE_CHAIN (path) == NULL_TREE)
return build1 (NOP_EXPR, type, expr);
if (nonnull == 0 && (alias_this && flag_this_is_variable <= 0))
nonnull = 1;
#if 0
/* We need additional logic to convert back to the unconverted type
(the static type of the complete object), and then convert back
to the type we want. Until that is done, or until we can
recognize when that is, we cannot do the short cut logic. (mrs) */
fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
#else
/* Do this, until we can undo any previous conversions. See net35.C
for a testcase. */
fixed_type_p = complete_type_p (expr);
#endif
if (!fixed_type_p && TREE_SIDE_EFFECTS (expr))
expr = save_expr (expr);

View File

@ -1078,12 +1078,14 @@ struct lang_decl
#define CLASSTYPE_TEMPLATE_INFO(NODE) (TYPE_LANG_SPECIFIC(NODE)->template_info)
#define TI_TEMPLATE(NODE) (TREE_PURPOSE (NODE))
#define TI_ARGS(NODE) (TREE_VALUE (NODE))
#define TI_SPEC_INFO(NODE) (TREE_CHAIN (NODE))
#define TI_USES_TEMPLATE_PARMS(NODE) TREE_LANG_FLAG_0 (NODE)
#define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
#define DECL_TI_TEMPLATE(NODE) TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE))
#define DECL_TI_ARGS(NODE) TI_ARGS (DECL_TEMPLATE_INFO (NODE))
#define CLASSTYPE_TI_TEMPLATE(NODE) TI_TEMPLATE (CLASSTYPE_TEMPLATE_INFO (NODE))
#define CLASSTYPE_TI_ARGS(NODE) TI_ARGS (CLASSTYPE_TEMPLATE_INFO (NODE))
#define CLASSTYPE_TI_SPEC_INFO(NODE) TI_SPEC_INFO (CLASSTYPE_TEMPLATE_INFO (NODE))
#define DECL_SAVED_TREE(NODE) DECL_MEMFUNC_POINTER_TO (NODE)
#define COMPOUND_STMT_NO_SCOPE(NODE) TREE_LANG_FLAG_0 (NODE)
@ -1515,6 +1517,7 @@ extern tree opaque_type_node, signature_type_node;
/* Array type `(void *)[]' */
extern tree vtbl_type_node;
extern tree delta_type_node;
extern tree std_node;
extern tree long_long_integer_type_node, long_long_unsigned_type_node;
/* For building calls to `delete'. */
@ -2295,7 +2298,7 @@ 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_decl_instantiation PROTO((tree, tree, tree));
extern void do_type_instantiation PROTO((tree, tree));
extern tree instantiate_decl PROTO((tree));
extern tree lookup_nested_type_by_name PROTO((tree, tree));

View File

@ -407,12 +407,23 @@ build_up_reference (type, arg, flags, checkconst)
address, transform all occurrences of the register, into a memory
reference we could win better. */
rval = build_unary_op (ADDR_EXPR, arg, 1);
if (flags & LOOKUP_PROTECT)
rval = convert_pointer_to (target_type, rval);
if ((flags & LOOKUP_PROTECT)
&& TYPE_MAIN_VARIANT (argtype) != TYPE_MAIN_VARIANT (target_type)
&& IS_AGGR_TYPE (argtype)
&& IS_AGGR_TYPE (target_type))
{
/* We go through get_binfo for the access control. */
tree binfo = get_binfo (target_type, argtype, 1);
if (binfo == error_mark_node)
return error_mark_node;
if (binfo == NULL_TREE)
return error_not_base_type (target_type, argtype);
rval = convert_pointer_to_real (binfo, rval);
}
else
rval
= convert_to_pointer_force (build_pointer_type (target_type), rval);
rval = build1 (CONVERT_EXPR, type, rval);
rval = build1 (NOP_EXPR, type, rval);
TREE_CONSTANT (rval) = TREE_CONSTANT (TREE_OPERAND (rval, 0));
return rval;
}
@ -1189,49 +1200,9 @@ convert (type, expr)
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
if (TREE_TYPE (expr) == type)
return expr;
if (TREE_CODE (type) != REFERENCE_TYPE)
{
expr = decay_conversion (expr);
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
Strip such NOP_EXPRs if VALUE is being used in non-lvalue context. */
if (TREE_CODE (expr) == NOP_EXPR
&& TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
expr = TREE_OPERAND (expr, 0);
}
intype = TREE_TYPE (expr);
if (TREE_CODE (type) == REFERENCE_TYPE)
{
expr = build_unary_op (ADDR_EXPR, expr, 0);
if (expr != error_mark_node)
expr = convert (build_pointer_type (TREE_TYPE (type)), expr);
if (expr != error_mark_node)
expr = build_indirect_ref (expr, 0);
return expr;
}
else if (comptypes (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type), 1))
return build_static_cast (type, expr);
if (TYPE_PTR_P (type) && (TREE_CODE (intype) == INTEGER_TYPE
|| TREE_CODE (intype) == ENUMERAL_TYPE))
/* OK */;
else if (TREE_CODE (type) == INTEGER_TYPE && TYPE_PTR_P (intype))
{
}
else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
|| (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
{
if (TREE_READONLY_DECL_P (expr))
expr = decl_constant_value (expr);
return fold (build1 (NOP_EXPR, type, expr));
}
else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
|| (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
if (POINTER_TYPE_P (type) && POINTER_TYPE_P (intype))
{
if (TREE_READONLY_DECL_P (expr))
expr = decl_constant_value (expr);

View File

@ -263,6 +263,9 @@ tree sigtable_entry_type;
/* Array type `vtable_entry_type[]' */
tree vtbl_type_node;
/* namespace std */
tree std_node;
/* In a destructor, the point at which all derived class destroying
has been done, just before any base class destroying will be done. */
@ -1675,6 +1678,13 @@ void
push_namespace (name)
tree name;
{
#if 1
static int warned;
if (! warned)
sorry ("namespace");
warned = 1;
#else
extern tree current_namespace;
tree old_id = get_namespace_id ();
char *buf;
@ -1711,6 +1721,7 @@ push_namespace (name)
sprintf (buf, "%s%s", old_id ? IDENTIFIER_POINTER (old_id) : "",
IDENTIFIER_POINTER (name));
TREE_PURPOSE (current_namespace) = get_identifier (buf);
#endif
}
/* Pop from the scope of the current namespace. */
@ -1718,6 +1729,7 @@ push_namespace (name)
void
pop_namespace ()
{
#if 0
extern tree current_namespace;
tree decls, link;
current_namespace = TREE_CHAIN (current_namespace);
@ -1761,6 +1773,7 @@ pop_namespace ()
/* suspend a level. */
suspend_binding_level ();
#endif
}
/* Subroutines for reverting temporarily to top-level for instantiation
@ -5289,6 +5302,10 @@ init_decl_processing ()
record_builtin_type (RID_MAX, SIGTABLE_PTR_TYPE, sigtable_entry_type);
}
std_node = build_decl (NAMESPACE_DECL, get_identifier ("std"),
void_type_node);
pushdecl (std_node);
#if 0
if (flag_rtti)
{
@ -12030,8 +12047,25 @@ finish_function (lineno, call_poplevel, nested)
/* So we can tell if jump_optimize sets it to 1. */
can_reach_end = 0;
/* Run the optimizers and output the assembler code for this function. */
rest_of_compilation (fndecl);
/* Run the optimizers and output the assembler code for this
function. */
if (DECL_ARTIFICIAL (fndecl))
{
/* Do we really *want* to inline this synthesized method? */
int save_fif = flag_inline_functions;
flag_inline_functions = 1;
/* Turn off DECL_INLINE for the moment so function_cannot_inline_p
will check our size. */
DECL_INLINE (fndecl) = 0;
rest_of_compilation (fndecl);
flag_inline_functions = save_fif;
}
else
rest_of_compilation (fndecl);
if (DECL_SAVED_INSNS (fndecl) && ! TREE_ASM_WRITTEN (fndecl))
{

View File

@ -2616,7 +2616,10 @@ import_export_decl (decl)
supported. */
if (flag_weak)
make_decl_one_only (decl);
/* else leave vars public so multiple defs will break. */
else
/* we can't do anything useful; leave vars for explicit
instantiation. */
DECL_NOT_REALLY_EXTERN (decl) = 0;
}
}
else
@ -3602,6 +3605,12 @@ void
do_toplevel_using_decl (decl)
tree decl;
{
#if 1
if (TREE_CODE (decl) == SCOPE_REF
&& TREE_OPERAND (decl, 0) == std_node)
return;
sorry ("using-declaration");
#else
if (decl == NULL_TREE || decl == error_mark_node)
return;
@ -3619,6 +3628,7 @@ do_toplevel_using_decl (decl)
pushdecl (TREE_VALUE (decl));
decl = TREE_CHAIN (decl);
}
#endif
}
tree
@ -3648,6 +3658,8 @@ void
do_using_directive (namespace)
tree namespace;
{
if (namespace == std_node)
return;
sorry ("using directive");
}

View File

@ -240,9 +240,11 @@ init_exception_processing ()
tree declspecs;
tree d;
/* void vtype () */
tree vtype = build_function_type (void_type_node, void_list_node);
/* void (*)() */
tree PFV = build_pointer_type (build_function_type
(void_type_node, void_list_node));
tree PFV = build_pointer_type (vtype);
/* Arg list for the build_function_type call for set_terminate and
set_unexpected. */
@ -251,9 +253,6 @@ init_exception_processing ()
/* void (*pfvtype (void (*) ()))() */
tree pfvtype = build_function_type (PFV, pfvlist);
/* void vtype () */
tree vtype = build_function_type (void_type_node, void_list_node);
set_terminate_fndecl = auto_function (get_identifier ("set_terminate"),
pfvtype, NOT_BUILT_IN);
set_unexpected_fndecl = auto_function (get_identifier ("set_unexpected"),
@ -290,7 +289,7 @@ init_exception_processing ()
NOT_BUILT_IN, NULL_PTR);
empty_fndecl
= builtin_function ("__empty",
build_function_type (void_type_node, void_list_node),
vtype,
NOT_BUILT_IN, NULL_PTR);
DECL_EXTERNAL (empty_fndecl) = 1;
TREE_PUBLIC (empty_fndecl) = 1;
@ -611,18 +610,18 @@ do_unwind (inner_throw_label)
/* This doesn't work for the flat model sparc, I bet. */
tree fcall;
tree params;
rtx return_val_rtx;
rtx next_pc;
rtx temp;
/* Call to __builtin_return_address. */
params = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
fcall = build_function_call (BuiltinReturnAddress, params);
return_val_rtx = expand_expr (fcall, NULL_RTX, Pmode, 0);
next_pc = expand_expr (fcall, NULL_RTX, Pmode, 0);
/* In the return, the new pc is pc+8, as the value coming in is
really the address of the call insn, not the next insn. */
temp = gen_reg_rtx (Pmode);
emit_move_insn (temp, inner_throw_label);
emit_move_insn (return_val_rtx, plus_constant (temp, -8));
emit_move_insn (next_pc, plus_constant (temp, -8));
emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 31)));
easy_expand_asm ("ret");
easy_expand_asm ("restore");
@ -663,16 +662,16 @@ do_unwind (inner_throw_label)
#if ! defined (TARGET_88000) && ! defined (ARM_FRAME_RTX) && ! defined (SPARC_STACK_ALIGN)
tree fcall;
tree params;
rtx return_val_rtx;
rtx next_pc;
#if 0
/* I would like to do this here, but the move below doesn't seem to work. */
/* Call to __builtin_return_address. */
params = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
fcall = build_function_call (BuiltinReturnAddress, params);
return_val_rtx = expand_expr (fcall, NULL_RTX, Pmode, 0);
next_pc = expand_expr (fcall, NULL_RTX, Pmode, 0);
emit_move_insn (return_val_rtx, inner_throw_label);
emit_move_insn (next_pc, inner_throw_label);
/* So, for now, just pass throw label to stack unwinder. */
#endif
params = tree_cons (NULL_TREE, make_tree (ptr_type_node,
@ -705,12 +704,15 @@ expand_builtin_throw ()
{
tree fcall;
tree params;
rtx return_val_rtx;
rtx handler;
rtx saved_pcnthrow;
rtx next_pc;
rtx gotta_rethrow_it;
rtx gotta_call_terminate;
rtx after_unwind;
rtx top_of_loop;
rtx unwind_first;
tree t;
rtx x;
if (! doing_eh (0))
return;
@ -721,8 +723,11 @@ expand_builtin_throw ()
params = void_list_node;
t = make_call_declarator (get_identifier ("__throw"), params, NULL_TREE,
NULL_TREE);
start_function (decl_tree_cons (NULL_TREE, get_identifier ("static"),
void_list_node),
start_function (decl_tree_cons (NULL_TREE,
get_identifier ("void"),
decl_tree_cons (NULL_TREE,
get_identifier ("static"),
NULL_TREE)),
t, NULL_TREE, 0);
store_parm_decls ();
pushlevel (0);
@ -732,8 +737,6 @@ expand_builtin_throw ()
gotta_rethrow_it = gen_label_rtx ();
gotta_call_terminate = gen_label_rtx ();
top_of_loop = gen_label_rtx ();
unwind_first = gen_label_rtx ();
/* These two can be frontend specific. If wanted, they can go in
expand_throw. */
@ -742,54 +745,108 @@ expand_builtin_throw ()
GET_MODE (DECL_RTL (saved_throw_type)), 0, 0);
emit_jump_insn (gen_beq (gotta_call_terminate));
emit_jump (unwind_first);
emit_label (top_of_loop);
/* search for an exception handler for the saved_pc */
return_val_rtx = do_function_call (FirstExceptionMatch,
tree_cons (NULL_TREE, saved_pc, NULL_TREE),
ptr_type_node);
handler = do_function_call (FirstExceptionMatch,
tree_cons (NULL_TREE, saved_pc,
NULL_TREE),
ptr_type_node);
assemble_external (TREE_OPERAND (FirstExceptionMatch, 0));
/* did we find one? */
emit_cmp_insn (return_val_rtx, const0_rtx, EQ, NULL_RTX,
GET_MODE (return_val_rtx), 0, 0);
emit_cmp_insn (handler, const0_rtx, EQ, NULL_RTX,
GET_MODE (handler), 0, 0);
/* if not, jump to gotta_rethrow_it */
emit_jump_insn (gen_beq (gotta_rethrow_it));
/* we found it, so jump to it */
emit_indirect_jump (return_val_rtx);
{
rtx ret_val, x;
ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
0, hard_frame_pointer_rtx);
/* code to deal with unwinding and looking for it again */
emit_label (gotta_rethrow_it);
/* Set it up so that we continue at the handler. */
emit_move_insn (ret_val, handler);
#ifdef RETURN_ADDR_OFFSET
x = plus_constant (ret_val, -RETURN_ADDR_OFFSET);
if (x != ret_val)
emit_move_insn (ret_val, x);
#endif
expand_null_return ();
}
top_of_loop = gen_label_rtx ();
emit_label (top_of_loop);
#ifdef DONT_ACCESS_GBLS_AFTER_EPILOGUE
if (DONT_ACCESS_GBLS_AFTER_EPILOGUE)
{
saved_pcnthrow = gen_reg_rtx (Pmode);
emit_move_insn (saved_pcnthrow, hard_function_value (ptr_type_node,
NULL_TREE));
}
#endif
/* Call to __builtin_return_address. */
#if defined (ARM_FRAME_RTX) /* was __arm */
/* This should be moved into arm.h:RETURN_ADDR_RTX */
/* This replaces a 'call' to __builtin_return_address */
return_val_rtx = gen_reg_rtx (Pmode);
emit_move_insn (return_val_rtx, gen_rtx (MEM, Pmode, plus_constant (hard_frame_pointer_rtx, -4)));
next_pc = gen_reg_rtx (Pmode);
emit_move_insn (next_pc,
gen_rtx (MEM, Pmode, plus_constant (hard_frame_pointer_rtx, -4)));
#else
params = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
fcall = build_function_call (BuiltinReturnAddress, params);
return_val_rtx = expand_expr (fcall, NULL_RTX, Pmode, 0);
next_pc = expand_expr (fcall, NULL_RTX, Pmode, 0);
#endif
/* Did __builtin_return_address return a valid address? */
emit_cmp_insn (return_val_rtx, const0_rtx, EQ, NULL_RTX,
GET_MODE (return_val_rtx), 0, 0);
emit_cmp_insn (next_pc, const0_rtx, EQ, NULL_RTX,
GET_MODE (next_pc), 0, 0);
emit_jump_insn (gen_beq (gotta_call_terminate));
return_val_rtx = eh_outer_context (return_val_rtx);
next_pc = eh_outer_context (next_pc);
/* Yes it did. */
emit_move_insn (eh_saved_pc_rtx, return_val_rtx);
#ifdef DONT_ACCESS_GBLS_AFTER_EPILOGUE
if (DONT_ACCESS_GBLS_AFTER_EPILOGUE)
{
rtx x;
do_unwind (gen_rtx (LABEL_REF, Pmode, top_of_loop));
emit_jump (top_of_loop);
x = validize_mem (gen_rtx (MEM, Pmode, saved_pcnthrow));
emit_move_insn (validize_mem (gen_rtx (MEM, Pmode, x)),
next_pc);
#ifdef FUNCTION_OUTGOING_VALUE
emit_move_insn (FUNCTION_OUTGOING_VALUE (ptr_type_node, NULL_TREE),
validize_mem (gen_rtx (MEM, Pmode,
plus_constant (saved_pcnthrow,
GET_MODE_SIZE (Pmode)))));
emit_insn (gen_rtx (USE, VOIDmode,
FUNCTION_OUTGOING_VALUE (ptr_type_node, NULL_TREE)));
#endif
}
else
#endif
emit_move_insn (eh_saved_pc_rtx, next_pc);
after_unwind = gen_label_rtx ();
do_unwind (gen_rtx (LABEL_REF, Pmode, after_unwind));
emit_label (after_unwind);
#ifdef DONT_ACCESS_GBLS_AFTER_EPILOGUE
if (DONT_ACCESS_GBLS_AFTER_EPILOGUE)
{
t = make_tree (build_pointer_type (TREE_TYPE (empty_fndecl)),
hard_function_value (ptr_type_node,
NULL_TREE));
t = build_function_call (t, NULL_TREE);
expand_expr (t, const0_rtx, VOIDmode, 0);
}
else
#endif
emit_throw ();
/* no it didn't --> therefore we need to call terminate */
emit_label (gotta_call_terminate);
@ -797,17 +854,37 @@ expand_builtin_throw ()
assemble_external (TREE_OPERAND (Terminate, 0));
{
rtx ret_val, return_val_rtx;
emit_label (unwind_first);
rtx ret_val, x;
/* code to deal with unwinding and looking for it again */
emit_label (gotta_rethrow_it);
ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
0, hard_frame_pointer_rtx);
/* Set it up so that we continue inside, at the top of the loop. */
emit_move_insn (ret_val, gen_rtx (LABEL_REF, Pmode, top_of_loop));
#ifdef RETURN_ADDR_OFFSET
return_val_rtx = plus_constant (ret_val, -RETURN_ADDR_OFFSET);
if (return_val_rtx != ret_val)
emit_move_insn (ret_val, return_val_rtx);
x = plus_constant (ret_val, -RETURN_ADDR_OFFSET);
if (x != ret_val)
emit_move_insn (ret_val, x);
#endif
#ifdef DONT_ACCESS_GBLS_AFTER_EPILOGUE
if (DONT_ACCESS_GBLS_AFTER_EPILOGUE)
{
rtx x = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode,
"__eh_pcnthrow"),
NULL_RTX, 1,
Pmode, 0);
/* This is to get a version of throw that will throw properly. */
emit_move_insn (validize_mem (gen_rtx (MEM, Pmode,
plus_constant (x, GET_MODE_SIZE (Pmode)))),
throw_libfunc);
#ifdef FUNCTION_OUTGOING_VALUE
emit_move_insn (FUNCTION_OUTGOING_VALUE (ptr_type_node, NULL_TREE),
x);
emit_insn (gen_rtx (USE, VOIDmode, FUNCTION_OUTGOING_VALUE (ptr_type_node, NULL_TREE)));
#endif
}
#endif
/* Fall into epilogue to unwind prologue. */

View File

@ -1675,6 +1675,10 @@ build_member_call (type, name, parmlist)
int dont_use_this = 0;
tree basetype_path, decl;
if (type == std_node)
return build_x_function_call (do_scoped_id (name, 0), parmlist,
current_class_ref);
if (TREE_CODE (method_name) == BIT_NOT_EXPR)
{
method_name = TREE_OPERAND (method_name, 0);
@ -1796,6 +1800,9 @@ build_offset_ref (type, name)
tree basebinfo = NULL_TREE;
int dtor = 0;
if (type == std_node)
return do_scoped_id (name, 0);
if (processing_template_decl)
return build_min_nt (SCOPE_REF, type, name);

View File

@ -3005,14 +3005,6 @@ real_yylex ()
token_buffer[0] = '^';
token_buffer[1] = 0;
}
else if (ptr->token == NAMESPACE)
{
static int warned;
if (! warned)
warning ("namespaces are mostly broken in this version of g++");
warned = 1;
}
value = (int) ptr->token;
}

View File

@ -2052,21 +2052,6 @@ synthesize_method (fndecl)
finish_function (lineno, 0, nested);
/* Do we really *want* to inline this function? */
if (DECL_INLINE (fndecl))
{
/* Turn off DECL_INLINE for the moment so function_cannot_inline_p
will check our size. */
DECL_INLINE (fndecl) = 0;
/* We say !at_eof because at the end of the file some of the rtl
for fndecl may have been allocated on the temporary obstack.
(The function_obstack is the temporary one if we're not in a
function). */
if ((! at_eof) && function_cannot_inline_p (fndecl) == 0)
DECL_INLINE (fndecl) = 1;
}
extract_interface_info ();
if (! context)
pop_from_top_level ();

View File

@ -390,7 +390,11 @@ extdef:
| using_decl ';'
{ do_toplevel_using_decl ($1); }
| USING NAMESPACE any_id ';'
{ do_using_directive ($3); }
{
if (TREE_CODE ($3) == IDENTIFIER_NODE)
$3 = lastiddecl;
do_using_directive ($3);
}
| extension extdef
{ pedantic = $<itype>1; }
;
@ -814,20 +818,20 @@ explicit_instantiation:
{ do_type_instantiation ($3, NULL_TREE); }
| TEMPLATE typed_declspecs declarator
{ tree specs = strip_attrs ($2.t);
do_function_instantiation (specs, $3, NULL_TREE); }
do_decl_instantiation (specs, $3, NULL_TREE); }
| TEMPLATE notype_declarator
{ do_function_instantiation (NULL_TREE, $2, NULL_TREE); }
{ do_decl_instantiation (NULL_TREE, $2, NULL_TREE); }
| TEMPLATE constructor_declarator
{ do_function_instantiation (NULL_TREE, $2, NULL_TREE); }
{ do_decl_instantiation (NULL_TREE, $2, NULL_TREE); }
| SCSPEC TEMPLATE aggr template_type
{ do_type_instantiation ($4, $1); }
| SCSPEC TEMPLATE typed_declspecs declarator
{ tree specs = strip_attrs ($3.t);
do_function_instantiation (specs, $4, $1); }
do_decl_instantiation (specs, $4, $1); }
| SCSPEC TEMPLATE notype_declarator
{ do_function_instantiation (NULL_TREE, $3, $1); }
{ do_decl_instantiation (NULL_TREE, $3, $1); }
| SCSPEC TEMPLATE constructor_declarator
{ do_function_instantiation (NULL_TREE, $3, $1); }
{ do_decl_instantiation (NULL_TREE, $3, $1); }
;
/* The TYPENAME expansions are to deal with use of a template class name as
@ -1831,13 +1835,9 @@ typespec:
{ $$.t = $1; $$.new_type_flag = 0; }
| TYPEOF '(' expr ')'
{ $$.t = TREE_TYPE ($3);
$$.new_type_flag = 0;
if (pedantic && !in_system_header)
pedwarn ("ANSI C++ forbids `typeof'"); }
$$.new_type_flag = 0; }
| TYPEOF '(' type_id ')'
{ $$.t = groktypename ($3.t);
if (pedantic && !in_system_header)
pedwarn ("ANSI C++ forbids `typeof'");
$$.new_type_flag = 0; }
| SIGOF '(' expr ')'
{ tree type = TREE_TYPE ($3);
@ -3051,7 +3051,15 @@ nested_name_specifier_1:
got_scope = $$ = TREE_TYPE ($$);
}
| NSNAME SCOPE
{ got_scope = $$ = $1; }
{
if (TREE_CODE ($$) == IDENTIFIER_NODE)
$$ = lastiddecl;
if (TREE_CODE ($$) == NAMESPACE_DECL
&& DECL_NAME ($$) == get_identifier ("std"))
got_scope = void_type_node;
else
got_scope = $$;
}
| template_type SCOPE
{ got_scope = $$ = complete_type (TREE_TYPE ($1)); }
/* These break 'const i;'

View File

@ -274,9 +274,9 @@ push_template_decl (decl)
return;
}
DECL_TEMPLATE_SPECIALIZATIONS (maintmpl) = perm_tree_cons
(mainargs, TREE_VALUE (current_template_parms),
DECL_TEMPLATE_SPECIALIZATIONS (maintmpl));
DECL_TEMPLATE_SPECIALIZATIONS (maintmpl) = CLASSTYPE_TI_SPEC_INFO (type)
= perm_tree_cons (mainargs, TREE_VALUE (current_template_parms),
DECL_TEMPLATE_SPECIALIZATIONS (maintmpl));
TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type;
return;
}
@ -291,6 +291,8 @@ push_template_decl (decl)
}
else
{
tree t;
if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctx))
cp_error ("must specialize `%#T' before defining member `%#D'",
ctx, decl);
@ -303,6 +305,18 @@ push_template_decl (decl)
}
else
tmpl = DECL_TI_TEMPLATE (decl);
if (CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx))
t = TREE_VALUE (CLASSTYPE_TI_SPEC_INFO (ctx));
else
t = DECL_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (ctx));
if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (args))
{
cp_error ("got %d template parameters for `%#D'",
TREE_VEC_LENGTH (args), decl);
cp_error (" but `%#T' has %d", ctx, TREE_VEC_LENGTH (t));
}
}
DECL_TEMPLATE_RESULT (tmpl) = decl;
@ -1183,8 +1197,13 @@ instantiate_class_template (type)
TREE_VEC_LENGTH (args), NULL_TREE);
BINFO_INHERITANCE_CHAIN (elt) = binfo;
if (! uses_template_parms (type)
&& TYPE_SIZE (complete_type (TREE_TYPE (elt))) == NULL_TREE)
if (! IS_AGGR_TYPE (TREE_TYPE (elt)))
cp_error
("base type `%T' of `%T' fails to be a struct or class type",
TREE_TYPE (elt), type);
else if (! uses_template_parms (type)
&& (TYPE_SIZE (complete_type (TREE_TYPE (elt)))
== NULL_TREE))
cp_error ("base class `%T' of `%T' has incomplete type",
TREE_TYPE (elt), type);
}
@ -1752,11 +1771,13 @@ tsubst (t, args, nargs, in_decl)
return t;
TREE_TYPE (t) = complete_type (type);
BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (type);
BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (type);
if (TYPE_BINFO_BASETYPES (type) != NULL_TREE)
BINFO_BASETYPES (t) = copy_node (TYPE_BINFO_BASETYPES (type));
if (IS_AGGR_TYPE (type))
{
BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (type);
BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (type);
if (TYPE_BINFO_BASETYPES (type) != NULL_TREE)
BINFO_BASETYPES (t) = copy_node (TYPE_BINFO_BASETYPES (type));
}
return t;
}
{
@ -3153,7 +3174,7 @@ most_specialized_class (specs, mainargs)
/* called from the parser. */
void
do_function_instantiation (declspecs, declarator, storage)
do_decl_instantiation (declspecs, declarator, storage)
tree declspecs, declarator, storage;
{
tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL_TREE);
@ -3169,7 +3190,18 @@ do_function_instantiation (declspecs, declarator, storage)
}
/* If we've already seen this template instance, use it. */
if (DECL_FUNCTION_MEMBER_P (decl))
if (TREE_CODE (decl) == VAR_DECL)
{
result = lookup_field (DECL_CONTEXT (decl), DECL_NAME (decl), 0, 0);
if (result && TREE_CODE (result) != VAR_DECL)
result = NULL_TREE;
}
else if (TREE_CODE (decl) != FUNCTION_DECL)
{
cp_error ("explicit instantiation of `%#D'", decl);
return;
}
else if (DECL_FUNCTION_MEMBER_P (decl))
{
if (DECL_TEMPLATE_INSTANTIATION (decl))
result = decl;
@ -3220,6 +3252,12 @@ do_function_instantiation (declspecs, declarator, storage)
return;
}
if (! DECL_TEMPLATE_INFO (result))
{
cp_pedwarn ("explicit instantiation of non-template `%#D'", result);
return;
}
if (flag_external_templates)
return;

View File

@ -41,6 +41,8 @@ static tree original_repo;
static char *repo_name;
static FILE *repo_file;
static char *old_args, *old_dir, *old_main;
extern int flag_use_repository;
extern int errorcount, sorrycount;
extern struct obstack temporary_obstack;
@ -198,35 +200,55 @@ save_string (s, len)
return obstack_copy0 (&temporary_obstack, s, len);
}
/* Parse a reasonable subset of shell quoting syntax. */
static char *
extract_string (pp)
char **pp;
{
char *p = *pp;
int backquote = 0;
int inside = 0;
for (;;)
{
char c = *p;
if (c == '\0')
break;
++p;
if (backquote)
obstack_1grow (&temporary_obstack, c);
else if (! inside && c == ' ')
break;
else if (! inside && c == '\\')
backquote = 1;
else if (c == '\'')
inside = !inside;
else
obstack_1grow (&temporary_obstack, c);
}
obstack_1grow (&temporary_obstack, '\0');
*pp = p;
return obstack_finish (&temporary_obstack);
}
static char *
get_base_filename (filename)
char *filename;
{
char *p = getenv ("COLLECT_GCC_OPTIONS");
char *output = 0;
char *output = NULL;
int compiling = 0;
if (p)
while (*p)
{
char *q = p;
while (*q && *q != ' ') q++;
if (*p == '-' && p[1] == 'o')
{
p += 2;
if (p == q)
{
p++; q++;
if (*q)
while (*q && *q != ' ') q++;
}
while (p && *p)
{
char *q = extract_string (&p);
output = save_string (p, q - p);
}
else if (*p == '-' && p[1] == 'c')
compiling = 1;
if (*q) q++;
p = q;
if (strcmp (q, "-o") == 0)
output = extract_string (&p);
else if (strcmp (q, "-c") == 0)
compiling = 1;
}
if (compiling && output)
@ -301,8 +323,16 @@ init_repo (filename)
switch (buf[0])
{
case 'A':
old_args = obstack_copy0 (&permanent_obstack, buf + 2,
strlen (buf + 2));
break;
case 'D':
old_dir = obstack_copy0 (&permanent_obstack, buf + 2,
strlen (buf + 2));
break;
case 'M':
old_main = obstack_copy0 (&permanent_obstack, buf + 2,
strlen (buf + 2));
break;
case 'C':
case 'O':
@ -350,6 +380,7 @@ finish_repo ()
tree t;
char *p;
int repo_changed = 0;
char *dir, *args;
if (! flag_use_repository)
return;
@ -382,6 +413,16 @@ finish_repo ()
}
}
dir = getpwd ();
args = getenv ("COLLECT_GCC_OPTIONS");
if (! repo_changed && pending_repo)
if (strcmp (old_main, main_input_filename) != 0
|| strcmp (old_dir, dir) != 0
|| (args == NULL) != (old_args == NULL)
|| strcmp (old_args, args) != 0)
repo_changed = 1;
if (! repo_changed || errorcount || sorrycount)
goto out;
@ -391,13 +432,9 @@ finish_repo ()
goto out;
fprintf (repo_file, "M %s\n", main_input_filename);
p = getpwd ();
fprintf (repo_file, "D %s\n", p);
p = getenv ("COLLECT_GCC_OPTIONS");
if (p != 0)
fprintf (repo_file, "A %s\n", p);
fprintf (repo_file, "D %s\n", dir);
if (args)
fprintf (repo_file, "A %s\n", args);
for (t = pending_repo; t; t = TREE_CHAIN (t))
{

View File

@ -5082,9 +5082,11 @@ build_conditional_expr (ifexp, op1, op2)
result_type = build_ptrmemfunc_type (result_type);
if (result_type != TREE_TYPE (op1))
op1 = convert_and_check (result_type, op1);
op1 = convert_for_initialization
(NULL_TREE, result_type, op1, LOOKUP_NORMAL, "converting", NULL_TREE, 0);
if (result_type != TREE_TYPE (op2))
op2 = convert_and_check (result_type, op2);
op2 = convert_for_initialization
(NULL_TREE, result_type, op2, LOOKUP_NORMAL, "converting", NULL_TREE, 0);
if (TREE_CONSTANT (ifexp))
return integer_zerop (ifexp) ? op2 : op1;
@ -7221,7 +7223,8 @@ c_expand_return (retval)
if (TREE_CODE (whats_returned) == ADDR_EXPR)
whats_returned = TREE_OPERAND (whats_returned, 0);
}
if (TREE_CODE (whats_returned) == CONVERT_EXPR)
while (TREE_CODE (whats_returned) == CONVERT_EXPR
|| TREE_CODE (whats_returned) == NOP_EXPR)
whats_returned = TREE_OPERAND (whats_returned, 0);
if (TREE_CODE (whats_returned) == ADDR_EXPR)
{

View File

@ -645,7 +645,7 @@ GNU_xref_member(cls, fld)
filename(xf), fld->decl.linenum, d, bufa, prot,
(TREE_CODE (fld) == FUNCTION_DECL ? 0 : 1),
(DECL_INLINE (fld) ? 1 : 0),
(DECL_FRIEND_P(fld) ? 1 : 0),
(DECL_LANG_SPECIFIC(fld) && DECL_FRIEND_P(fld) ? 1 : 0),
(DECL_VINDEX(fld) ? 1 : 0),
(TREE_STATIC(fld) ? 1 : 0),
pure, confg);