parent
59ba1a3a60
commit
6633d6367f
122
gcc/cp/ChangeLog
122
gcc/cp/ChangeLog
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
59
gcc/cp/cvt.c
59
gcc/cp/cvt.c
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
167
gcc/cp/except.c
167
gcc/cp/except.c
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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;'
|
||||
|
|
62
gcc/cp/pt.c
62
gcc/cp/pt.c
|
@ -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;
|
||||
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue