parent
c7a7ac465e
commit
db5ae43ff2
502
gcc/cp/ChangeLog
502
gcc/cp/ChangeLog
|
@ -1,3 +1,8 @@
|
|||
Mon Nov 28 16:44:41 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* Makefile.in: Make is easier to decide where parse.[ch] will be
|
||||
built.
|
||||
|
||||
Thu Nov 17 20:11:24 1994 Doug Evans <dje@cygnus.com>
|
||||
|
||||
* cp/Make-lang.in (CXX_INSTALL_NAME) Use program_transform_name.
|
||||
|
@ -12,33 +17,236 @@ Thu Nov 3 18:48:19 1994 Paul Eggert <eggert@twinsun.com>
|
|||
* Makefile.in (spew.o, lex.o, pt.o):
|
||||
Depend on $(srcdir)/parse.h, not parse.h.
|
||||
|
||||
Sat Oct 29 07:18:52 1994 Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
|
||||
Mon Nov 28 13:53:03 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* g++.c (main): Cast arg to bzero to avoid warning.
|
||||
* parse.y (THROW): Fix precedence of throw expressions.
|
||||
|
||||
Mon Nov 28 13:15:16 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* typeck.c (build_unary_op): Allow promotions from bool to int on
|
||||
unary ~.
|
||||
|
||||
Sun Nov 27 00:16:21 1994 Jason Merrill <jason@phydeaux.cygnus.com>
|
||||
|
||||
* method.c (build_overload_name): Use DECL_ASSEMBLER_NAME for
|
||||
classes when appropriate.
|
||||
(build_overload_nested_name): When dealing with a function context,
|
||||
use ASM_FORMAT_PRIVATE_NAME to tweak the name of the function to
|
||||
avoid conflicts between local classes of the same name.
|
||||
|
||||
Wed Nov 23 17:59:42 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* gxx.gperf, parse.y, lex.h, hash.h, lex.c (init_lex), delc.c
|
||||
(duplicate_decls, grokdeclarator), cp-tree.h: Add support for
|
||||
`explicit'.
|
||||
* cvt.c (convert_to_reference, cp_convert, build_type_conversion_1,
|
||||
build_type_conversion): Use LOOKUP_ONLYCONVERTING in
|
||||
build_method_calls so that non-converting constructors are not used.
|
||||
* call.c (build_method_call): If we shouldn't use a non-converting
|
||||
constructor, then don't.
|
||||
|
||||
Wed Nov 23 14:46:56 1994 Jason Merrill <jason@phydeaux.cygnus.com>
|
||||
|
||||
* call.c (build_method_call): Don't try to synthesize methods yet.
|
||||
|
||||
Tue Nov 22 12:45:21 1994 Jason Merrill <jason@phydeaux.cygnus.com>
|
||||
|
||||
* pt.c (push_template_decls): Create CONST_DECLs for template
|
||||
constant parameters, not VAR_DECLs.
|
||||
|
||||
Sat Nov 19 15:28:31 1994 Jim Wilson (wilson@chestnut.cygnus.com)
|
||||
|
||||
* typeck.c (build_binary_op_nodefault): Can shorten shift only if
|
||||
shift count is less than size in bits of arg0.
|
||||
|
||||
Thu Nov 17 15:30:50 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* gxx.gperf, hash.h, lex.c (init_lex, real_yylex), parse.y: Add new
|
||||
ANSI keywords and, and_eq, bitand, bitor, explicit, namespace, not,
|
||||
not_eq, or, or_eq, typename, using, xor, xor_eq to g++. Still need
|
||||
to add support for explicit, namespace, typename, and using, support
|
||||
for the rest is already in.
|
||||
|
||||
Thu Nov 17 10:56:50 1994 Jason Merrill <jason@phydeaux.cygnus.com>
|
||||
|
||||
* typeck2.c (build_m_component_ref): Check the basetype of the
|
||||
member pointer against the main variant of the object type.
|
||||
|
||||
Mon Nov 14 14:21:52 1994 Jason Merrill <jason@phydeaux.cygnus.com>
|
||||
|
||||
* cvt.c (convert_to_reference): Make sure that the original expr
|
||||
gets its type back when converting a reference.
|
||||
|
||||
* method.c (build_overload_name): Clear numeric_outputed_need_bar here.
|
||||
(build_decl_overload): Instead of here.
|
||||
|
||||
Tue Nov 8 17:11:24 1994 Jason Merrill <jason@phydeaux.cygnus.com>
|
||||
|
||||
* cvt.c (cp_convert): Don't build a TARGET_EXPR if we're not in a
|
||||
function.
|
||||
|
||||
* typeck.c (convert_for_initialization): Handle initialization from
|
||||
a TARGET_EXPR.
|
||||
|
||||
Sun Nov 6 01:34:24 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* pt.c (lookup_nested_type_by_name): Fix list-walking logic.
|
||||
(tsubst): When replacing a TEMPLATE_TYPE_PARM, propagate
|
||||
TYPE_READONLY and TYPE_VOLATILE from the argument.
|
||||
(unify): When unifying with a TEMPLATE_TYPE_PARM, remove cv-quals
|
||||
present in parm from arg.
|
||||
(type_unification): Strip REFERENCE_TYPE from the argument type.
|
||||
(unify): Don't strip REFERENCE_TYPE from the argument type.
|
||||
|
||||
Sat Nov 5 22:42:15 1994 Greg McGary (gkm@magilla.cichlid.com)
|
||||
|
||||
* pt.c (do_type_instantiation): Check to see if there's a
|
||||
IDENTIFIER_TEMPLATE on a class before calling
|
||||
instantiate_member_templates().
|
||||
|
||||
Fri Nov 4 19:04:18 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* gc.c (get_bad_cast_node): New routine to support compile time
|
||||
throws of bad_cast.
|
||||
* gc.c (build_dynamic_cast): Support throwing of bad_cast at compile
|
||||
time.
|
||||
|
||||
Fri Nov 4 11:12:00 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* except.c: Add hppa support.
|
||||
|
||||
Fri Nov 4 10:50:50 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* except.c: Add rs6000 support.
|
||||
|
||||
Thu Nov 3 14:24:23 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* except.c (do_unwind): Add i[34]86 support.
|
||||
|
||||
Thu Nov 3 00:10:46 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* pt.c (do_pending_expansions): Unset TREE_PUBLIC on implicit
|
||||
instantiations.
|
||||
|
||||
Wed Nov 2 15:08:24 1994 Kung Hsu (kung@mexican.cygnus.com)
|
||||
|
||||
* decl.c (finish_function): emit types used in method parameters
|
||||
into symbol table.
|
||||
|
||||
Wed Nov 2 15:05:47 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* pt.c (process_template_parm): Allow pointer to member function
|
||||
template parameter types.
|
||||
(uses_template_parms): Handle pointer to member function
|
||||
CONSTRUCTORs.
|
||||
|
||||
* g++.c (main): Cast first argument of bzero to (char *).
|
||||
Pass -lstdc++ instead of -lg++ unless we are invoked as 'g++'.
|
||||
|
||||
Mon Oct 31 14:50:48 1994 Kung Hsu (kung@mexican.cygnus.com)
|
||||
|
||||
* gc.c (build_dynamic_cast): rewrite to make it work.
|
||||
* class.c (finish_vtbls): build more vtables if flag_rtti is on.
|
||||
* class.c (modify_all_direct_vtables): ditto.
|
||||
* init.c (expand_direct_vtbls_init): expand more vtables if
|
||||
flag_rtti is on.
|
||||
* decl.c (init_type_desc): add default return.
|
||||
|
||||
Tue Oct 25 17:13:09 1994 Kung Hsu (kung@mexican.cygnus.com)
|
||||
|
||||
* tree.c (debug_binfo): get rid of the initial size entry of
|
||||
vtable.
|
||||
* cp-tree.h: change flag_dossier to flag rtti, define type
|
||||
descriptor type nodes.
|
||||
* decl.c (init_type_desc): new function to initialize type
|
||||
descriptor type nodes.
|
||||
* decl.c (record_builtin_type): change flag_dossier to flag_rtti.
|
||||
* lex.c (init_lex): ditto.
|
||||
* decl.c : change variable flag_dossier to flag_rtti.
|
||||
* decl.c (duplicate_decls): get rid initial size entry of vtable.
|
||||
* decl.c (hack_incomplete_structures): take out assert 164.
|
||||
* search.c (get_abstract_virtuals_1): ditto.
|
||||
* search.c (dfs_init_vbase_pointers): change CLASSTYPE_DOSSIER to
|
||||
CLASSTYPE_RTTI.
|
||||
* parse.y: ditto.
|
||||
* class.c (prepare_fresh_vtable): for virtual bases, get right
|
||||
offset.
|
||||
* class.c (add_virtual_function): change flag_dossier to
|
||||
flag_rtti.
|
||||
* class.c (modify_one_vtable): modify the right rtti entry.
|
||||
* class.c (override_one_vtable): get rid of size entry.
|
||||
* class.c (finish_struct): change flag_dossier to flag_rtti, and
|
||||
build extra vtables, build type descriptors for polymorphic
|
||||
classes.
|
||||
* gc.c (build_headof): make headof() works correctly with new
|
||||
rtti.
|
||||
* gc.c (build_typeid): make this function work with new rtti.
|
||||
* gc.c (get_typeid): make this function work with new rtti.
|
||||
* gc.c (build_bltn_desc): new function for new rtti.
|
||||
* gc.c (build_user_desc): ditto.
|
||||
* gc.c (build_class_desc): ditto.
|
||||
* gc.c (build_ptr_desc): ditto.
|
||||
* gc.c (build_attr_desc): ditto.
|
||||
* gc.c (build_func_desc): ditto.
|
||||
* gc.c (build_ptmf_desc): ditto.
|
||||
* gc.c (build_ptmd_desc): ditto.
|
||||
* gc.c (build_t_desc): ditto.
|
||||
* gc.c : comment out old build_t_desc, build_i_desc, build_m_desc.
|
||||
|
||||
Tue Oct 25 13:37:41 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* call.c (convert_harshness): Check for TREE_UNSIGNED differences
|
||||
after checking for integral conversions.
|
||||
|
||||
Sun Oct 23 13:19:55 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* decl2.c: Declare flag_access_control.
|
||||
(struct lang_f_options): Add access-control.
|
||||
* expr.c (cplus_expand_expr, NEW_EXPR): Unset flag_access_control
|
||||
for the call to expand_aggr_init to copy the object out of the
|
||||
pcc_struct_return slot.
|
||||
* search.c (compute_access): if (!flag_access_control) return
|
||||
access_public.
|
||||
* decl2.c: Declare flag_access_control.
|
||||
(struct lang_f_options): Add access-control.
|
||||
* expr.c (cplus_expand_expr, NEW_EXPR): Unset flag_access_control
|
||||
for the call to expand_aggr_init to copy the object out of the
|
||||
pcc_struct_return slot.
|
||||
* search.c (compute_access): if (!flag_access_control) return
|
||||
access_public.
|
||||
|
||||
Fri Oct 21 00:32:54 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* decl.c (init_decl_processing): Use __pure_virtual for abort_fndecl
|
||||
instead of abort, since the OSF/1 dynamic linker doesn't like to see
|
||||
relocation entries for abort.
|
||||
* lex.c (cons_up_default_function): Don't try to defer method
|
||||
synthesis now.
|
||||
|
||||
* tree.c (array_type_nelts_total): Use sizetype, not
|
||||
integer_type_node.
|
||||
(array_type_nelts_top): Ditto.
|
||||
* decl.c (init_decl_processing): Use __pure_virtual for abort_fndecl
|
||||
instead of abort, since the OSF/1 dynamic linker doesn't like to see
|
||||
relocation entries for abort.
|
||||
|
||||
* tree.c (array_type_nelts_total): Use sizetype, not
|
||||
integer_type_node.
|
||||
(array_type_nelts_top): Ditto.
|
||||
|
||||
Thu Oct 20 15:48:27 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* decl.c (grokdeclarator): Added handling for catch parameters
|
||||
(CATCHPARM).
|
||||
* except.c (expand_start_catch_block): Use the new CATCHPARM context
|
||||
instead of NORMAL.
|
||||
* except.c (expand_throw): Don't let convert_to_reference complain
|
||||
about what we are doing.
|
||||
|
||||
Thu Oct 20 12:55:24 1994 Jim Wilson (wilson@cygnus.com)
|
||||
|
||||
* method.c (emit_thunk): Call instantiate_virtual_regs.
|
||||
|
||||
Wed Oct 19 14:15:33 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* except.c (expand_exception_blocks): Make sure throw code doesn't
|
||||
get put in function that won't be output.
|
||||
|
||||
Mon Oct 17 18:03:15 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* decl.c (init_decl_processing): Make alloca a builtin.
|
||||
* decl.c (init_decl_processing): Make alloca a builtin.
|
||||
|
||||
Thu Oct 27 21:10:25 1994 Craig Burley (craig@burley)
|
||||
|
||||
* g++.c (main): Only decrement "added" and set "library" to
|
||||
NULL when "library" != NULL (just like 940829 fix).
|
||||
|
||||
Mon Oct 17 15:56:11 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
|
@ -51,47 +259,74 @@ Fri Oct 14 18:54:48 1994 Mike Stump <mrs@cygnus.com>
|
|||
* class.c (modify_one_vtable): Since the DECL_CONTEXT of fndecl can
|
||||
be set just below, use current_fndecl instead.
|
||||
|
||||
Fri Oct 14 15:12:22 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* init.c (expand_aggr_vbase_init_1): Don't call expand_aggr_init_1
|
||||
with LOOKUP_SPECULATIVELY.
|
||||
(expand_default_init): Abort if build_method_call returns NULL_TREE.
|
||||
|
||||
* typeck.c (build_modify_expr): Don't just build a MODIFY_EXPR if
|
||||
the rhs is a TARGET_EXPR.
|
||||
|
||||
* parse.y (left_curly): Anonymous types are not affected by #pragma
|
||||
interface/implementation.
|
||||
|
||||
* method.c (synthesize_method): Don't call setup_vtbl_ptr for the
|
||||
default constructor if it isn't needed.
|
||||
|
||||
* lex.c (cons_up_default_function): Do synthesize methods for
|
||||
anonymous types if necessary.
|
||||
|
||||
Thu Oct 13 17:44:55 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* method.c (build_decl_overload): Set numeric_outputed_need_bar to 0.
|
||||
* method.c (build_decl_overload): Set numeric_outputed_need_bar to 0.
|
||||
|
||||
Wed Oct 12 13:27:57 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* lex.c (real_yylex): Use HOST_BITS_PER_WIDE_INT to determine the
|
||||
bitmask for lexing character constants.
|
||||
* typeck.c (build_modify_expr): Understand how to copy an aggregate.
|
||||
|
||||
* call.c (build_method_call): Disable code that tries to do tricky
|
||||
stuff with a default parameter that is a constructor call, but
|
||||
actually does other tricky stuff that breaks things.
|
||||
* init.c (expand_default_init): Ditto. Also remove some of the
|
||||
crufty code that assumes methods will not be synthesized properly.
|
||||
|
||||
* lex.c (cons_up_default_function): If the containing type has no
|
||||
name, these functions should never need to be called, so just
|
||||
declare them.
|
||||
|
||||
* lex.c (real_yylex): Use HOST_BITS_PER_WIDE_INT to determine the
|
||||
bitmask for lexing character constants.
|
||||
|
||||
* call.c (build_method_call): Disable code that tries to do tricky
|
||||
stuff with a default parameter that is a constructor call, but
|
||||
actually does other tricky stuff that breaks things.
|
||||
|
||||
Wed Oct 12 16:14:01 1994 Benoit Belley <belley@cae.ca>
|
||||
|
||||
* decl.c (finish_enum): Disable code which forces enums to be signed,
|
||||
since this conflicts with their use as bitfields. type_promotes_to
|
||||
handles promotion of enums of underlying unsigned types to signed
|
||||
integer types.
|
||||
* decl.c (finish_enum): Disable code which forces enums to be signed,
|
||||
since this conflicts with their use as bitfields. type_promotes_to
|
||||
handles promotion of enums of underlying unsigned types to signed
|
||||
integer types.
|
||||
|
||||
Wed Oct 12 13:24:03 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* cvt.c (type_promotes_to): Also promote enums to long if
|
||||
appropriate.
|
||||
* cvt.c (type_promotes_to): Also promote enums to long if
|
||||
appropriate.
|
||||
|
||||
* typeck.c (default_conversion): Don't expect type_promotes_to to
|
||||
return a main variant.
|
||||
* typeck.c (default_conversion): Don't expect type_promotes_to to
|
||||
return a main variant.
|
||||
|
||||
Wed Oct 12 12:19:45 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* call.c (build_scoped_method_call): Don't lose side effects in the
|
||||
object expression when calling a non-existent destructor.
|
||||
* call.c (build_scoped_method_call): Don't lose side effects in the
|
||||
object expression when calling a non-existent destructor.
|
||||
|
||||
Fri Sep 2 19:05:21 1994 Rohan Lenard (rjl@iassf.easams.com.au)
|
||||
|
||||
* call.c (build_scoped_method_call): Remove erroneous error message
|
||||
when destructor call is written as a scoped call.
|
||||
* call.c (build_scoped_method_call): Remove erroneous error message
|
||||
when destructor call is written as a scoped call.
|
||||
|
||||
Tue Oct 11 23:48:31 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* various: Cast pointer arguments to bzero and bcopy to char *.
|
||||
|
||||
* various: Cast pointer arguments to bzero and bcopy to char *.
|
||||
|
||||
Tue Oct 11 19:34:32 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
|
@ -101,61 +336,172 @@ Tue Oct 11 19:34:32 1994 Mike Stump <mrs@cygnus.com>
|
|||
offset to put into the vtable for the this parameter, make sure we
|
||||
don't offset from a parent of the DECL_CONTEXT of the function.
|
||||
|
||||
Tue Oct 11 16:10:52 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* pt.c (do_function_instantiation): Set DECL_EXTERNAL and
|
||||
TREE_STATIC when setting DECL_INTERFACE_KNOWN.
|
||||
(do_type_instantiation): Ditto.
|
||||
|
||||
* lex.c (cons_up_default_function): Set DECL_INTERFACE_KNOWN,
|
||||
DECL_EXTERNAL and TREE_STATIC as appropriate.
|
||||
|
||||
* decl2.c (finish_file): Also synthesize methods that don't have
|
||||
DECL_EXTERNAL set. Set interface_unknown before doing so.
|
||||
|
||||
* decl.c (start_function): If DECL_INTERFACE_KNOWN is set on the
|
||||
function decl, don't muck with TREE_PUBLIC and DECL_EXTERNAL.
|
||||
|
||||
Mon Oct 10 00:56:53 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* lex.c (cons_up_default_function): Mark methods in a template class
|
||||
as template instances. Store the values of interface_unknown and
|
||||
interface_only for do_pending_inlines.
|
||||
(do_pending_inlines): Use them.
|
||||
* lex.c (cons_up_default_function): Mark methods in a template class
|
||||
as template instances. Store the values of interface_unknown and
|
||||
interface_only for do_pending_inlines.
|
||||
(do_pending_inlines): Use them.
|
||||
|
||||
* decl2.c (finish_file): If we haven't seen a definition of a
|
||||
function declared static, make the decl non-PUBLIC so compile_file
|
||||
can give an error.
|
||||
|
||||
Sun Oct 9 02:42:29 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* method.c (do_build_copy_constructor): Handle anonymous unions.
|
||||
(do_build_assign_ref): Ditto.
|
||||
(largest_union_member): Move from lex.c.
|
||||
* method.c (do_build_copy_constructor): Handle anonymous unions.
|
||||
(do_build_assign_ref): Ditto.
|
||||
(largest_union_member): Move from lex.c.
|
||||
|
||||
Sat Oct 8 14:59:43 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
Re-implement g++'s vague linkage independent of TREE_PUBLIC.
|
||||
* pt.c (instantiate_member_templates): Lose redundant
|
||||
-fexternal-templates handling.
|
||||
(tsubst): Set TREE_PUBLIC and DECL_EXTERNAL on new decls. Don't set
|
||||
TREE_STATIC or DECL_INTERFACE_KNOWN.
|
||||
(do_pending_expansions): Predicate on DECL_INTERFACE_KNOWN instead
|
||||
of DECL_EXTERNAL for explicit instantiations.
|
||||
(do_function_instantiation): Do the new thing.
|
||||
(do_type_instantiation): Ditto.
|
||||
(instantiate_template): Deal with member templates defined in a .cc
|
||||
file with -fexternal-templates.
|
||||
* except.c (expand_exception_blocks): Use DECL_LINKAGE_KNOWN to
|
||||
decide whether to stick builtin_throw here.
|
||||
* decl2.c (import_export_inline): Predicate on DECL_INTERFACE_KNOWN
|
||||
rather than TREE_PUBLIC. Generally fix rules.
|
||||
(finish_file): Use DECL_INITIAL to determine whether or not a method
|
||||
has been synthesized, rather than TREE_ASM_WRITTEN.
|
||||
* decl.c (warn_extern_redeclared_static): Use DECL_PUBLIC instead of
|
||||
TREE_PUBLIC.
|
||||
(pushdecl): Ditto.
|
||||
(duplicate_decls): Ditto. Deal with DECL_DECLARED_STATIC and
|
||||
DECL_INTERFACE_KNOWN.
|
||||
(redeclaration_error_message): Fix checking for conflicting linkage.
|
||||
(define_function): Set DECL_INTERFACE_KNOWN.
|
||||
(grokfndecl): Function decls are PUBLIC until we are sure about
|
||||
their linkage. Set DECL_DECLARED_STATIC as needed.
|
||||
(start_function): Deal with linkage. Move pushdecl after linkage
|
||||
magic.
|
||||
(finish_function): Don't set TREE_ASM_WRITTEN on discarded inlines.
|
||||
* cp-tree.h (lang_decl_flags): Add interface_known and
|
||||
declared_static.
|
||||
(DECL_INTERFACE_KNOWN): New macro.
|
||||
(DECL_DECLARED_STATIC): New macro.
|
||||
(DECL_PUBLIC): New macro.
|
||||
|
||||
Clean up bogus use of TREE_PUBLIC.
|
||||
* class.c (alter_access): Fix mistaken use of TREE_PUBLIC (it
|
||||
doesn't correspond to TREE_PROTECTED and TREE_PRIVATE).
|
||||
* init.c (do_friend): Don't arbitrarily set TREE_PUBLIC.
|
||||
|
||||
Wed Oct 5 13:44:41 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* call.c (build_overload_call_real): Don't immediately do
|
||||
array->pointer conversion.
|
||||
* call.c (build_overload_call_real): Don't immediately do
|
||||
array->pointer conversion.
|
||||
|
||||
* pt.c (type_unification): If not passing to a reference, strip
|
||||
cv-quals. Also handle array->pointer conversion.
|
||||
* pt.c (type_unification): If not passing to a reference, strip
|
||||
cv-quals. Also handle array->pointer conversion.
|
||||
|
||||
Tue Oct 4 17:45:37 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* decl.c (grokdeclarator): Don't warn about applying const to a
|
||||
const typedef or template type parameter.
|
||||
* decl.c (grokdeclarator): Don't warn about applying const to a
|
||||
const typedef or template type parameter.
|
||||
|
||||
* decl2.c (finish_file): Also synthesize methods after walking the
|
||||
vtables. Ugly ugly ugly.
|
||||
|
||||
Mon Oct 3 15:02:41 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* decl.c (shadow_tag): Remove obsolete code for pushing tags and
|
||||
dealing with exceptions.
|
||||
* various: Remove lingering remnants of old exception handling code.
|
||||
|
||||
* decl2.c (finish_file): Synthesize methods before walking the
|
||||
vtables, so that the vtables get emitted as needed.
|
||||
|
||||
* decl.c (shadow_tag): Remove obsolete code for pushing tags and
|
||||
dealing with exceptions.
|
||||
|
||||
Mon Oct 3 13:05:27 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
|
||||
|
||||
* Make-lang.in (g++-cross): Depend upon version.o and $(LIBDEPS).
|
||||
|
||||
Mon Oct 3 02:59:28 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* decl2.c (finish_file): Fix inline handling.
|
||||
|
||||
Sun Oct 2 00:21:56 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* parse.y (expr_or_declarator): Add '(' expr_or_declarator ')' rule.
|
||||
(direct_notype_declarator): Ditto.
|
||||
(complex_direct_notype_declarator): Remove it here.
|
||||
* decl.c (grokdeclarator): Handle redundant scope even better.
|
||||
({push,pop}_cp_function_context): Take toplev parameter.
|
||||
|
||||
* method.c (synthesize_method): Pass toplev parameter to
|
||||
{push,pop}_cp_function_context depending on decl_function_context
|
||||
(fndecl).
|
||||
|
||||
* typeck.c (build_x_unary_op): Unary & on OFFSET_REFs is always the
|
||||
built-in version.
|
||||
|
||||
* method.c (synthesize_method): Don't be confused by __in_chrg
|
||||
parameter.
|
||||
|
||||
* class.c (popclass): Set C_C_D like start_function does.
|
||||
|
||||
* decl.c (grokdeclarator): Handle redundant scope better.
|
||||
|
||||
* parse.y (expr_or_declarator): Add '(' expr_or_declarator ')' rule.
|
||||
(direct_notype_declarator): Ditto.
|
||||
(complex_direct_notype_declarator): Remove it here.
|
||||
|
||||
Sat Oct 1 21:42:18 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* init.c (resolve_offset_ref): Fix types used in resolving .*
|
||||
expressions.
|
||||
* init.c (resolve_offset_ref): Fix types used in resolving .*
|
||||
expressions.
|
||||
|
||||
Thu Sep 29 16:15:36 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
|
||||
Sat Oct 1 15:18:49 1994 Jason Merrill (jason@phydeaux.cygnus.com)
|
||||
|
||||
* g++.c: Rework last change so it's done like collect.c (and
|
||||
gcc.c).
|
||||
|
||||
Wed Sep 28 19:19:01 1994 Brendan Kehoe (brendan@mole.gnu.ai.mit.edu)
|
||||
|
||||
* except.c (register_exception_table): Use Pmode, not PTRmode.
|
||||
|
||||
Wed Sep 14 10:17:27 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
|
||||
|
||||
* g++.c: Include <sys/errno.h> in case `errno' is a macro
|
||||
as permitted by ANSI C.
|
||||
Beginnings of work to synthesize methods only when needed.
|
||||
* call.c (build_method_call): Synthesize methods as necessary
|
||||
(currently never necessary).
|
||||
* class.c (popclass): Don't try to set C_C_D here, as it'll end up
|
||||
on the wrong obstack.
|
||||
* decl.c (push_cp_function_context): Mostly copied from
|
||||
push_c_function_context.
|
||||
(pop_cp_function_context): Similarly.
|
||||
(finish_function): Reverse order of poplevel and pop_nested_class so
|
||||
that current_class_decl is restored properly.
|
||||
(start_function): Ditto.
|
||||
(finish_function): Add parameter 'nested'. Don't call
|
||||
permanent_allocation if (nested).
|
||||
* various: Pass extra parameter to finish_function.
|
||||
* decl2.c (finish_file): Reorganize end-of-file inline handling,
|
||||
synthesizing methods as necessary.
|
||||
* lex.c (cons_up_default_function): Call mark_inline_for_output.
|
||||
Only synthesize methods immediately if #pragma implementation
|
||||
(currently disabled).
|
||||
(do_pending_inlines): Call synthesize_method.
|
||||
* method.c (synthesize_method): New function; all method synthesis
|
||||
goes through here. Calls do_build_assign_ref and
|
||||
do_build_copy_constructor.
|
||||
(build_default_constructor): Remove.
|
||||
(build_dtor): Ditto.
|
||||
(build_assign_ref): Rename to do_build_assign_ref and remove stuff
|
||||
done by synthesize_method.
|
||||
(build_copy_constructor): Similarly.
|
||||
|
||||
Thu Sep 29 16:58:52 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
|
@ -282,12 +628,12 @@ Sun Sep 18 10:12:12 1994 Jason Merrill (jason@deneb.cygnus.com)
|
|||
* *.c: Use cp_build_type_variant instead of c_build_type_variant.
|
||||
|
||||
* pt.c (do_type_instantiation): Don't try to instantiate nested
|
||||
enums.
|
||||
enums.
|
||||
|
||||
Tue Sep 13 10:56:58 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* cvt.c (build_up_reference): Handle preincrement and predecrement
|
||||
properly.
|
||||
properly.
|
||||
|
||||
Tue Sep 13 09:51:59 1994 Brendan Kehoe (brendan@lisa.cygnus.com)
|
||||
|
||||
|
@ -466,7 +812,7 @@ Sun Aug 21 23:07:35 1994 Gerald Baumgartner (gb@cs.purdue.edu)
|
|||
* class.c (finish_struct): Move setting of CLASSTYPE_INTERFACE and
|
||||
CLASSTYPE_VTABLE_NEEDS_WRITING for signatures up to left_curly time.
|
||||
* decl.c (xref_tag): Move setting of CLASSTYPE_INTERFACE and
|
||||
CLASSTYPE_VTABLE_NEEDS_WRITING for signatures down to left_curly time.
|
||||
CLASSTYPE_VTABLE_NEEDS_WRITING for signatures down to left_curly time.
|
||||
* parse.y (left_curly): New final resting place for setting
|
||||
CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING for signatures.
|
||||
|
||||
|
@ -486,12 +832,22 @@ Thu Aug 18 16:24:43 1994 Mike Stump (mrs@cygnus.com)
|
|||
|
||||
* error.c (dump_decl): Handle NULL args.
|
||||
|
||||
Thu Sep 29 16:15:36 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
|
||||
|
||||
* g++.c: Rework last change so it's done like collect.c (and
|
||||
gcc.c).
|
||||
|
||||
Wed Sep 14 10:17:27 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu>
|
||||
|
||||
* g++.c: Include <sys/errno.h> in case `errno' is a macro
|
||||
as permitted by ANSI C.
|
||||
|
||||
Thu Aug 18 12:48:09 1994 Mike Stump (mrs@cygnus.com)
|
||||
|
||||
* class.c (finish_struct): Move setting of CLASSTYPE_INTERFACE and
|
||||
CLASSTYPE_VTABLE_NEEDS_WRITING up to left_curly time.
|
||||
* decl.c (xref_tag): Move setting of CLASSTYPE_INTERFACE and
|
||||
CLASSTYPE_VTABLE_NEEDS_WRITING down to left_curly time.
|
||||
CLASSTYPE_VTABLE_NEEDS_WRITING down to left_curly time.
|
||||
* parse.y (left_curly): New final resting place for setting
|
||||
CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING.
|
||||
|
||||
|
@ -851,7 +1207,7 @@ Fri Jul 8 12:59:38 1994 Jason Merrill (jason@deneb.cygnus.com)
|
|||
* method.c (hack_identifier): Fix for new overloading.
|
||||
|
||||
* typeck.c (build_binary_op_nodefault): Don't mess with division by
|
||||
zero.
|
||||
zero.
|
||||
|
||||
Fri Jul 8 13:20:28 1994 Gerald Baumgartner (gb@cs.purdue.edu)
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ g++: $(srcdir)/cp/g++.c $(CONFIG_H) $(LIBDEPS)
|
|||
$(CC) $(ALL_CFLAGS) $(INCLUDES) $(LDFLAGS) -o g++ $(srcdir)/cp/g++.c $(LIBS)
|
||||
|
||||
# Create a version of the g++ driver which calls the cross-compiler.
|
||||
g++-cross: $(srcdir)/cp/g++.c
|
||||
g++-cross: $(srcdir)/cp/g++.c version.o $(LIBDEPS)
|
||||
$(CC) $(ALL_CFLAGS) $(INCLUDES) $(LDFLAGS) -o g++-cross \
|
||||
-DGCC_NAME=\"$(GCC_CROSS_NAME)\" $(srcdir)/cp/g++.c version.o $(LIBS)
|
||||
|
||||
|
|
|
@ -187,15 +187,26 @@ RTL_H = $(srcdir)/../rtl.h $(srcdir)/../rtl.def \
|
|||
TREE_H = $(srcdir)/../tree.h $(srcdir)/../real.h $(srcdir)/../tree.def \
|
||||
$(srcdir)/../machmode.h $(srcdir)/../machmode.def
|
||||
CXX_TREE_H = $(TREE_H) cp-tree.h tree.def
|
||||
PARSE_H = $(srcdir)/parse.h
|
||||
PARSE_C = $(srcdir)/parse.c
|
||||
|
||||
parse.o : $(srcdir)/parse.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
|
||||
parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
|
||||
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
|
||||
`echo $(srcdir)/parse.c | sed 's,^\./,,'`
|
||||
`echo $(PARSE_C) | sed 's,^\./,,'`
|
||||
|
||||
$(srcdir)/parse.c $(srcdir)/parse.h : $(srcdir)/parse.y
|
||||
#$(PARSE_C) $(PARSE_H) : $(srcdir)/parse.y
|
||||
# @echo expect 1 shift/reduce confict and 34 reduce/reduce conflicts.
|
||||
# cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o parse.c parse.y
|
||||
# cd $(srcdir); grep '^#define[ ]*YYEMPTY' parse.c >>parse.h
|
||||
$(PARSE_C) $(PARSE_H) : stamp-parse ; @true
|
||||
stamp-parse: $(srcdir)/parse.y
|
||||
@echo expect 1 shift/reduce confict and 34 reduce/reduce conflicts.
|
||||
cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o parse.c parse.y
|
||||
cd $(srcdir); grep '^#define[ ]*YYEMPTY' parse.c >>parse.h
|
||||
$(BISON) $(BISONFLAGS) -d $(srcdir)/parse.y
|
||||
grep '^#define[ ]*YYEMPTY' y.tab.c >>y.tab.h
|
||||
$(srcdir)/../move-if-change y.tab.c $(PARSE_C)
|
||||
$(srcdir)/../move-if-change y.tab.h $(PARSE_H)
|
||||
cp $(PARSE_C) y.tab.c
|
||||
touch stamp-parse
|
||||
|
||||
# hash.h really depends on $(srcdir)/gxx.gperf.
|
||||
# But this would screw things for people that don't have gperf,
|
||||
|
@ -206,9 +217,9 @@ $(srcdir)/hash.h:
|
|||
$(srcdir)/gxx.gperf >$(srcdir)/hash.h
|
||||
|
||||
spew.o : spew.c $(CONFIG_H) $(CXX_TREE_H) \
|
||||
$(srcdir)/parse.h $(srcdir)/../flags.h lex.h
|
||||
$(PARSE_H) $(srcdir)/../flags.h lex.h
|
||||
lex.o : lex.c $(CONFIG_H) $(CXX_TREE_H) \
|
||||
$(srcdir)/parse.h input.c $(srcdir)/../flags.h hash.h lex.h
|
||||
$(PARSE_H) input.c $(srcdir)/../flags.h hash.h lex.h
|
||||
decl.o : decl.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
|
||||
lex.h decl.h $(srcdir)/../stack.h
|
||||
decl2.o : decl2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
|
||||
|
@ -229,7 +240,7 @@ expr.o : expr.c $(CONFIG_H) $(CXX_TREE_H) $(RTL_H) $(srcdir)/../flags.h \
|
|||
$(srcdir)/../expr.h ../insn-codes.h
|
||||
edsel.o : edsel.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../stack.h $(srcdir)/../flags.h
|
||||
xref.o : xref.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../input.h
|
||||
pt.o : pt.c $(CONFIG_H) $(CXX_TREE_H) decl.h $(srcdir)/parse.h
|
||||
pt.o : pt.c $(CONFIG_H) $(CXX_TREE_H) decl.h $(PARSE_H)
|
||||
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
|
||||
|
|
|
@ -525,13 +525,6 @@ convert_harshness (type, parmtype, parm)
|
|||
else
|
||||
penalty = 2;
|
||||
|
||||
if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype))
|
||||
{
|
||||
ttl = unsigned_type (ttl);
|
||||
intype = unsigned_type (intype);
|
||||
penalty += 2;
|
||||
}
|
||||
|
||||
ttr = intype;
|
||||
|
||||
/* If the initializer is not an lvalue, then it does not
|
||||
|
@ -551,6 +544,13 @@ convert_harshness (type, parmtype, parm)
|
|||
return h;
|
||||
}
|
||||
|
||||
if (TREE_UNSIGNED (ttl) ^ TREE_UNSIGNED (intype))
|
||||
{
|
||||
ttl = unsigned_type (ttl);
|
||||
ttr = intype = unsigned_type (intype);
|
||||
penalty += 2;
|
||||
}
|
||||
|
||||
if (ttl == ttr)
|
||||
{
|
||||
if (penalty > 2)
|
||||
|
@ -2197,6 +2197,12 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
cp->function = function;
|
||||
cp->basetypes = basetype_path;
|
||||
|
||||
/* Don't allow non-converting constructors to convert. */
|
||||
if (flags & LOOKUP_ONLYCONVERTING
|
||||
&& DECL_LANG_SPECIFIC (function)
|
||||
&& DECL_NONCONVERTING_P (function))
|
||||
continue;
|
||||
|
||||
/* No "two-level" conversions. */
|
||||
if (flags & LOOKUP_NO_CONVERSION
|
||||
&& (cp->h.code & USER_CODE))
|
||||
|
@ -2434,6 +2440,13 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
/* Declare external function if necessary. */
|
||||
assemble_external (function);
|
||||
|
||||
#if 0
|
||||
if (DECL_ARTIFICIAL (function) && ! flag_no_inline
|
||||
&& DECL_SAVED_INSNS (function) == 0
|
||||
&& ! TREE_ASM_WRITTEN (function))
|
||||
synthesize_method (function);
|
||||
#endif
|
||||
|
||||
fntype = TREE_TYPE (function);
|
||||
if (TREE_CODE (fntype) == POINTER_TYPE)
|
||||
fntype = TREE_TYPE (fntype);
|
||||
|
|
195
gcc/cp/class.c
195
gcc/cp/class.c
|
@ -659,7 +659,7 @@ prepare_fresh_vtable (binfo, for_type)
|
|||
for_type, and we really want different names. (mrs) */
|
||||
tree name = build_type_pathname (VTABLE_NAME_FORMAT, basetype, for_type);
|
||||
tree new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl));
|
||||
tree path;
|
||||
tree path, offset;
|
||||
int result;
|
||||
|
||||
/* Remember which class this vtable is really for. */
|
||||
|
@ -676,11 +676,18 @@ prepare_fresh_vtable (binfo, for_type)
|
|||
|
||||
/* Make fresh virtual list, so we can smash it later. */
|
||||
BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo));
|
||||
|
||||
if (TREE_VIA_VIRTUAL (binfo))
|
||||
offset = BINFO_OFFSET (binfo_member (BINFO_TYPE (binfo),
|
||||
CLASSTYPE_VBASECLASSES (for_type)));
|
||||
else
|
||||
offset = BINFO_OFFSET (binfo);
|
||||
|
||||
/* Install the value for `headof' if that's what we're doing. */
|
||||
if (flag_dossier)
|
||||
TREE_VALUE (TREE_CHAIN (BINFO_VIRTUALS (binfo)))
|
||||
= build_vtable_entry (size_binop (MINUS_EXPR, integer_zero_node, BINFO_OFFSET (binfo)),
|
||||
FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (TREE_CHAIN (BINFO_VIRTUALS (binfo)))));
|
||||
if (flag_rtti)
|
||||
TREE_VALUE (BINFO_VIRTUALS (binfo))
|
||||
= build_vtable_entry (size_binop (MINUS_EXPR, integer_zero_node, offset),
|
||||
FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (BINFO_VIRTUALS (binfo))));
|
||||
|
||||
#ifdef GATHER_STATISTICS
|
||||
n_vtables += 1;
|
||||
|
@ -803,11 +810,13 @@ add_virtual_function (pending_virtuals, has_virtual, fndecl, t)
|
|||
{
|
||||
tree entry;
|
||||
|
||||
if (flag_dossier && *has_virtual == 0)
|
||||
if (flag_rtti && *has_virtual == 0)
|
||||
{
|
||||
/* CLASSTYPE_DOSSIER is only used as a Boolean (NULL or not). */
|
||||
CLASSTYPE_DOSSIER (t) = integer_one_node;
|
||||
/* CLASSTYPE_RTTI is only used as a Boolean (NULL or not). */
|
||||
CLASSTYPE_RTTI (t) = integer_one_node;
|
||||
#if 0
|
||||
*has_virtual = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Build a new INT_CST for this DECL_VINDEX. */
|
||||
|
@ -1083,19 +1092,21 @@ alter_access (t, fdecl, access)
|
|||
error ("conflicting access specifications for field `%s', ignored",
|
||||
IDENTIFIER_POINTER (DECL_NAME (fdecl)));
|
||||
}
|
||||
else if (TREE_PRIVATE (fdecl) && access != access_private)
|
||||
cp_error_at ("cannot make private `%D' non-private", fdecl);
|
||||
else if (TREE_PRIVATE (fdecl))
|
||||
{
|
||||
if (access != access_private)
|
||||
cp_error_at ("cannot make private `%D' non-private", fdecl);
|
||||
goto alter;
|
||||
}
|
||||
else if (TREE_PROTECTED (fdecl))
|
||||
{
|
||||
if (access == access_public)
|
||||
cp_error_at ("cannot make protected `%D' public", fdecl);
|
||||
if (access != access_protected)
|
||||
cp_error_at ("cannot make protected `%D' non-protected", fdecl);
|
||||
goto alter;
|
||||
}
|
||||
/* ARM 11.3: an access declaration may not be used to restrict access
|
||||
to a member that is accessible in the base class. */
|
||||
else if (TREE_PUBLIC (fdecl)
|
||||
&& (access == access_private
|
||||
|| access == access_protected))
|
||||
else if (access != access_public)
|
||||
cp_error_at ("cannot reduce access of public member `%D'", fdecl);
|
||||
else if (elem == NULL_TREE)
|
||||
{
|
||||
|
@ -2120,7 +2131,7 @@ finish_vtbls (binfo, do_self, t)
|
|||
{
|
||||
base_binfo = binfo_member (BINFO_TYPE (base_binfo), CLASSTYPE_VBASECLASSES (t));
|
||||
}
|
||||
finish_vtbls (base_binfo, is_not_base_vtable, t);
|
||||
finish_vtbls (base_binfo, (is_not_base_vtable || flag_rtti), t);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2239,12 +2250,34 @@ modify_one_vtable (binfo, t, fndecl, pfn)
|
|||
tree binfo, t, fndecl, pfn;
|
||||
{
|
||||
tree virtuals = BINFO_VIRTUALS (binfo);
|
||||
tree old_rtti;
|
||||
unsigned HOST_WIDE_INT n;
|
||||
|
||||
n = 0;
|
||||
/* Skip initial vtable length field and RTTI fake object. */
|
||||
for (; virtuals && n < 1 + flag_dossier; n++)
|
||||
virtuals = TREE_CHAIN (virtuals);
|
||||
/* update rtti entry */
|
||||
if (flag_rtti)
|
||||
{
|
||||
if (binfo == TYPE_BINFO (t))
|
||||
{
|
||||
if (! BINFO_NEW_VTABLE_MARKED (binfo))
|
||||
build_vtable (TYPE_BINFO (DECL_CONTEXT (CLASSTYPE_VFIELD (t))), t);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! BINFO_NEW_VTABLE_MARKED (binfo))
|
||||
prepare_fresh_vtable (binfo, t);
|
||||
}
|
||||
old_rtti = get_vtable_entry_n (BINFO_VIRTUALS (binfo), 0);
|
||||
if (old_rtti)
|
||||
TREE_VALUE (old_rtti) = build_vtable_entry (
|
||||
DELTA_FROM_VTABLE_ENTRY (TREE_VALUE (old_rtti)),
|
||||
build_t_desc (t, 0));
|
||||
}
|
||||
if (fndecl == NULL_TREE) return;
|
||||
|
||||
/* Skip RTTI fake object. */
|
||||
n = 1;
|
||||
if (virtuals)
|
||||
virtuals = TREE_CHAIN (virtuals);
|
||||
while (virtuals)
|
||||
{
|
||||
tree current_fndecl = TREE_VALUE (virtuals);
|
||||
|
@ -2330,7 +2363,7 @@ modify_all_direct_vtables (binfo, do_self, t, fndecl, pfn)
|
|||
int is_not_base_vtable =
|
||||
i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
|
||||
if (! TREE_VIA_VIRTUAL (base_binfo))
|
||||
modify_all_direct_vtables (base_binfo, is_not_base_vtable, t, fndecl, pfn);
|
||||
modify_all_direct_vtables (base_binfo, (is_not_base_vtable || flag_rtti), t, fndecl, pfn);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2345,10 +2378,10 @@ fixup_vtable_deltas (binfo, t)
|
|||
tree virtuals = BINFO_VIRTUALS (binfo);
|
||||
unsigned HOST_WIDE_INT n;
|
||||
|
||||
n = 0;
|
||||
/* Skip initial vtable length field and RTTI fake object. */
|
||||
for (; virtuals && n < 1 + flag_dossier; n++)
|
||||
virtuals = TREE_CHAIN (virtuals);
|
||||
/* Skip RTTI fake object. */
|
||||
n = 1;
|
||||
if (virtuals)
|
||||
virtuals = TREE_CHAIN (virtuals);
|
||||
while (virtuals)
|
||||
{
|
||||
tree fndecl = TREE_VALUE (virtuals);
|
||||
|
@ -2489,21 +2522,9 @@ override_one_vtable (binfo, old, t)
|
|||
if (BINFO_NEW_VTABLE_MARKED (binfo))
|
||||
choose = NEITHER;
|
||||
|
||||
/* Skip size entry. */
|
||||
/* Skip RTTI fake object. */
|
||||
virtuals = TREE_CHAIN (virtuals);
|
||||
/* Skip RTTI fake object. */
|
||||
if (flag_dossier)
|
||||
{
|
||||
virtuals = TREE_CHAIN (virtuals);
|
||||
}
|
||||
|
||||
/* Skip size entry. */
|
||||
old_virtuals = TREE_CHAIN (old_virtuals);
|
||||
/* Skip RTTI fake object. */
|
||||
if (flag_dossier)
|
||||
{
|
||||
old_virtuals = TREE_CHAIN (old_virtuals);
|
||||
}
|
||||
|
||||
while (virtuals)
|
||||
{
|
||||
|
@ -2789,8 +2810,10 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (flag_dossier)
|
||||
#if 0
|
||||
if (flag_rtti)
|
||||
build_t_desc (t, 0);
|
||||
#endif
|
||||
|
||||
TYPE_BINFO (t) = NULL_TREE;
|
||||
|
||||
|
@ -3303,7 +3326,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
tail = &TREE_CHAIN (dtor);
|
||||
|
||||
if (DECL_VINDEX (dtor) == NULL_TREE
|
||||
&& ! CLASSTYPE_DECLARED_EXCEPTION (t)
|
||||
&& (needs_virtual_dtor
|
||||
|| pending_virtuals != NULL_TREE
|
||||
|| pending_hard_virtuals != NULL_TREE))
|
||||
|
@ -3319,6 +3341,9 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
*tail_user_methods = NULL_TREE;
|
||||
|
||||
TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t);
|
||||
if (flag_rtti && (max_has_virtual > 0 || needs_virtual_dtor) &&
|
||||
has_virtual == 0)
|
||||
has_virtual = 1;
|
||||
|
||||
if (! fn_fields)
|
||||
nonprivate_method = 1;
|
||||
|
@ -3374,7 +3399,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
method_vec = finish_struct_methods (t, fn_fields, nonprivate_method);
|
||||
|
||||
if (TYPE_HAS_CONSTRUCTOR (t)
|
||||
&& ! CLASSTYPE_DECLARED_EXCEPTION (t)
|
||||
&& CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
|
||||
&& DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE)
|
||||
{
|
||||
|
@ -3485,7 +3509,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
DECL_FCONTEXT (vfield) = t;
|
||||
DECL_FIELD_SIZE (vfield) = 0;
|
||||
DECL_ALIGN (vfield) = TYPE_ALIGN (ptr_type_node);
|
||||
if (CLASSTYPE_DOSSIER (t))
|
||||
if (CLASSTYPE_RTTI (t))
|
||||
{
|
||||
/* vfield is always first entry in structure. */
|
||||
TREE_CHAIN (vfield) = fields;
|
||||
|
@ -3680,14 +3704,16 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
vbases = CLASSTYPE_VBASECLASSES (t);
|
||||
CLASSTYPE_N_VBASECLASSES (t) = list_length (vbases);
|
||||
|
||||
/* The rtti code should do this. (mrs) */
|
||||
#if 0
|
||||
while (vbases)
|
||||
{
|
||||
/* The rtti code should do this. (mrs) */
|
||||
/* Update dossier info with offsets for virtual baseclasses. */
|
||||
if (flag_dossier && ! BINFO_NEW_VTABLE_MARKED (vbases))
|
||||
/* Update rtti info with offsets for virtual baseclasses. */
|
||||
if (flag_rtti && ! BINFO_NEW_VTABLE_MARKED (vbases))
|
||||
prepare_fresh_vtable (vbases, t);
|
||||
vbases = TREE_CHAIN (vbases);
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
/* Now fixup overrides of all functions in vtables from all
|
||||
|
@ -3750,6 +3776,15 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
#ifdef NOTQUITE
|
||||
cp_warning ("Doing hard virtuals for %T...", t);
|
||||
#endif
|
||||
|
||||
if (has_virtual > max_has_virtual)
|
||||
max_has_virtual = has_virtual;
|
||||
if (max_has_virtual > 0)
|
||||
TYPE_VIRTUAL_P (t) = 1;
|
||||
|
||||
if (flag_rtti && TYPE_VIRTUAL_P (t) && !pending_hard_virtuals)
|
||||
modify_all_vtables (t, NULL_TREE, NULL_TREE);
|
||||
|
||||
while (pending_hard_virtuals)
|
||||
{
|
||||
modify_all_vtables (t,
|
||||
|
@ -3761,19 +3796,27 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
|
||||
/* Under our model of GC, every C++ class gets its own virtual
|
||||
function table, at least virtually. */
|
||||
if (pending_virtuals || CLASSTYPE_DOSSIER (t))
|
||||
if (pending_virtuals || (flag_rtti && TYPE_VIRTUAL_P (t)))
|
||||
{
|
||||
pending_virtuals = nreverse (pending_virtuals);
|
||||
/* We must enter these virtuals into the table. */
|
||||
if (first_vfn_base_index < 0)
|
||||
{
|
||||
if (flag_dossier)
|
||||
if (flag_rtti)
|
||||
pending_virtuals = tree_cons (NULL_TREE,
|
||||
build_vtable_entry (integer_zero_node,
|
||||
build_t_desc (t, 0)),
|
||||
pending_virtuals);
|
||||
build_vtable_entry (integer_zero_node, build_t_desc (t, 0)),
|
||||
pending_virtuals);
|
||||
else
|
||||
pending_virtuals = tree_cons (NULL_TREE,
|
||||
build_vtable_entry (integer_zero_node, integer_zero_node),
|
||||
pending_virtuals);
|
||||
|
||||
#if 0
|
||||
/* The size is no longer used. */
|
||||
/* now we put the size of the vtable as first entry */
|
||||
pending_virtuals = tree_cons (NULL_TREE, the_null_vtable_entry,
|
||||
pending_virtuals);
|
||||
#endif
|
||||
build_vtable (NULL_TREE, t);
|
||||
}
|
||||
else
|
||||
|
@ -3784,9 +3827,9 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
|
||||
build_vtable (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), first_vfn_base_index), t);
|
||||
|
||||
/* Update the dossier pointer for this class. */
|
||||
if (flag_dossier)
|
||||
TREE_VALUE (TREE_CHAIN (TYPE_BINFO_VIRTUALS (t)))
|
||||
/* Update the rtti pointer for this class. */
|
||||
if (flag_rtti)
|
||||
TREE_VALUE (TYPE_BINFO_VIRTUALS (t))
|
||||
= build_vtable_entry (integer_zero_node, build_t_desc (t, 0));
|
||||
}
|
||||
|
||||
|
@ -3815,11 +3858,8 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1;
|
||||
}
|
||||
|
||||
if (has_virtual > max_has_virtual)
|
||||
max_has_virtual = has_virtual;
|
||||
if (max_has_virtual || first_vfn_base_index >= 0)
|
||||
{
|
||||
TYPE_VIRTUAL_P (t) = 1;
|
||||
CLASSTYPE_VSIZE (t) = has_virtual;
|
||||
if (first_vfn_base_index >= 0)
|
||||
{
|
||||
|
@ -3970,7 +4010,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
else if (TYPE_NEEDS_CONSTRUCTING (t))
|
||||
build_class_init_list (t);
|
||||
|
||||
if (! CLASSTYPE_DECLARED_EXCEPTION (t) && ! IS_SIGNATURE (t))
|
||||
if (! IS_SIGNATURE (t))
|
||||
embrace_waiting_friends (t);
|
||||
|
||||
/* Write out inline function definitions. */
|
||||
|
@ -4022,13 +4062,23 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
finish_vtbls (TYPE_BINFO (t), 1, t);
|
||||
TYPE_BEING_DEFINED (t) = 0;
|
||||
|
||||
if (flag_dossier && CLASSTYPE_VTABLE_NEEDS_WRITING (t))
|
||||
if (flag_rtti && TYPE_VIRTUAL_P (t) && CLASSTYPE_VTABLE_NEEDS_WRITING (t))
|
||||
{
|
||||
tree variants;
|
||||
tree tdecl;
|
||||
tree tdecl, td;
|
||||
|
||||
/* Now instantiate its type descriptors. */
|
||||
tdecl = TREE_OPERAND (build_t_desc (t, 1), 0);
|
||||
td = build_t_desc (t, 1);
|
||||
if (td == NULL_TREE)
|
||||
{
|
||||
cp_error ("failed to build type descriptor node of '%T', maybe typeinfo.h not included", t);
|
||||
tdecl = NULL_TREE;
|
||||
}
|
||||
else
|
||||
tdecl = TREE_OPERAND (td, 0);
|
||||
|
||||
#if 0
|
||||
/* I see no need for building the following TD */
|
||||
variants = TYPE_POINTER_TO (t);
|
||||
build_type_variant (variants, 1, 0);
|
||||
while (variants)
|
||||
|
@ -4036,6 +4086,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
build_t_desc (variants, 1);
|
||||
variants = TYPE_NEXT_VARIANT (variants);
|
||||
}
|
||||
#endif
|
||||
variants = build_reference_type (t);
|
||||
build_type_variant (variants, 1, 0);
|
||||
while (variants)
|
||||
|
@ -4043,11 +4094,14 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
build_t_desc (variants, 1);
|
||||
variants = TYPE_NEXT_VARIANT (variants);
|
||||
}
|
||||
DECL_CONTEXT (tdecl) = t;
|
||||
if (tdecl != NULL_TREE)
|
||||
DECL_CONTEXT (tdecl) = t;
|
||||
}
|
||||
#if 0
|
||||
/* Still need to instantiate this C struct's type descriptor. */
|
||||
else if (flag_dossier && ! CLASSTYPE_DOSSIER (t))
|
||||
else if (flag_rtti && ! CLASSTYPE_RTTI (t))
|
||||
build_t_desc (t, 1);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (TYPE_NAME (t) && TYPE_IDENTIFIER (t))
|
||||
|
@ -4450,9 +4504,20 @@ popclass (modify)
|
|||
if (TREE_CODE (TREE_TYPE (current_class_decl)) == POINTER_TYPE)
|
||||
{
|
||||
tree temp;
|
||||
/* Can't call build_indirect_ref here, because it has special
|
||||
logic to return C_C_D given this argument. */
|
||||
C_C_D = build1 (INDIRECT_REF, current_class_type, current_class_decl);
|
||||
if (CLASSTYPE_INST_VAR (current_class_type) == NULL_TREE)
|
||||
{
|
||||
/* Can't call build_indirect_ref here, because it has special
|
||||
logic to return C_C_D given this argument. */
|
||||
C_C_D = build1 (INDIRECT_REF, current_class_type, current_class_decl);
|
||||
CLASSTYPE_INST_VAR (current_class_type) = C_C_D;
|
||||
}
|
||||
else
|
||||
{
|
||||
C_C_D = CLASSTYPE_INST_VAR (current_class_type);
|
||||
/* `current_class_decl' is different for every
|
||||
function we compile. */
|
||||
TREE_OPERAND (C_C_D, 0) = current_class_decl;
|
||||
}
|
||||
temp = TREE_TYPE (TREE_TYPE (current_class_decl));
|
||||
TREE_READONLY (C_C_D) = TYPE_READONLY (temp);
|
||||
TREE_SIDE_EFFECTS (C_C_D) = TYPE_VOLATILE (temp);
|
||||
|
|
|
@ -408,7 +408,7 @@ struct lang_type
|
|||
unsigned interface_only : 1;
|
||||
unsigned interface_unknown : 1;
|
||||
unsigned needs_virtual_reinit : 1;
|
||||
unsigned declared_exception : 1;
|
||||
unsigned vec_delete_takes_size : 1;
|
||||
unsigned declared_class : 1;
|
||||
unsigned being_defined : 1;
|
||||
unsigned redefined : 1;
|
||||
|
@ -442,13 +442,12 @@ struct lang_type
|
|||
unsigned has_const_init_ref : 1;
|
||||
unsigned has_complex_init_ref : 1;
|
||||
unsigned has_complex_assign_ref : 1;
|
||||
unsigned vec_delete_takes_size : 1;
|
||||
unsigned has_abstract_assign_ref : 1;
|
||||
|
||||
/* The MIPS compiler gets it wrong if this struct also
|
||||
does not fill out to a multiple of 4 bytes. Add a
|
||||
member `dummy' with new bits if you go over the edge. */
|
||||
unsigned dummy : 19;
|
||||
unsigned dummy : 20;
|
||||
|
||||
unsigned n_vancestors : 16;
|
||||
} type_flags;
|
||||
|
@ -495,7 +494,7 @@ struct lang_type
|
|||
char *mi_matrix;
|
||||
union tree_node *conversions[last_conversion_type];
|
||||
|
||||
union tree_node *dossier;
|
||||
union tree_node *rtti;
|
||||
|
||||
union tree_node *methods;
|
||||
|
||||
|
@ -629,8 +628,8 @@ struct lang_type
|
|||
signature reference type. */
|
||||
#define SIGNATURE_REFERENCE_TO(NODE) (TYPE_LANG_SPECIFIC(NODE)->signature_reference_to)
|
||||
|
||||
/* The is the VAR_DECL that contains NODE's dossier. */
|
||||
#define CLASSTYPE_DOSSIER(NODE) (TYPE_LANG_SPECIFIC(NODE)->dossier)
|
||||
/* The is the VAR_DECL that contains NODE's rtti. */
|
||||
#define CLASSTYPE_RTTI(NODE) (TYPE_LANG_SPECIFIC(NODE)->rtti)
|
||||
|
||||
/* List of all explicit methods (chained using DECL_NEXT_METHOD),
|
||||
in order they were parsed. */
|
||||
|
@ -816,8 +815,6 @@ struct lang_type
|
|||
|
||||
/* Say whether this node was declared as a "class" or a "struct". */
|
||||
#define CLASSTYPE_DECLARED_CLASS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.declared_class)
|
||||
/* Say whether this node was declared as a "class" or a "struct". */
|
||||
#define CLASSTYPE_DECLARED_EXCEPTION(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.declared_exception)
|
||||
/* whether this can be globalized. */
|
||||
#define CLASSTYPE_NO_GLOBALIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.no_globalize)
|
||||
|
||||
|
@ -947,7 +944,10 @@ struct lang_decl_flags
|
|||
unsigned saved_inline : 1;
|
||||
unsigned use_template : 2;
|
||||
|
||||
unsigned dummy : 8;
|
||||
unsigned interface_known : 1;
|
||||
unsigned declared_static : 1;
|
||||
unsigned nonconverting : 1;
|
||||
unsigned dummy : 5;
|
||||
|
||||
tree access;
|
||||
tree context;
|
||||
|
@ -1032,6 +1032,10 @@ struct lang_decl
|
|||
is mutable. */
|
||||
#define DECL_MUTABLE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.mutable_flag)
|
||||
|
||||
/* Nonzero for _DECL means that this constructor is a non-converting
|
||||
constructor. */
|
||||
#define DECL_NONCONVERTING_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.nonconverting)
|
||||
|
||||
/* Nonzero for FUNCTION_DECL means that this member function
|
||||
exists as part of an abstract class's interface. */
|
||||
#define DECL_ABSTRACT_VIRTUAL_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.abstract_virtual)
|
||||
|
@ -1322,6 +1326,18 @@ struct lang_decl
|
|||
#define SET_CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \
|
||||
(CLASSTYPE_USE_TEMPLATE(NODE) = 3)
|
||||
|
||||
/* We know what we're doing with this decl now. */
|
||||
#define DECL_INTERFACE_KNOWN(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.interface_known)
|
||||
|
||||
/* This decl was declared to have internal linkage. */
|
||||
#define DECL_DECLARED_STATIC(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.declared_static)
|
||||
|
||||
#define DECL_PUBLIC(NODE) \
|
||||
(TREE_CODE (NODE) == FUNCTION_DECL ? ! DECL_DECLARED_STATIC (NODE) \
|
||||
: TREE_PUBLIC (NODE))
|
||||
|
||||
#define THUNK_DELTA(DECL) ((DECL)->decl.frame_size.i)
|
||||
|
||||
/* ...and for unexpanded-parameterized-type nodes. */
|
||||
|
@ -1330,7 +1346,7 @@ struct lang_decl
|
|||
|
||||
/* An enumeration of the kind of tags that C++ accepts. */
|
||||
enum tag_types { record_type, class_type, union_type, enum_type,
|
||||
exception_type, signature_type };
|
||||
signature_type };
|
||||
|
||||
/* Zero means prototype weakly, as in ANSI C (no args means nothing).
|
||||
Each language context defines how this variable should be set. */
|
||||
|
@ -1387,8 +1403,14 @@ extern tree void_zero_node;
|
|||
extern tree default_function_type;
|
||||
extern tree vtable_entry_type;
|
||||
extern tree sigtable_entry_type;
|
||||
extern tree __t_desc_type_node, __i_desc_type_node, __m_desc_type_node;
|
||||
extern tree Type_info_type_node;
|
||||
extern tree __t_desc_type_node;
|
||||
extern tree __tp_desc_type_node;
|
||||
extern tree __access_mode_type_node;
|
||||
extern tree __bltn_desc_type_node, __user_desc_type_node;
|
||||
extern tree __class_desc_type_node, __attr_desc_type_node;
|
||||
extern tree __ptr_desc_type_node, __func_desc_type_node;
|
||||
extern tree __ptmf_desc_type_node, __ptmd_desc_type_node;
|
||||
extern tree type_info_type_node;
|
||||
extern tree class_star_type_node;
|
||||
extern tree this_identifier;
|
||||
extern tree pfn_identifier;
|
||||
|
@ -1402,7 +1424,7 @@ extern tree error_mark_list;
|
|||
|
||||
extern tree ptr_type_node, const_ptr_type_node;
|
||||
extern tree class_type_node, record_type_node, union_type_node, enum_type_node;
|
||||
extern tree exception_type_node, unknown_type_node;
|
||||
extern tree unknown_type_node;
|
||||
extern tree opaque_type_node, signature_type_node;
|
||||
|
||||
/* Node for "pointer to (virtual) function".
|
||||
|
@ -1419,11 +1441,6 @@ extern tree long_long_integer_type_node, long_long_unsigned_type_node;
|
|||
extern tree integer_two_node, integer_three_node;
|
||||
extern tree bool_type_node, true_node, false_node;
|
||||
|
||||
/* in except.c */
|
||||
extern tree current_exception_type;
|
||||
extern tree current_exception_decl;
|
||||
extern tree current_exception_object;
|
||||
|
||||
/* in pt.c */
|
||||
/* PARM_VEC is a vector of template parameters, either IDENTIFIER_NODEs or
|
||||
PARM_DECLs. BINDINGS, if non-null, is a vector of bindings for those
|
||||
|
@ -1715,9 +1732,9 @@ extern int flag_int_enum_equivalence;
|
|||
|
||||
extern int flag_gc;
|
||||
|
||||
/* Nonzero means generate 'dossiers' that give run-time type information. */
|
||||
/* Nonzero means generate 'rtti' that give run-time type information. */
|
||||
|
||||
extern int flag_dossier;
|
||||
extern int flag_rtti;
|
||||
|
||||
/* Nonzero means do emit exported implementations of functions even if
|
||||
they can be inlined. */
|
||||
|
@ -1782,7 +1799,8 @@ extern tree current_class_type; /* _TYPE: the type of the current class */
|
|||
#define LOOKUP_GLOBAL (16)
|
||||
#define LOOKUP_HAS_IN_CHARGE (32)
|
||||
#define LOOKUP_SPECULATIVELY (64)
|
||||
/* 128 & 256 are free */
|
||||
#define LOOKUP_ONLYCONVERTING (128)
|
||||
/* 256 is free */
|
||||
#define LOOKUP_NO_CONVERSION (512)
|
||||
#define LOOKUP_DESTRUCTOR (512)
|
||||
|
||||
|
@ -1953,7 +1971,7 @@ extern tree grok_enum_decls PROTO((tree, tree));
|
|||
extern int start_function PROTO((tree, tree, tree, int));
|
||||
extern void store_parm_decls PROTO((void));
|
||||
extern void store_return_init PROTO((tree, tree));
|
||||
extern void finish_function PROTO((int, int));
|
||||
extern void finish_function PROTO((int, int, int));
|
||||
extern tree start_method PROTO((tree, tree, tree));
|
||||
extern tree finish_method PROTO((tree));
|
||||
extern void hack_incomplete_structures PROTO((tree));
|
||||
|
|
169
gcc/cp/cvt.c
169
gcc/cp/cvt.c
|
@ -663,10 +663,12 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
|
|||
|
||||
if (form == REFERENCE_TYPE)
|
||||
{
|
||||
rval = copy_node (expr);
|
||||
TREE_TYPE (rval) = build_pointer_type (TREE_TYPE (TREE_TYPE (expr)));
|
||||
rval = cp_convert (build_pointer_type (TREE_TYPE (reftype)), rval,
|
||||
tree type = TREE_TYPE (expr);
|
||||
tree tmp = copy_node (expr);
|
||||
TREE_TYPE (tmp) = build_pointer_type (TREE_TYPE (TREE_TYPE (expr)));
|
||||
rval = cp_convert (build_pointer_type (TREE_TYPE (reftype)), tmp,
|
||||
convtype, flags);
|
||||
TREE_TYPE (tmp) = type;
|
||||
TREE_TYPE (rval) = reftype;
|
||||
return rval;
|
||||
}
|
||||
|
@ -725,7 +727,8 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
|
|||
&& (rval = build_method_call
|
||||
(NULL_TREE, constructor_name_full (type),
|
||||
build_tree_list (NULL_TREE, expr), TYPE_BINFO (type),
|
||||
LOOKUP_NO_CONVERSION|LOOKUP_SPECULATIVELY)))
|
||||
LOOKUP_NO_CONVERSION|LOOKUP_SPECULATIVELY
|
||||
| LOOKUP_ONLYCONVERTING)))
|
||||
{
|
||||
tree init;
|
||||
|
||||
|
@ -736,7 +739,8 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
|
|||
init = build_method_call (t, constructor_name_full (type),
|
||||
build_tree_list (NULL_TREE, expr),
|
||||
TYPE_BINFO (type),
|
||||
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
|
||||
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION
|
||||
| LOOKUP_ONLYCONVERTING);
|
||||
|
||||
if (init == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
@ -750,7 +754,8 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
|
|||
init = build_method_call (NULL_TREE, constructor_name_full (type),
|
||||
build_tree_list (NULL_TREE, expr),
|
||||
TYPE_BINFO (type),
|
||||
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
|
||||
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION
|
||||
|LOOKUP_ONLYCONVERTING);
|
||||
|
||||
if (init == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
@ -1283,12 +1288,9 @@ cp_convert (type, expr, convtype, flags)
|
|||
if (IS_AGGR_TYPE_CODE (code))
|
||||
{
|
||||
tree dtype = TREE_TYPE (e);
|
||||
tree ctor = NULL_TREE;
|
||||
tree conversion = NULL_TREE;
|
||||
|
||||
if (TREE_CODE (dtype) == REFERENCE_TYPE)
|
||||
{
|
||||
e = convert_from_reference (e);
|
||||
dtype = TREE_TYPE (e);
|
||||
}
|
||||
dtype = TYPE_MAIN_VARIANT (dtype);
|
||||
|
||||
/* Conversion of object pointers or signature pointers/references
|
||||
|
@ -1321,87 +1323,78 @@ cp_convert (type, expr, convtype, flags)
|
|||
There may be some ambiguity between using a constructor
|
||||
vs. using a type conversion operator when both apply. */
|
||||
|
||||
else if (IS_AGGR_TYPE (dtype))
|
||||
if (IS_AGGR_TYPE (dtype) && ! DERIVED_FROM_P (type, dtype)
|
||||
&& TYPE_HAS_CONVERSION (dtype))
|
||||
conversion = build_type_conversion (CONVERT_EXPR, type, e, 1);
|
||||
|
||||
if (conversion == error_mark_node)
|
||||
{
|
||||
tree binfo;
|
||||
error ("ambiguous pointer conversion");
|
||||
return conversion;
|
||||
}
|
||||
|
||||
tree conversion;
|
||||
if (TYPE_HAS_CONSTRUCTOR (type))
|
||||
ctor = build_method_call (NULL_TREE, constructor_name_full (type),
|
||||
build_tree_list (NULL_TREE, e),
|
||||
TYPE_BINFO (type),
|
||||
LOOKUP_NORMAL | LOOKUP_SPECULATIVELY
|
||||
| LOOKUP_ONLYCONVERTING
|
||||
| (conversion ? LOOKUP_NO_CONVERSION : 0));
|
||||
|
||||
if (! DERIVED_FROM_P (type, dtype) && TYPE_HAS_CONVERSION (dtype))
|
||||
conversion = build_type_conversion (CONVERT_EXPR, type, e, 1);
|
||||
else
|
||||
conversion = NULL_TREE;
|
||||
|
||||
if (TYPE_HAS_CONSTRUCTOR (type))
|
||||
{
|
||||
tree rval = build_method_call (NULL_TREE, constructor_name_full (type),
|
||||
build_tree_list (NULL_TREE, e),
|
||||
TYPE_BINFO (type),
|
||||
conversion ? LOOKUP_NO_CONVERSION : 0);
|
||||
|
||||
if (rval != error_mark_node)
|
||||
{
|
||||
if (conversion)
|
||||
{
|
||||
error ("both constructor and type conversion operator apply");
|
||||
return error_mark_node;
|
||||
}
|
||||
/* call to constructor successful. */
|
||||
rval = build_cplus_new (type, rval, 1);
|
||||
return rval;
|
||||
}
|
||||
}
|
||||
/* Type conversion successful/applies. */
|
||||
if (conversion)
|
||||
{
|
||||
if (conversion == error_mark_node)
|
||||
error ("ambiguous pointer conversion");
|
||||
return conversion;
|
||||
}
|
||||
|
||||
/* now try normal C++ assignment semantics. */
|
||||
binfo = TYPE_BINFO (dtype);
|
||||
if (BINFO_TYPE (binfo) == type
|
||||
|| (binfo = get_binfo (type, dtype, 1)))
|
||||
{
|
||||
if (binfo == error_mark_node)
|
||||
return error_mark_node;
|
||||
}
|
||||
if (binfo != NULL_TREE)
|
||||
{
|
||||
if (lvalue_p (e))
|
||||
{
|
||||
e = build_unary_op (ADDR_EXPR, e, 0);
|
||||
|
||||
if (! BINFO_OFFSET_ZEROP (binfo))
|
||||
e = build (PLUS_EXPR, TYPE_POINTER_TO (type),
|
||||
e, BINFO_OFFSET (binfo));
|
||||
return build1 (INDIRECT_REF, type, e);
|
||||
}
|
||||
|
||||
sorry ("addressable aggregates");
|
||||
return error_mark_node;
|
||||
}
|
||||
error ("conversion between incompatible aggregate types requested");
|
||||
if (ctor == error_mark_node)
|
||||
{
|
||||
cp_error ("in conversion to type `%T'", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
/* conversion from non-aggregate to aggregate type requires
|
||||
constructor. */
|
||||
else if (TYPE_HAS_CONSTRUCTOR (type))
|
||||
|
||||
if (conversion && ctor)
|
||||
{
|
||||
tree rval;
|
||||
tree init = build_method_call (NULL_TREE, constructor_name_full (type),
|
||||
build_tree_list (NULL_TREE, e),
|
||||
TYPE_BINFO (type), LOOKUP_NORMAL);
|
||||
if (init == error_mark_node)
|
||||
error ("both constructor and type conversion operator apply");
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (conversion)
|
||||
return conversion;
|
||||
else if (ctor)
|
||||
{
|
||||
if (current_function_decl)
|
||||
/* We can't pass 1 to the with_cleanup_p arg here, because that
|
||||
screws up passing classes by value. */
|
||||
ctor = build_cplus_new (type, ctor, 0);
|
||||
else
|
||||
{
|
||||
cp_error ("in conversion to type `%T'", type);
|
||||
return error_mark_node;
|
||||
register tree parm = TREE_OPERAND (ctor, 1);
|
||||
|
||||
/* Initializers for static variables and parameters
|
||||
have to handle doing the initialization and
|
||||
cleanup themselves. */
|
||||
my_friendly_assert (TREE_CODE (ctor) == CALL_EXPR, 322);
|
||||
#if 0
|
||||
/* The following assertion fails in cases where we
|
||||
are initializing a static member variable of a
|
||||
particular instance of a template class with a
|
||||
call to a constructor of the given instance, as
|
||||
in:
|
||||
|
||||
TMPL<int> object = TMPL<int>();
|
||||
|
||||
Curiously, the assertion does not fail if we do
|
||||
the same thing for a static member of a
|
||||
non-template class, as in:
|
||||
|
||||
T object = T();
|
||||
|
||||
I can't see why we should care here whether or not
|
||||
the initializer expression involves a call to
|
||||
`new', so for the time being, it seems best to
|
||||
just avoid doing this assertion. */
|
||||
my_friendly_assert (TREE_CALLS_NEW (TREE_VALUE (parm)),
|
||||
323);
|
||||
#endif
|
||||
TREE_VALUE (parm) = NULL_TREE;
|
||||
ctor = build_indirect_ref (ctor, NULL_PTR);
|
||||
TREE_HAS_CONSTRUCTOR (ctor) = 1;
|
||||
}
|
||||
/* We can't pass 1 to the with_cleanup_p arg here, because that
|
||||
screws up passing classes by value. */
|
||||
rval = build_cplus_new (type, init, 0);
|
||||
return rval;
|
||||
return ctor;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1483,9 +1476,9 @@ build_type_conversion_1 (xtype, basetype, expr, typename, for_sure)
|
|||
int flags;
|
||||
|
||||
if (for_sure == 0)
|
||||
flags = LOOKUP_PROTECT;
|
||||
flags = LOOKUP_PROTECT|LOOKUP_ONLYCONVERTING;
|
||||
else
|
||||
flags = LOOKUP_NORMAL;
|
||||
flags = LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING;
|
||||
|
||||
rval = build_method_call (expr, typename, NULL_TREE, NULL_TREE, flags);
|
||||
if (rval == error_mark_node)
|
||||
|
@ -1615,9 +1608,9 @@ build_type_conversion (code, xtype, expr, for_sure)
|
|||
int flags;
|
||||
|
||||
if (for_sure == 0)
|
||||
flags = LOOKUP_PROTECT;
|
||||
flags = LOOKUP_PROTECT|LOOKUP_ONLYCONVERTING;
|
||||
else
|
||||
flags = LOOKUP_NORMAL;
|
||||
flags = LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING;
|
||||
rval = build_method_call (expr,
|
||||
constructor_name_full (typename),
|
||||
NULL_TREE, NULL_TREE, flags);
|
||||
|
|
546
gcc/cp/decl.c
546
gcc/cp/decl.c
|
@ -234,11 +234,27 @@ tree int_ftype_cptr_cptr_sizet;
|
|||
/* C++ extensions */
|
||||
tree vtable_entry_type;
|
||||
tree delta_type_node;
|
||||
tree __t_desc_type_node, __i_desc_type_node, __m_desc_type_node;
|
||||
#if 0
|
||||
/* Old rtti stuff. */
|
||||
tree __baselist_desc_type_node;
|
||||
tree __i_desc_type_node, __m_desc_type_node;
|
||||
tree __t_desc_array_type, __i_desc_array_type, __m_desc_array_type;
|
||||
#endif
|
||||
tree __t_desc_type_node, __tp_desc_type_node;
|
||||
tree __access_mode_type_node;
|
||||
tree __bltn_desc_type_node, __user_desc_type_node, __class_desc_type_node;
|
||||
tree __ptr_desc_type_node, __attr_desc_type_node, __func_desc_type_node;
|
||||
tree __ptmf_desc_type_node, __ptmd_desc_type_node;
|
||||
#if 0
|
||||
/* Not needed yet? May be needed one day? */
|
||||
tree __bltn_desc_array_type, __user_desc_array_type, __class_desc_array_type;
|
||||
tree __ptr_desc_array_type, __attr_dec_array_type, __func_desc_array_type;
|
||||
tree __ptmf_desc_array_type, __ptmd_desc_array_type;
|
||||
#endif
|
||||
|
||||
tree class_star_type_node;
|
||||
tree class_type_node, record_type_node, union_type_node, enum_type_node;
|
||||
tree exception_type_node, unknown_type_node;
|
||||
tree unknown_type_node;
|
||||
tree opaque_type_node, signature_type_node;
|
||||
tree sigtable_entry_type;
|
||||
tree maybe_gc_cleanup;
|
||||
|
@ -1729,10 +1745,7 @@ pushtag (name, type, globalize)
|
|||
TYPE_NAME (type) = name;
|
||||
|
||||
/* Do C++ gratuitous typedefing. */
|
||||
if (IDENTIFIER_TYPE_VALUE (name) != type
|
||||
&& (TREE_CODE (type) != RECORD_TYPE
|
||||
|| b->parm_flag != 2
|
||||
|| !CLASSTYPE_DECLARED_EXCEPTION (type)))
|
||||
if (IDENTIFIER_TYPE_VALUE (name) != type)
|
||||
{
|
||||
register tree d;
|
||||
int newdecl = 0;
|
||||
|
@ -2055,7 +2068,7 @@ warn_extern_redeclared_static (newdecl, olddecl)
|
|||
return;
|
||||
|
||||
name = DECL_ASSEMBLER_NAME (newdecl);
|
||||
if (TREE_PUBLIC (name) && ! TREE_PUBLIC (newdecl))
|
||||
if (TREE_PUBLIC (name) && ! DECL_PUBLIC (newdecl))
|
||||
{
|
||||
/* It's okay to redeclare an ANSI built-in function as static,
|
||||
or to declare a non-ANSI built-in function as anything. */
|
||||
|
@ -2119,7 +2132,7 @@ duplicate_decls (newdecl, olddecl)
|
|||
/* If you declare a built-in or predefined function name as static,
|
||||
the old definition is overridden, but optionally warn this was a
|
||||
bad choice of name. Ditto for overloads. */
|
||||
if (! TREE_PUBLIC (newdecl)
|
||||
if (! DECL_PUBLIC (newdecl)
|
||||
|| (TREE_CODE (newdecl) == FUNCTION_DECL
|
||||
&& DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl)))
|
||||
{
|
||||
|
@ -2453,33 +2466,29 @@ duplicate_decls (newdecl, olddecl)
|
|||
{
|
||||
TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
|
||||
DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
|
||||
TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
|
||||
|
||||
if (TREE_CODE (newdecl) != FUNCTION_DECL)
|
||||
TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
|
||||
if (TREE_CODE (newdecl) == FUNCTION_DECL)
|
||||
{
|
||||
DECL_DECLARED_STATIC (newdecl) = DECL_DECLARED_STATIC (olddecl);
|
||||
DECL_INTERFACE_KNOWN (newdecl) = DECL_INTERFACE_KNOWN (olddecl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
|
||||
/* A `const' which was not declared `extern' and is
|
||||
in static storage is invisible. */
|
||||
/* A `const' which was not declared `extern' gets internal linkage. */
|
||||
if (TREE_CODE (newdecl) == VAR_DECL
|
||||
&& TREE_READONLY (newdecl) && TREE_STATIC (newdecl)
|
||||
&& ! DECL_THIS_EXTERN (newdecl))
|
||||
&& TREE_READONLY (newdecl) && ! DECL_THIS_EXTERN (newdecl))
|
||||
TREE_PUBLIC (newdecl) = 0;
|
||||
else if (TREE_CODE (newdecl) != FUNCTION_DECL)
|
||||
TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
|
||||
}
|
||||
else
|
||||
{
|
||||
TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
|
||||
|
||||
/* For functions, static overrides non-static. */
|
||||
if (TREE_CODE (newdecl) == FUNCTION_DECL)
|
||||
{
|
||||
TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
|
||||
/* This is since we don't automatically
|
||||
copy the attributes of NEWDECL into OLDDECL. */
|
||||
TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
|
||||
/* If this clears `static', clear it in the identifier too. */
|
||||
if (! TREE_PUBLIC (olddecl))
|
||||
TREE_PUBLIC (DECL_ASSEMBLER_NAME (olddecl)) = 0;
|
||||
/* If this clears PUBLIC, clear it in the identifier too. */
|
||||
if (TREE_CODE (newdecl) == FUNCTION_DECL && ! TREE_PUBLIC (olddecl))
|
||||
TREE_PUBLIC (DECL_ASSEMBLER_NAME (olddecl)) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If either decl says `inline', this fn is inline,
|
||||
|
@ -2551,6 +2560,7 @@ duplicate_decls (newdecl, olddecl)
|
|||
{
|
||||
DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
|
||||
DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl);
|
||||
DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
|
||||
}
|
||||
|
||||
if (TREE_CODE (newdecl) == FUNCTION_DECL)
|
||||
|
@ -2843,7 +2853,7 @@ pushdecl (x)
|
|||
|
||||
/* If the first global decl has external linkage,
|
||||
warn if we later see static one. */
|
||||
if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x))
|
||||
if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && DECL_PUBLIC (x))
|
||||
TREE_PUBLIC (name) = 1;
|
||||
|
||||
/* Don't install a TYPE_DECL if we already have another
|
||||
|
@ -3376,10 +3386,10 @@ redeclaration_error_message (newdecl, olddecl)
|
|||
if (DECL_LANG_SPECIFIC (olddecl) && DECL_ABSTRACT_VIRTUAL_P (olddecl))
|
||||
return 0;
|
||||
|
||||
/* Declarations of functions can insist on internal linkage
|
||||
but they can't be inconsistent with internal linkage,
|
||||
so there can be no error on that account.
|
||||
However defining the same name twice is no good. */
|
||||
/* We'll complain about linkage mismatches in
|
||||
warn_extern_redeclared_static. */
|
||||
|
||||
/* defining the same name twice is no good. */
|
||||
if (DECL_INITIAL (olddecl) != NULL_TREE
|
||||
&& DECL_INITIAL (newdecl) != NULL_TREE
|
||||
/* However, defining once as extern inline and a second
|
||||
|
@ -3415,13 +3425,12 @@ redeclaration_error_message (newdecl, olddecl)
|
|||
else if (current_binding_level == global_binding_level)
|
||||
{
|
||||
/* Objects declared at top level: */
|
||||
/* Insist that the linkage match. */
|
||||
if (! TREE_PUBLIC (newdecl) && TREE_PUBLIC (olddecl))
|
||||
return "conflicting declarations of `%#D'";
|
||||
/* If at least one is a reference, it's ok. */
|
||||
if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl))
|
||||
return 0;
|
||||
/* Now we have two tentative defs, or one tentative and one real def. */
|
||||
/* Insist that the linkage match. */
|
||||
if (TREE_PUBLIC (olddecl) != TREE_PUBLIC (newdecl))
|
||||
return "conflicting declarations of `%#D'";
|
||||
/* Reject two definitions. */
|
||||
return "redefinition of `%#D'";
|
||||
}
|
||||
|
@ -4134,7 +4143,7 @@ record_builtin_type (rid_index, name, type)
|
|||
}
|
||||
}
|
||||
|
||||
if (flag_dossier)
|
||||
if (flag_rtti)
|
||||
{
|
||||
if (builtin_type_tdescs_len+5 >= builtin_type_tdescs_max)
|
||||
{
|
||||
|
@ -4254,7 +4263,7 @@ init_decl_processing ()
|
|||
#endif
|
||||
|
||||
gcc_obstack_init (&decl_obstack);
|
||||
if (flag_dossier)
|
||||
if (flag_rtti)
|
||||
{
|
||||
builtin_type_tdescs_max = 100;
|
||||
builtin_type_tdescs_arr = (tree *)xmalloc (100 * sizeof (tree));
|
||||
|
@ -4839,7 +4848,8 @@ init_decl_processing ()
|
|||
record_builtin_type (RID_MAX, SIGTABLE_PTR_TYPE, sigtable_entry_type);
|
||||
}
|
||||
|
||||
if (flag_dossier)
|
||||
#if 0
|
||||
if (flag_rtti)
|
||||
{
|
||||
/* Must build __t_desc type. Currently, type descriptors look like this:
|
||||
|
||||
|
@ -4950,9 +4960,7 @@ init_decl_processing ()
|
|||
integer_type_node);
|
||||
}
|
||||
|
||||
/* Now, C++. */
|
||||
current_lang_name = lang_name_cplusplus;
|
||||
if (flag_dossier)
|
||||
if (flag_rtti)
|
||||
{
|
||||
int i = builtin_type_tdescs_len;
|
||||
while (i > 0)
|
||||
|
@ -4962,6 +4970,10 @@ init_decl_processing ()
|
|||
TREE_PUBLIC (TREE_OPERAND (tdesc, 0)) = 1;
|
||||
}
|
||||
}
|
||||
#endif /*flag_rtti*/
|
||||
|
||||
/* Now, C++. */
|
||||
current_lang_name = lang_name_cplusplus;
|
||||
|
||||
auto_function (ansi_opname[(int) NEW_EXPR],
|
||||
build_function_type (ptr_type_node,
|
||||
|
@ -5016,6 +5028,74 @@ init_decl_processing ()
|
|||
init_function_format_info ();
|
||||
}
|
||||
|
||||
/* initialize type descriptor type node of various rtti type. */
|
||||
|
||||
int
|
||||
init_type_desc()
|
||||
{
|
||||
tree tdecl;
|
||||
|
||||
tdecl = lookup_name (get_identifier ("type_info"), 0);
|
||||
if (tdecl == NULL_TREE)
|
||||
return 0;
|
||||
__t_desc_type_node = TREE_TYPE(tdecl);
|
||||
__tp_desc_type_node = build_pointer_type (__t_desc_type_node);
|
||||
|
||||
#if 0
|
||||
tdecl = lookup_name (get_identifier ("__baselist_type_info"), 0);
|
||||
if (tdecl == NULL_TREE)
|
||||
return 0;
|
||||
__baselist_desc_type_node = TREE_TYPE (tdecl);
|
||||
#endif
|
||||
|
||||
tdecl = lookup_name (get_identifier ("__builtin_type_info"), 0);
|
||||
if (tdecl == NULL_TREE)
|
||||
return 0;
|
||||
__bltn_desc_type_node = TREE_TYPE (tdecl);
|
||||
|
||||
tdecl = lookup_name (get_identifier ("__user_type_info"), 0);
|
||||
if (tdecl == NULL_TREE)
|
||||
return 0;
|
||||
__user_desc_type_node = TREE_TYPE (tdecl);
|
||||
|
||||
tdecl = lookup_name (get_identifier ("__class_type_info"), 0);
|
||||
if (tdecl == NULL_TREE)
|
||||
return 0;
|
||||
__class_desc_type_node = TREE_TYPE (tdecl);
|
||||
|
||||
tdecl = lookup_field (__class_desc_type_node,
|
||||
get_identifier ("access_mode"), 0, 0);
|
||||
if (tdecl == NULL_TREE)
|
||||
return 0;
|
||||
__access_mode_type_node = TREE_TYPE (tdecl);
|
||||
|
||||
tdecl = lookup_name (get_identifier ("__attr_type_info"), 0);
|
||||
if (tdecl == NULL_TREE)
|
||||
return 0;
|
||||
__attr_desc_type_node = TREE_TYPE (tdecl);
|
||||
|
||||
tdecl = lookup_name (get_identifier ("__pointer_type_info"), 0);
|
||||
if (tdecl == NULL_TREE)
|
||||
return 0;
|
||||
__ptr_desc_type_node = TREE_TYPE (tdecl);
|
||||
|
||||
tdecl = lookup_name (get_identifier ("__func_type_info"), 0);
|
||||
if (tdecl == NULL_TREE)
|
||||
return 0;
|
||||
__func_desc_type_node = TREE_TYPE (tdecl);
|
||||
|
||||
tdecl = lookup_name (get_identifier ("__ptmf_type_info"), 0);
|
||||
if (tdecl == NULL_TREE)
|
||||
return 0;
|
||||
__ptmf_desc_type_node = TREE_TYPE (tdecl);
|
||||
|
||||
tdecl = lookup_name (get_identifier ("__ptmd_type_info"), 0);
|
||||
if (tdecl == NULL_TREE)
|
||||
return 0;
|
||||
__ptmd_desc_type_node = TREE_TYPE (tdecl);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* Make a definition for a builtin function named NAME and whose data type
|
||||
is TYPE. TYPE should be a function type with argument types.
|
||||
FUNCTION_CODE tells later passes how to compile calls to this function.
|
||||
|
@ -5035,6 +5115,7 @@ define_function (name, type, function_code, pfn, library_name)
|
|||
tree decl = build_lang_decl (FUNCTION_DECL, get_identifier (name), type);
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
DECL_INTERFACE_KNOWN (decl) = 1;
|
||||
|
||||
/* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME,
|
||||
we cannot change DECL_ASSEMBLER_NAME until we have installed this
|
||||
|
@ -5213,11 +5294,6 @@ start_decl (declarator, declspecs, initialized, raises)
|
|||
pop_obstacks ();
|
||||
}
|
||||
|
||||
/* Interesting work for this is done in `finish_exception_decl'. */
|
||||
if (TREE_CODE (type) == RECORD_TYPE
|
||||
&& CLASSTYPE_DECLARED_EXCEPTION (type))
|
||||
return decl;
|
||||
|
||||
/* Corresponding pop_obstacks is done in `finish_decl'. */
|
||||
push_obstacks_nochange ();
|
||||
|
||||
|
@ -5258,9 +5334,6 @@ start_decl (declarator, declspecs, initialized, raises)
|
|||
DECL_ARGUMENTS (decl) = args;
|
||||
}
|
||||
d = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), TREE_TYPE (decl));
|
||||
if (interface_unknown && flag_external_templates
|
||||
&& ! DECL_IN_SYSTEM_HEADER (decl))
|
||||
warn_if_unknown_interface ();
|
||||
TREE_PUBLIC (d) = TREE_PUBLIC (decl);
|
||||
TREE_STATIC (d) = TREE_STATIC (decl);
|
||||
DECL_EXTERNAL (d) = (DECL_EXTERNAL (decl)
|
||||
|
@ -5751,12 +5824,6 @@ finish_decl (decl, init, asmspec_tree, need_pop)
|
|||
DECL_CONTEXT (decl) == NULL_TREE, 0);
|
||||
goto finish_end;
|
||||
}
|
||||
if (type != error_mark_node && IS_AGGR_TYPE (type)
|
||||
&& CLASSTYPE_DECLARED_EXCEPTION (type))
|
||||
{
|
||||
CLASSTYPE_GOT_SEMICOLON (type) = 1;
|
||||
goto finish_end;
|
||||
}
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL)
|
||||
{
|
||||
ttype = target_type (type);
|
||||
|
@ -6158,7 +6225,7 @@ finish_decl (decl, init, asmspec_tree, need_pop)
|
|||
else if (toplev && ! TREE_PUBLIC (decl))
|
||||
{
|
||||
/* If this is a static const, change its apparent linkage
|
||||
if it belongs to a #pragma interface. */
|
||||
if it belongs to a #pragma interface. */
|
||||
if (!interface_unknown)
|
||||
{
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
|
@ -6623,8 +6690,14 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
|
|||
DECL_CLASS_CONTEXT (decl) = ctype;
|
||||
}
|
||||
|
||||
/* All function decls start out public; we'll fix their linkage later (at
|
||||
definition or EOF) if appropriate. */
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
|
||||
if (publicp)
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
;
|
||||
else
|
||||
DECL_DECLARED_STATIC (decl) = 1;
|
||||
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE)
|
||||
|
@ -6876,7 +6949,7 @@ build_ptrmemfunc_type (type)
|
|||
t = make_lang_type (RECORD_TYPE);
|
||||
|
||||
/* Let the front-end know this is a pointer to member function. */
|
||||
TYPE_PTRMEMFUNC_FLAG(t) = 1;
|
||||
TYPE_PTRMEMFUNC_FLAG (t) = 1;
|
||||
/* and not really an aggregate. */
|
||||
IS_AGGR_TYPE (t) = 0;
|
||||
|
||||
|
@ -6920,6 +6993,7 @@ build_ptrmemfunc_type (type)
|
|||
try to parse.
|
||||
PARM for a parameter declaration (either within a function prototype
|
||||
or before a function body). Make a PARM_DECL, or return void_type_node.
|
||||
CATCHPARM for a parameter declaration before a catch clause.
|
||||
TYPENAME if for a typename (in a cast or sizeof).
|
||||
Don't make a DECL node; just return the ..._TYPE node.
|
||||
FIELD for a struct or union field; make a FIELD_DECL.
|
||||
|
@ -6972,7 +7046,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
int longlong = 0;
|
||||
int constp;
|
||||
int volatilep;
|
||||
int virtualp, friendp, inlinep, staticp;
|
||||
int virtualp, explicitp, friendp, inlinep, staticp;
|
||||
int explicit_int = 0;
|
||||
int explicit_char = 0;
|
||||
int opaque_typedef = 0;
|
||||
|
@ -7553,6 +7627,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
warning ("duplicate `volatile'");
|
||||
#endif
|
||||
virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits);
|
||||
RIDBIT_RESET (RID_VIRTUAL, specbits);
|
||||
explicitp = RIDBIT_SETP (RID_EXPLICIT, specbits) != 0;
|
||||
RIDBIT_RESET (RID_EXPLICIT, specbits);
|
||||
|
||||
if (RIDBIT_SETP (RID_STATIC, specbits))
|
||||
staticp = 1 + (decl_context == FIELD);
|
||||
|
@ -7564,37 +7641,36 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
staticp = 0;
|
||||
}
|
||||
friendp = RIDBIT_SETP (RID_FRIEND, specbits);
|
||||
RIDBIT_RESET (RID_VIRTUAL, specbits);
|
||||
RIDBIT_RESET (RID_FRIEND, specbits);
|
||||
|
||||
if (RIDBIT_SETP (RID_MUTABLE, specbits))
|
||||
{
|
||||
if (decl_context == PARM)
|
||||
{
|
||||
error ("non-member `%s' cannot be declared mutable", name);
|
||||
error ("non-member `%s' cannot be declared `mutable'", name);
|
||||
RIDBIT_RESET (RID_MUTABLE, specbits);
|
||||
}
|
||||
else if (friendp || decl_context == TYPENAME)
|
||||
{
|
||||
error ("non-object member `%s' cannot be declared mutable", name);
|
||||
error ("non-object member `%s' cannot be declared `mutable'", name);
|
||||
RIDBIT_RESET (RID_MUTABLE, specbits);
|
||||
}
|
||||
else if (staticp)
|
||||
{
|
||||
error ("static `%s' cannot be declared mutable", name);
|
||||
error ("static `%s' cannot be declared `mutable'", name);
|
||||
RIDBIT_RESET (RID_MUTABLE, specbits);
|
||||
}
|
||||
#if 0
|
||||
if (RIDBIT_SETP (RID_TYPEDEF, specbits))
|
||||
{
|
||||
error ("non-object member `%s' cannot be declared mutable", name);
|
||||
error ("non-object member `%s' cannot be declared `mutable'", name);
|
||||
RIDBIT_RESET (RID_MUTABLE, specbits);
|
||||
}
|
||||
/* Because local typedefs are parsed twice, we don't want this
|
||||
message here. */
|
||||
else if (decl_context != FIELD)
|
||||
{
|
||||
error ("non-member `%s' cannot be declared mutable", name);
|
||||
error ("non-member `%s' cannot be declared `mutable'", name);
|
||||
RIDBIT_RESET (RID_MUTABLE, specbits);
|
||||
}
|
||||
#endif
|
||||
|
@ -7682,7 +7758,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
error ("multiple storage classes in declaration of `%s'", name);
|
||||
else if (decl_context != NORMAL && nclasses > 0)
|
||||
{
|
||||
if (decl_context == PARM
|
||||
if ((decl_context == PARM || decl_context == CATCHPARM)
|
||||
&& (RIDBIT_SETP (RID_REGISTER, specbits)
|
||||
|| RIDBIT_SETP (RID_AUTO, specbits)))
|
||||
;
|
||||
|
@ -7782,7 +7858,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
op ? operator_name_string (tmp) : name);
|
||||
}
|
||||
else
|
||||
error ((decl_context == PARM
|
||||
error (((decl_context == PARM || decl_context == CATCHPARM)
|
||||
? "storage class specified for parameter `%s'"
|
||||
: "storage class specified for typename"), name);
|
||||
RIDBIT_RESET (RID_REGISTER, specbits);
|
||||
|
@ -8107,6 +8183,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
}
|
||||
else /* it's a constructor. */
|
||||
{
|
||||
if (explicitp == 1)
|
||||
explicitp = 2;
|
||||
/* ANSI C++ June 5 1992 WP 12.1.2. A constructor may
|
||||
not be declared const or volatile. A constructor may
|
||||
not be virtual. A constructor may not be static. */
|
||||
|
@ -8389,10 +8467,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
/* This is the `standard' use of the scoping operator:
|
||||
basetype :: member . */
|
||||
|
||||
if (TREE_CODE (type) == FUNCTION_TYPE)
|
||||
if (ctype == current_class_type)
|
||||
cp_pedwarn ("extra qualification `%T::' on member `%s' ignored",
|
||||
ctype, name);
|
||||
else if (TREE_CODE (type) == FUNCTION_TYPE)
|
||||
{
|
||||
if (current_class_type == NULL_TREE
|
||||
|| TYPE_MAIN_VARIANT (ctype) == current_class_type
|
||||
|| friendp)
|
||||
type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep),
|
||||
TREE_TYPE (type), TYPE_ARG_TYPES (type));
|
||||
|
@ -8403,19 +8483,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
return void_type_node;
|
||||
}
|
||||
}
|
||||
else if (TYPE_MAIN_VARIANT (ctype) == current_class_type)
|
||||
{
|
||||
if (extra_warnings)
|
||||
cp_warning ("redundant qualification `%T' on member `%s' ignored",
|
||||
ctype, name);
|
||||
type = build_offset_type (ctype, type);
|
||||
}
|
||||
else if (TYPE_SIZE (ctype) != NULL_TREE
|
||||
|| (RIDBIT_SETP (RID_TYPEDEF, specbits)))
|
||||
{
|
||||
tree t;
|
||||
/* have to move this code elsewhere in this function.
|
||||
this code is used for i.e., typedef int A::M; M *pm; */
|
||||
this code is used for i.e., typedef int A::M; M *pm;
|
||||
|
||||
It is? How? jason 10/2/94 */
|
||||
|
||||
if (explicit_int == -1 && decl_context == FIELD
|
||||
&& funcdef_flag == 0)
|
||||
|
@ -8441,7 +8516,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
/* Don't include destructor with constructors. */
|
||||
t = DECL_CHAIN (TREE_VALUE (t));
|
||||
if (t == NULL_TREE)
|
||||
error ("class `%s' does not have any constructors", IDENTIFIER_POINTER (sname));
|
||||
cp_error ("`%T' does not have any constructors",
|
||||
ctype);
|
||||
t = build_tree_list (NULL_TREE, t);
|
||||
}
|
||||
t = build_lang_field_decl (FIELD_DECL, build_nt (SCOPE_REF, ctype, t), type);
|
||||
|
@ -8456,15 +8532,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
|
||||
if (current_class_type)
|
||||
{
|
||||
if (TYPE_MAIN_VARIANT (ctype) != current_class_type)
|
||||
{
|
||||
cp_error ("cannot declare member `%T::%s' within `%T'",
|
||||
ctype, name, current_class_type);
|
||||
return void_type_node;
|
||||
}
|
||||
else if (extra_warnings)
|
||||
cp_warning ("extra qualification `%T' on member `%s' ignored",
|
||||
ctype, name);
|
||||
cp_error ("cannot declare member `%T::%s' within `%T'",
|
||||
ctype, name, current_class_type);
|
||||
return void_type_node;
|
||||
}
|
||||
type = build_offset_type (ctype, type);
|
||||
}
|
||||
|
@ -8526,6 +8596,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
}
|
||||
}
|
||||
|
||||
if (explicitp == 1)
|
||||
{
|
||||
error ("only constructors can be declared `explicit'");
|
||||
explicitp = 0;
|
||||
}
|
||||
|
||||
/* Now TYPE has the actual type. */
|
||||
|
||||
/* If this is declaring a typedef name, return a TYPE_DECL. */
|
||||
|
@ -8658,6 +8734,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
return type;
|
||||
}
|
||||
else if (declarator == NULL_TREE && decl_context != PARM
|
||||
&& decl_context != CATCHPARM
|
||||
&& TREE_CODE (type) != UNION_TYPE
|
||||
&& ! bitfield)
|
||||
{
|
||||
|
@ -8803,6 +8880,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
if (decl == NULL_TREE)
|
||||
return NULL_TREE;
|
||||
|
||||
if (explicitp == 2)
|
||||
DECL_NONCONVERTING_P (decl) = 1;
|
||||
|
||||
DECL_INLINE (decl) = inlinep;
|
||||
}
|
||||
else if (TREE_CODE (type) == METHOD_TYPE)
|
||||
|
@ -8817,20 +8897,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
|
||||
DECL_INLINE (decl) = inlinep;
|
||||
}
|
||||
else if (TREE_CODE (type) == RECORD_TYPE
|
||||
&& CLASSTYPE_DECLARED_EXCEPTION (type))
|
||||
{
|
||||
/* Handle a class-local exception declaration. */
|
||||
decl = build_lang_field_decl (VAR_DECL, declarator, type);
|
||||
if (ctype == NULL_TREE)
|
||||
ctype = current_class_type;
|
||||
return void_type_node;
|
||||
}
|
||||
else if (TYPE_SIZE (type) == NULL_TREE && !staticp
|
||||
&& (TREE_CODE (type) != ARRAY_TYPE || initialized == 0))
|
||||
{
|
||||
error ("field `%s' has incomplete type",
|
||||
IDENTIFIER_POINTER (declarator));
|
||||
cp_error ("field `%D' has incomplete type", declarator);
|
||||
|
||||
/* If we're instantiating a template, tell them which
|
||||
instantiation made the field's type be incomplete. */
|
||||
|
@ -8839,9 +8909,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
&& IDENTIFIER_TEMPLATE (DECL_NAME (TYPE_NAME (current_class_type)))
|
||||
&& declspecs && TREE_VALUE (declspecs)
|
||||
&& TREE_TYPE (TREE_VALUE (declspecs)) == type)
|
||||
error (" in instantiation of template `%s'",
|
||||
TYPE_NAME_STRING (current_class_type));
|
||||
|
||||
cp_error (" in instantiation of template `%T'",
|
||||
current_class_type);
|
||||
|
||||
type = error_mark_node;
|
||||
decl = NULL_TREE;
|
||||
}
|
||||
|
@ -9062,6 +9132,31 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
{
|
||||
/* It's a variable. */
|
||||
|
||||
if (decl_context == CATCHPARM)
|
||||
{
|
||||
if (ctype)
|
||||
{
|
||||
ctype = NULL_TREE;
|
||||
error ("cannot use `::' in parameter declaration");
|
||||
}
|
||||
|
||||
/* A parameter declared as an array of T is really a pointer to T.
|
||||
One declared as a function is really a pointer to a function.
|
||||
One declared as a member is really a pointer to member. */
|
||||
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
/* Transfer const-ness of array into that of type pointed to. */
|
||||
type = build_pointer_type
|
||||
(cp_build_type_variant (TREE_TYPE (type), constp, volatilep));
|
||||
volatilep = constp = 0;
|
||||
}
|
||||
else if (TREE_CODE (type) == FUNCTION_TYPE)
|
||||
type = build_pointer_type (type);
|
||||
else if (TREE_CODE (type) == OFFSET_TYPE)
|
||||
type = build_pointer_type (type);
|
||||
}
|
||||
|
||||
/* An uninitialized decl with `extern' is a reference. */
|
||||
decl = grokvardecl (type, declarator, specbits, initialized);
|
||||
bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE,
|
||||
|
@ -9850,7 +9945,6 @@ xref_tag (code_type_node, name, binfo, globalize)
|
|||
{
|
||||
case record_type:
|
||||
case class_type:
|
||||
case exception_type:
|
||||
case signature_type:
|
||||
code = RECORD_TYPE;
|
||||
len = list_length (binfo);
|
||||
|
@ -9949,17 +10043,6 @@ xref_tag (code_type_node, name, binfo, globalize)
|
|||
if (flag_cadillac)
|
||||
cadillac_start_enum (ref);
|
||||
}
|
||||
else if (tag_code == exception_type)
|
||||
{
|
||||
ref = make_lang_type (code);
|
||||
/* Enable us to recognize when an exception type is created in
|
||||
class context. To do nested classes correctly, this should
|
||||
probably be cleared out when we leave this class's scope. */
|
||||
CLASSTYPE_DECLARED_EXCEPTION (ref) = 1;
|
||||
pushtag (name, ref, globalize);
|
||||
if (flag_cadillac)
|
||||
cadillac_start_struct (ref);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct binding_level *old_b = class_binding_level;
|
||||
|
@ -9990,17 +10073,6 @@ xref_tag (code_type_node, name, binfo, globalize)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (IS_AGGR_TYPE_CODE (code))
|
||||
{
|
||||
if (IS_AGGR_TYPE (ref)
|
||||
&& ((tag_code == exception_type)
|
||||
!= (CLASSTYPE_DECLARED_EXCEPTION (ref) == 1)))
|
||||
{
|
||||
cp_error ("type `%T' is both exception and aggregate type", ref);
|
||||
CLASSTYPE_DECLARED_EXCEPTION (ref) = (tag_code == exception_type);
|
||||
}
|
||||
}
|
||||
|
||||
/* If it no longer looks like a nested type, make sure it's
|
||||
in global scope. */
|
||||
if (b == global_binding_level && !class_binding_level
|
||||
|
@ -10666,6 +10738,42 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
|
|||
(This does not mean `static' in the C sense!) */
|
||||
TREE_STATIC (decl1) = 1;
|
||||
|
||||
if (DECL_INTERFACE_KNOWN (decl1))
|
||||
/* We know. */;
|
||||
/* If this function belongs to an interface, it is public.
|
||||
If it belongs to someone else's interface, it is also external.
|
||||
It doesn't matter whether it's inline or not. */
|
||||
else if (interface_unknown == 0)
|
||||
{
|
||||
if (DECL_DECLARED_STATIC (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1))
|
||||
DECL_EXTERNAL (decl1)
|
||||
= (interface_only
|
||||
|| (DECL_INLINE (decl1) && ! flag_implement_inlines));
|
||||
else
|
||||
DECL_EXTERNAL (decl1) = current_extern_inline;
|
||||
DECL_INTERFACE_KNOWN (decl1) = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is a definition, not a reference.
|
||||
So normally clear DECL_EXTERNAL.
|
||||
However, `extern inline' acts like a declaration except for
|
||||
defining how to inline. So set DECL_EXTERNAL in that case. */
|
||||
DECL_EXTERNAL (decl1) = current_extern_inline;
|
||||
|
||||
if (DECL_INLINE (decl1) && (DECL_FUNCTION_MEMBER_P (decl1)
|
||||
|| DECL_TEMPLATE_INSTANTIATION (decl1)))
|
||||
/* We know nothing yet */;
|
||||
else
|
||||
{
|
||||
DECL_INTERFACE_KNOWN (decl1) = 1;
|
||||
if (DECL_DECLARED_STATIC (decl1))
|
||||
TREE_PUBLIC (decl1) = 0;
|
||||
}
|
||||
|
||||
DECL_DEFER_OUTPUT (decl1) = ! DECL_INTERFACE_KNOWN (decl1);
|
||||
}
|
||||
|
||||
/* Record the decl so that the function name is defined.
|
||||
If we already have a decl for this name, and it is a FUNCTION_DECL,
|
||||
use the old decl. */
|
||||
|
@ -10679,31 +10787,6 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
|
|||
else
|
||||
current_function_decl = decl1;
|
||||
|
||||
/* If this function belongs to an interface, it is public.
|
||||
If it belongs to someone else's interface, it is also external.
|
||||
It doesn't matter whether it's inline or not. */
|
||||
if (interface_unknown == 0
|
||||
&& ! TREE_PUBLIC (decl1))
|
||||
{
|
||||
TREE_PUBLIC (decl1) = 1;
|
||||
DECL_EXTERNAL (decl1)
|
||||
= (interface_only
|
||||
|| (DECL_INLINE (decl1) && ! flag_implement_inlines));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is a definition, not a reference.
|
||||
So normally clear DECL_EXTERNAL.
|
||||
However, `extern inline' acts like a declaration except for
|
||||
defining how to inline. So set DECL_EXTERNAL in that case. */
|
||||
DECL_EXTERNAL (decl1) = current_extern_inline;
|
||||
|
||||
DECL_DEFER_OUTPUT (decl1)
|
||||
= DECL_INLINE (decl1) && ! TREE_PUBLIC (decl1)
|
||||
&& (DECL_FUNCTION_MEMBER_P (decl1)
|
||||
|| DECL_TEMPLATE_INSTANTIATION (decl1));
|
||||
}
|
||||
|
||||
if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1))
|
||||
{
|
||||
if (TREE_CODE (fntype) == METHOD_TYPE)
|
||||
|
@ -10716,18 +10799,6 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
|
|||
}
|
||||
restype = TREE_TYPE (fntype);
|
||||
|
||||
pushlevel (0);
|
||||
current_binding_level->parm_flag = 1;
|
||||
|
||||
/* Save the parm names or decls from this function's declarator
|
||||
where store_parm_decls will find them. */
|
||||
current_function_parms = last_function_parms;
|
||||
current_function_parm_tags = last_function_parm_tags;
|
||||
|
||||
GNU_xref_function (decl1, current_function_parms);
|
||||
|
||||
make_function_rtl (decl1);
|
||||
|
||||
if (ctype)
|
||||
{
|
||||
push_nested_class (ctype, 1);
|
||||
|
@ -10777,6 +10848,18 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
|
|||
push_memoized_context (0, 1);
|
||||
}
|
||||
|
||||
pushlevel (0);
|
||||
current_binding_level->parm_flag = 1;
|
||||
|
||||
/* Save the parm names or decls from this function's declarator
|
||||
where store_parm_decls will find them. */
|
||||
current_function_parms = last_function_parms;
|
||||
current_function_parm_tags = last_function_parm_tags;
|
||||
|
||||
GNU_xref_function (decl1, current_function_parms);
|
||||
|
||||
make_function_rtl (decl1);
|
||||
|
||||
/* Allocate further tree nodes temporarily during compilation
|
||||
of this function only. Tiemann moved up here from bottom of fn. */
|
||||
temporary_allocation ();
|
||||
|
@ -10972,9 +11055,11 @@ store_parm_decls ()
|
|||
if (flag_gc)
|
||||
expand_expr (build_function_call (lookup_name (get_identifier ("__gc_main"), 0), NULL_TREE),
|
||||
0, VOIDmode, 0);
|
||||
|
||||
if (flag_dossier)
|
||||
#if 0
|
||||
/* done at a differnet time */
|
||||
if (flag_rtti)
|
||||
output_builtin_tdesc_entries ();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11043,9 +11128,10 @@ store_return_init (return_id, init)
|
|||
constructors. */
|
||||
|
||||
void
|
||||
finish_function (lineno, call_poplevel)
|
||||
finish_function (lineno, call_poplevel, nested)
|
||||
int lineno;
|
||||
int call_poplevel;
|
||||
int nested;
|
||||
{
|
||||
register tree fndecl = current_function_decl;
|
||||
tree fntype, ctype = NULL_TREE;
|
||||
|
@ -11072,7 +11158,7 @@ finish_function (lineno, call_poplevel)
|
|||
store_parm_decls ();
|
||||
}
|
||||
|
||||
if (write_symbols != NO_DEBUG && TREE_CODE (fntype) != METHOD_TYPE)
|
||||
if (write_symbols != NO_DEBUG /*&& TREE_CODE (fntype) != METHOD_TYPE*/)
|
||||
{
|
||||
tree ttype = target_type (fntype);
|
||||
tree parmdecl;
|
||||
|
@ -11442,19 +11528,6 @@ finish_function (lineno, call_poplevel)
|
|||
expand_label (no_return_label);
|
||||
}
|
||||
|
||||
/* reset scope for C++: if we were in the scope of a class,
|
||||
then when we finish this function, we are not longer so.
|
||||
This cannot be done until we know for sure that no more
|
||||
class members will ever be referenced in this function
|
||||
(i.e., calls to destructors). */
|
||||
if (current_class_name)
|
||||
{
|
||||
ctype = current_class_type;
|
||||
pop_nested_class (1);
|
||||
}
|
||||
else
|
||||
pop_memoized_context (1);
|
||||
|
||||
/* Generate rtl for function exit. */
|
||||
expand_function_end (input_filename, lineno, 1);
|
||||
|
||||
|
@ -11468,6 +11541,19 @@ finish_function (lineno, call_poplevel)
|
|||
my_friendly_abort (122);
|
||||
poplevel (1, 0, 1);
|
||||
|
||||
/* reset scope for C++: if we were in the scope of a class,
|
||||
then when we finish this function, we are not longer so.
|
||||
This cannot be done until we know for sure that no more
|
||||
class members will ever be referenced in this function
|
||||
(i.e., calls to destructors). */
|
||||
if (current_class_name)
|
||||
{
|
||||
ctype = current_class_type;
|
||||
pop_nested_class (1);
|
||||
}
|
||||
else
|
||||
pop_memoized_context (1);
|
||||
|
||||
/* Must mark the RESULT_DECL as being in this function. */
|
||||
DECL_CONTEXT (DECL_RESULT (fndecl)) = DECL_INITIAL (fndecl);
|
||||
|
||||
|
@ -11554,7 +11640,8 @@ finish_function (lineno, call_poplevel)
|
|||
/* Free all the tree nodes making up this function. */
|
||||
/* Switch back to allocating nodes permanently
|
||||
until we start another function. */
|
||||
permanent_allocation (1);
|
||||
if (! nested)
|
||||
permanent_allocation (1);
|
||||
|
||||
if (flag_cadillac)
|
||||
cadillac_finish_function (fndecl);
|
||||
|
@ -11802,7 +11889,9 @@ hack_incomplete_structures (type)
|
|||
decl);
|
||||
}
|
||||
}
|
||||
/*
|
||||
my_friendly_assert (current_binding_level->n_incomplete > 0, 164);
|
||||
*/
|
||||
--current_binding_level->n_incomplete;
|
||||
}
|
||||
}
|
||||
|
@ -11980,3 +12069,100 @@ id_in_current_class (id)
|
|||
{
|
||||
return !!purpose_member (id, class_binding_level->class_shadowed);
|
||||
}
|
||||
|
||||
struct cp_function
|
||||
{
|
||||
int returns_value;
|
||||
int returns_null;
|
||||
int warn_about_return_type;
|
||||
int extern_inline;
|
||||
int assigns_this;
|
||||
int just_assigned_this;
|
||||
int parms_stored;
|
||||
tree named_labels;
|
||||
tree shadowed_labels;
|
||||
tree ctor_label;
|
||||
tree dtor_label;
|
||||
rtx result_rtx;
|
||||
struct cp_function *next;
|
||||
struct binding_level *binding_level;
|
||||
};
|
||||
|
||||
struct cp_function *cp_function_chain;
|
||||
|
||||
/* Save and reinitialize the variables
|
||||
used during compilation of a C++ function. */
|
||||
|
||||
void
|
||||
push_cp_function_context (toplev)
|
||||
int toplev;
|
||||
{
|
||||
struct cp_function *p
|
||||
= (struct cp_function *) xmalloc (sizeof (struct cp_function));
|
||||
|
||||
push_function_context_to (toplev);
|
||||
|
||||
p->next = cp_function_chain;
|
||||
cp_function_chain = p;
|
||||
|
||||
p->named_labels = named_labels;
|
||||
p->shadowed_labels = shadowed_labels;
|
||||
p->returns_value = current_function_returns_value;
|
||||
p->returns_null = current_function_returns_null;
|
||||
p->warn_about_return_type = warn_about_return_type;
|
||||
p->extern_inline = current_extern_inline;
|
||||
p->binding_level = current_binding_level;
|
||||
p->ctor_label = ctor_label;
|
||||
p->dtor_label = dtor_label;
|
||||
p->assigns_this = current_function_assigns_this;
|
||||
p->just_assigned_this = current_function_just_assigned_this;
|
||||
p->parms_stored = current_function_parms_stored;
|
||||
p->result_rtx = original_result_rtx;
|
||||
}
|
||||
|
||||
/* Restore the variables used during compilation of a C++ function. */
|
||||
|
||||
void
|
||||
pop_cp_function_context (toplev)
|
||||
int toplev;
|
||||
{
|
||||
struct cp_function *p = cp_function_chain;
|
||||
tree link;
|
||||
|
||||
/* Bring back all the labels that were shadowed. */
|
||||
for (link = shadowed_labels; link; link = TREE_CHAIN (link))
|
||||
if (DECL_NAME (TREE_VALUE (link)) != 0)
|
||||
SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)),
|
||||
TREE_VALUE (link));
|
||||
|
||||
#if 0
|
||||
if (DECL_SAVED_INSNS (current_function_decl) == 0)
|
||||
{
|
||||
/* Stop pointing to the local nodes about to be freed. */
|
||||
/* But DECL_INITIAL must remain nonzero so we know this
|
||||
was an actual function definition. */
|
||||
DECL_INITIAL (current_function_decl) = error_mark_node;
|
||||
DECL_ARGUMENTS (current_function_decl) = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
pop_function_context_from (toplev);
|
||||
|
||||
cp_function_chain = p->next;
|
||||
|
||||
named_labels = p->named_labels;
|
||||
shadowed_labels = p->shadowed_labels;
|
||||
current_function_returns_value = p->returns_value;
|
||||
current_function_returns_null = p->returns_null;
|
||||
warn_about_return_type = p->warn_about_return_type;
|
||||
current_extern_inline = p->extern_inline;
|
||||
current_binding_level = p->binding_level;
|
||||
ctor_label = p->ctor_label;
|
||||
dtor_label = p->dtor_label;
|
||||
current_function_assigns_this = p->assigns_this;
|
||||
current_function_just_assigned_this = p->just_assigned_this;
|
||||
current_function_parms_stored = p->parms_stored;
|
||||
original_result_rtx = p->result_rtx;
|
||||
|
||||
free (p);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ enum decl_context
|
|||
{ NORMAL, /* Ordinary declaration */
|
||||
FUNCDEF, /* Function definition */
|
||||
PARM, /* Declaration of parm before function body */
|
||||
CATCHPARM, /* Declaration of catch parm */
|
||||
FIELD, /* Declaration inside struct or union */
|
||||
BITFIELD, /* Likewise but with specified width */
|
||||
TYPENAME, /* Typename (inside cast or sizeof) */
|
||||
|
|
162
gcc/cp/decl2.c
162
gcc/cp/decl2.c
|
@ -301,9 +301,9 @@ int flag_cadillac;
|
|||
that can be collected when they become garbage. */
|
||||
int flag_gc;
|
||||
|
||||
/* Controls whether compiler generates 'dossiers' that give
|
||||
/* Controls whether compiler generates 'type descriptor' that give
|
||||
run-time type information. */
|
||||
int flag_dossier;
|
||||
int flag_rtti = 0;
|
||||
|
||||
/* Nonzero if we wish to output cross-referencing information
|
||||
for the GNU class browser. */
|
||||
|
@ -365,7 +365,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
|
|||
{"dollars-in-identifiers", &dollars_in_ident, 1},
|
||||
{"enum-int-equiv", &flag_int_enum_equivalence, 1},
|
||||
{"gc", &flag_gc, 1},
|
||||
{"dossier", &flag_dossier, 1},
|
||||
{"rtti", &flag_rtti, 1},
|
||||
{"xref", &flag_gnu_xref, 1},
|
||||
{"nonnull-objects", &flag_assume_nonnull_objects, 1},
|
||||
{"implement-inlines", &flag_implement_inlines, 1},
|
||||
|
@ -442,14 +442,14 @@ lang_decode_option (p)
|
|||
{
|
||||
flag_gc = 1;
|
||||
/* This must come along for the ride. */
|
||||
flag_dossier = 1;
|
||||
flag_rtti = 1;
|
||||
found = 1;
|
||||
}
|
||||
else if (! strcmp (p, "no-gc"))
|
||||
{
|
||||
flag_gc = 0;
|
||||
/* This must come along for the ride. */
|
||||
flag_dossier = 0;
|
||||
flag_rtti = 0;
|
||||
found = 1;
|
||||
}
|
||||
else if (! strcmp (p, "alt-external-templates"))
|
||||
|
@ -707,15 +707,10 @@ grok_x_components (specs, components)
|
|||
tcode = class_type_node;
|
||||
else if (IS_SIGNATURE(t))
|
||||
tcode = signature_type_node;
|
||||
else if (CLASSTYPE_DECLARED_EXCEPTION(t))
|
||||
tcode = exception_type_node;
|
||||
|
||||
t = xref_defn_tag(tcode, TYPE_IDENTIFIER(t), NULL_TREE);
|
||||
if (TYPE_CONTEXT(t))
|
||||
CLASSTYPE_NO_GLOBALIZE(t) = 1;
|
||||
if (TYPE_LANG_SPECIFIC (t)
|
||||
&& CLASSTYPE_DECLARED_EXCEPTION (t))
|
||||
shadow_tag (specs);
|
||||
return NULL_TREE;
|
||||
break;
|
||||
|
||||
|
@ -2170,7 +2165,9 @@ finish_table (name, type, init, publicp)
|
|||
if (TREE_VALUE (init) == integer_zero_node
|
||||
&& TREE_CHAIN (init) == NULL_TREE)
|
||||
{
|
||||
#if 0
|
||||
if (empty_table == NULL_TREE)
|
||||
#endif
|
||||
{
|
||||
empty_table = get_temp_name (atype, 1);
|
||||
init = build (CONSTRUCTOR, atype, NULL_TREE, init);
|
||||
|
@ -2347,9 +2344,6 @@ mark_vtable_entries (decl)
|
|||
{
|
||||
tree entries = TREE_CHAIN (CONSTRUCTOR_ELTS (DECL_INITIAL (decl)));
|
||||
|
||||
if (flag_dossier)
|
||||
entries = TREE_CHAIN (entries);
|
||||
|
||||
for (; entries; entries = TREE_CHAIN (entries))
|
||||
{
|
||||
tree fnaddr = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries));
|
||||
|
@ -2439,14 +2433,18 @@ finish_vtable_vardecl (prev, vars)
|
|||
|
||||
/* Stuff this virtual function table's size into
|
||||
`pfn' slot of `the_null_vtable_entry'. */
|
||||
#if 0
|
||||
/* we do not put size as first entry any more */
|
||||
tree nelts = array_type_nelts (TREE_TYPE (vars));
|
||||
if (flag_vtable_thunks)
|
||||
TREE_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (vars))) = nelts;
|
||||
else
|
||||
SET_FNADDR_FROM_VTABLE_ENTRY (the_null_vtable_entry, nelts);
|
||||
/* Kick out the dossier before writing out the vtable. */
|
||||
if (flag_dossier)
|
||||
rest_of_decl_compilation (TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (TREE_CHAIN (CONSTRUCTOR_ELTS (DECL_INITIAL (vars))))), 0), 0, 1, 1);
|
||||
#endif
|
||||
|
||||
/* Kick out the type descriptor before writing out the vtable. */
|
||||
if (flag_rtti)
|
||||
rest_of_decl_compilation (TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (vars)))), 0), 0, 1, 1);
|
||||
|
||||
/* Write it out. */
|
||||
mark_vtable_entries (vars);
|
||||
|
@ -2565,30 +2563,32 @@ void
|
|||
import_export_inline (decl)
|
||||
tree decl;
|
||||
{
|
||||
if (TREE_PUBLIC (decl))
|
||||
if (DECL_INTERFACE_KNOWN (decl))
|
||||
return;
|
||||
|
||||
/* If an explicit instantiation doesn't have TREE_PUBLIC set, it was with
|
||||
'extern'. */
|
||||
if (DECL_EXPLICIT_INSTANTIATION (decl)
|
||||
|| (DECL_IMPLICIT_INSTANTIATION (decl) && ! flag_implicit_templates))
|
||||
if (DECL_TEMPLATE_INSTANTIATION (decl))
|
||||
{
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
if (DECL_IMPLICIT_INSTANTIATION (decl) && flag_implicit_templates)
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
else
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
}
|
||||
else if (DECL_FUNCTION_MEMBER_P (decl))
|
||||
{
|
||||
tree ctype = DECL_CLASS_CONTEXT (decl);
|
||||
if (CLASSTYPE_INTERFACE_KNOWN (ctype))
|
||||
{
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
DECL_EXTERNAL (decl)
|
||||
= (CLASSTYPE_INTERFACE_ONLY (ctype)
|
||||
|| (DECL_INLINE (decl) && ! flag_implement_inlines));
|
||||
}
|
||||
else
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
}
|
||||
else
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
}
|
||||
|
||||
|
||||
extern int parse_time, varconst_time;
|
||||
|
||||
#define TIMEVAR(VAR, BODY) \
|
||||
|
@ -2693,7 +2693,7 @@ finish_file ()
|
|||
poplevel (1, 0, 0);
|
||||
pop_momentary ();
|
||||
|
||||
finish_function (lineno, 0);
|
||||
finish_function (lineno, 0, 0);
|
||||
|
||||
assemble_destructor (IDENTIFIER_POINTER (fnname));
|
||||
|
||||
|
@ -2818,7 +2818,7 @@ finish_file ()
|
|||
poplevel (1, 0, 0);
|
||||
pop_momentary ();
|
||||
|
||||
finish_function (lineno, 0);
|
||||
finish_function (lineno, 0, 0);
|
||||
assemble_constructor (IDENTIFIER_POINTER (fnname));
|
||||
}
|
||||
|
||||
|
@ -2871,74 +2871,86 @@ finish_file ()
|
|||
pushdecl (vars);
|
||||
#endif
|
||||
|
||||
interface_unknown = 1;
|
||||
interface_only = 0;
|
||||
|
||||
for (vars = saved_inlines; vars; vars = TREE_CHAIN (vars))
|
||||
{
|
||||
tree decl = TREE_VALUE (vars);
|
||||
|
||||
if (DECL_ARTIFICIAL (decl)
|
||||
&& ! DECL_INITIAL (decl)
|
||||
&& (TREE_USED (decl) || ! DECL_EXTERNAL (decl)))
|
||||
synthesize_method (decl);
|
||||
}
|
||||
|
||||
walk_vtables ((void (*)())0, finish_vtable_vardecl);
|
||||
if (flag_handle_signatures)
|
||||
walk_sigtables ((void (*)())0, finish_sigtable_vardecl);
|
||||
|
||||
for (vars = saved_inlines; vars; vars = TREE_CHAIN (vars))
|
||||
{
|
||||
tree decl = TREE_VALUE (vars);
|
||||
|
||||
if (DECL_ARTIFICIAL (decl)
|
||||
&& ! DECL_INITIAL (decl)
|
||||
&& TREE_USED (decl))
|
||||
synthesize_method (decl);
|
||||
}
|
||||
|
||||
for (vars = getdecls (); vars; vars = TREE_CHAIN (vars))
|
||||
{
|
||||
if (TREE_CODE (vars) == THUNK_DECL)
|
||||
emit_thunk (vars);
|
||||
else if (TREE_CODE (vars) == FUNCTION_DECL
|
||||
&& ! DECL_INTERFACE_KNOWN (vars)
|
||||
&& DECL_DECLARED_STATIC (vars))
|
||||
TREE_PUBLIC (vars) = 0;
|
||||
}
|
||||
|
||||
/* Now write out inline functions which had their addresses taken and
|
||||
which were not declared virtual and which were not declared `extern
|
||||
inline'. */
|
||||
{
|
||||
int reconsider = 0; /* More may be referenced; check again */
|
||||
tree delayed = NULL_TREE; /* These might be referenced later */
|
||||
int reconsider = 1; /* More may be referenced; check again */
|
||||
saved_inlines = tree_cons (NULL_TREE, NULL_TREE, saved_inlines);
|
||||
|
||||
/* Now write out inline functions which had their addresses taken and
|
||||
which were not declared virtual and which were not declared `extern
|
||||
inline'. */
|
||||
while (saved_inlines)
|
||||
while (reconsider)
|
||||
{
|
||||
tree decl = TREE_VALUE (saved_inlines);
|
||||
saved_inlines = TREE_CHAIN (saved_inlines);
|
||||
/* Redefinition of a member function can cause DECL_SAVED_INSNS to be
|
||||
0; don't crash. */
|
||||
if (TREE_ASM_WRITTEN (decl) || DECL_SAVED_INSNS (decl) == 0)
|
||||
continue;
|
||||
import_export_inline (decl);
|
||||
if (TREE_PUBLIC (decl)
|
||||
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
|
||||
|| flag_keep_inline_functions)
|
||||
tree last = saved_inlines;
|
||||
tree place = TREE_CHAIN (saved_inlines);
|
||||
reconsider = 0;
|
||||
|
||||
for (; place; place = TREE_CHAIN (place))
|
||||
{
|
||||
if (DECL_EXTERNAL (decl))
|
||||
assemble_external (decl);
|
||||
else
|
||||
tree decl = TREE_VALUE (place);
|
||||
|
||||
if (TREE_ASM_WRITTEN (decl) || DECL_SAVED_INSNS (decl) == 0)
|
||||
{
|
||||
reconsider = 1;
|
||||
temporary_allocation ();
|
||||
output_inline_function (decl);
|
||||
permanent_allocation (1);
|
||||
TREE_CHAIN (last) = TREE_CHAIN (place);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (TREE_USED (decl)
|
||||
|| TREE_USED (DECL_ASSEMBLER_NAME (decl)))
|
||||
delayed = tree_cons (NULL_TREE, decl, delayed);
|
||||
}
|
||||
|
||||
if (reconsider && delayed)
|
||||
{
|
||||
while (reconsider)
|
||||
{
|
||||
tree place;
|
||||
reconsider = 0;
|
||||
for (place = delayed; place; place = TREE_CHAIN (place))
|
||||
import_export_inline (decl);
|
||||
if (TREE_PUBLIC (decl)
|
||||
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
|
||||
|| flag_keep_inline_functions)
|
||||
{
|
||||
tree decl = TREE_VALUE (place);
|
||||
if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
|
||||
&& ! TREE_ASM_WRITTEN (decl))
|
||||
TREE_CHAIN (last) = TREE_CHAIN (place);
|
||||
|
||||
if (DECL_EXTERNAL (decl))
|
||||
assemble_external (decl);
|
||||
else
|
||||
{
|
||||
if (DECL_EXTERNAL (decl))
|
||||
assemble_external (decl);
|
||||
else
|
||||
{
|
||||
reconsider = 1;
|
||||
temporary_allocation ();
|
||||
output_inline_function (decl);
|
||||
permanent_allocation (1);
|
||||
}
|
||||
reconsider = 1;
|
||||
temporary_allocation ();
|
||||
output_inline_function (decl);
|
||||
permanent_allocation (1);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
last = place;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
177
gcc/cp/except.c
177
gcc/cp/except.c
|
@ -43,6 +43,9 @@ tree builtin_return_address_fndecl;
|
|||
#define TRY_NEW_EH
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__i386) || defined(__rs6000) || defined(__hppa)
|
||||
#define TRY_NEW_EH
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef TRY_NEW_EH
|
||||
|
@ -188,60 +191,6 @@ easy_expand_asm (str)
|
|||
expand_asm (build_string (strlen (str)+1, str));
|
||||
}
|
||||
|
||||
/* unwind the stack. */
|
||||
static void
|
||||
do_unwind (throw_label)
|
||||
rtx throw_label;
|
||||
{
|
||||
#ifdef sparc
|
||||
extern FILE *asm_out_file;
|
||||
tree fcall;
|
||||
tree params;
|
||||
rtx return_val_rtx;
|
||||
|
||||
/* 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, SImode, 0);
|
||||
/* In the return, the new pc is pc+8, as the value comming in is
|
||||
really the address of the call insn, not the next insn. */
|
||||
emit_move_insn (return_val_rtx, plus_constant(gen_rtx (LABEL_REF,
|
||||
Pmode,
|
||||
throw_label), -8));
|
||||
/* We use three values, PC, type, and value */
|
||||
easy_expand_asm ("st %l0,[%fp]");
|
||||
easy_expand_asm ("st %l1,[%fp+4]");
|
||||
easy_expand_asm ("st %l2,[%fp+8]");
|
||||
easy_expand_asm ("ret");
|
||||
easy_expand_asm ("restore");
|
||||
emit_barrier ();
|
||||
#endif
|
||||
#if m88k
|
||||
rtx temp_frame = frame_pointer_rtx;
|
||||
|
||||
temp_frame = memory_address (Pmode, temp_frame);
|
||||
temp_frame = copy_to_reg (gen_rtx (MEM, Pmode, temp_frame));
|
||||
|
||||
/* hopefully this will successfully pop the frame! */
|
||||
emit_move_insn (frame_pointer_rtx, temp_frame);
|
||||
emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
|
||||
emit_move_insn (arg_pointer_rtx, frame_pointer_rtx);
|
||||
emit_insn (gen_add2_insn (stack_pointer_rtx, gen_rtx (CONST_INT, VOIDmode,
|
||||
(HOST_WIDE_INT)m88k_debugger_offset (stack_pointer_rtx, 0))));
|
||||
|
||||
#if 0
|
||||
emit_insn (gen_add2_insn (arg_pointer_rtx, gen_rtx (CONST_INT, VOIDmode,
|
||||
-(HOST_WIDE_INT)m88k_debugger_offset (arg_pointer_rtx, 0))));
|
||||
|
||||
emit_move_insn (stack_pointer_rtx, arg_pointer_rtx);
|
||||
|
||||
emit_insn (gen_add2_insn (stack_pointer_rtx, gen_rtx (CONST_INT, VOIDmode,
|
||||
(HOST_WIDE_INT)m88k_debugger_offset (arg_pointer_rtx, 0))));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
/* This is the startup, and finish stuff per exception table. */
|
||||
|
@ -834,10 +783,26 @@ init_exception_processing ()
|
|||
|
||||
pop_lang_context ();
|
||||
throw_label = gen_label_rtx ();
|
||||
#ifdef sparc
|
||||
saved_pc = gen_rtx (REG, Pmode, 16);
|
||||
saved_throw_type = gen_rtx (REG, Pmode, 17);
|
||||
saved_throw_value = gen_rtx (REG, Pmode, 18);
|
||||
|
||||
#endif
|
||||
#ifdef __i386
|
||||
saved_pc = gen_rtx (REG, Pmode, 3);
|
||||
saved_throw_type = gen_rtx (REG, Pmode, 4);
|
||||
saved_throw_value = gen_rtx (REG, Pmode, 5);
|
||||
#endif
|
||||
#ifdef __rs6000
|
||||
saved_pc = gen_rtx (REG, Pmode, 12);
|
||||
saved_throw_type = gen_rtx (REG, Pmode, 13);
|
||||
saved_throw_value = gen_rtx (REG, Pmode, 14);
|
||||
#endif
|
||||
#ifdef __hppa
|
||||
saved_pc = gen_rtx (REG, Pmode, 5);
|
||||
saved_throw_type = gen_rtx (REG, Pmode, 6);
|
||||
saved_throw_value = gen_rtx (REG, Pmode, 7);
|
||||
#endif
|
||||
new_eh_queue (&ehqueue);
|
||||
new_eh_queue (&eh_table_output_queue);
|
||||
new_eh_stack (&ehstack);
|
||||
|
@ -1112,7 +1077,7 @@ expand_start_catch_block (declspecs, declarator)
|
|||
if (declspecs)
|
||||
{
|
||||
tree init_type;
|
||||
decl = grokdeclarator (declarator, declspecs, NORMAL, 1, NULL_TREE);
|
||||
decl = grokdeclarator (declarator, declspecs, CATCHPARM, 1, NULL_TREE);
|
||||
|
||||
/* Figure out the type that the initializer is. */
|
||||
init_type = TREE_TYPE (decl);
|
||||
|
@ -1247,6 +1212,82 @@ do_function_call (func, params, return_type)
|
|||
return NULL_RTX;
|
||||
}
|
||||
|
||||
/* unwind the stack. */
|
||||
static void
|
||||
do_unwind (throw_label)
|
||||
rtx throw_label;
|
||||
{
|
||||
#ifdef sparc
|
||||
extern FILE *asm_out_file;
|
||||
tree fcall;
|
||||
tree params;
|
||||
rtx return_val_rtx;
|
||||
|
||||
/* 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, SImode, 0);
|
||||
/* In the return, the new pc is pc+8, as the value comming in is
|
||||
really the address of the call insn, not the next insn. */
|
||||
emit_move_insn (return_val_rtx, plus_constant(gen_rtx (LABEL_REF,
|
||||
Pmode,
|
||||
throw_label), -8));
|
||||
/* We use three values, PC, type, and value */
|
||||
easy_expand_asm ("st %l0,[%fp]");
|
||||
easy_expand_asm ("st %l1,[%fp+4]");
|
||||
easy_expand_asm ("st %l2,[%fp+8]");
|
||||
easy_expand_asm ("ret");
|
||||
easy_expand_asm ("restore");
|
||||
emit_barrier ();
|
||||
#endif
|
||||
#if defined(__i386) || defined(__rs6000) || defined(__hppa)
|
||||
extern FILE *asm_out_file;
|
||||
tree fcall;
|
||||
tree params;
|
||||
rtx return_val_rtx;
|
||||
|
||||
/* 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, SImode, 0);
|
||||
#if 0
|
||||
/* I would like to do this here, but doesn't seem to work. */
|
||||
emit_move_insn (return_val_rtx, gen_rtx (LABEL_REF,
|
||||
Pmode,
|
||||
throw_label));
|
||||
/* So, for now, just pass throw label to stack unwinder. */
|
||||
#endif
|
||||
/* We use three values, PC, type, and value */
|
||||
params = tree_cons (NULL_TREE, make_tree (ptr_type_node,
|
||||
gen_rtx (LABEL_REF, Pmode, throw_label)), NULL_TREE);
|
||||
|
||||
do_function_call (Unwind, params, NULL_TREE);
|
||||
emit_barrier ();
|
||||
#endif
|
||||
#if m88k
|
||||
rtx temp_frame = frame_pointer_rtx;
|
||||
|
||||
temp_frame = memory_address (Pmode, temp_frame);
|
||||
temp_frame = copy_to_reg (gen_rtx (MEM, Pmode, temp_frame));
|
||||
|
||||
/* hopefully this will successfully pop the frame! */
|
||||
emit_move_insn (frame_pointer_rtx, temp_frame);
|
||||
emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
|
||||
emit_move_insn (arg_pointer_rtx, frame_pointer_rtx);
|
||||
emit_insn (gen_add2_insn (stack_pointer_rtx, gen_rtx (CONST_INT, VOIDmode,
|
||||
(HOST_WIDE_INT)m88k_debugger_offset (stack_pointer_rtx, 0))));
|
||||
|
||||
#if 0
|
||||
emit_insn (gen_add2_insn (arg_pointer_rtx, gen_rtx (CONST_INT, VOIDmode,
|
||||
-(HOST_WIDE_INT)m88k_debugger_offset (arg_pointer_rtx, 0))));
|
||||
|
||||
emit_move_insn (stack_pointer_rtx, arg_pointer_rtx);
|
||||
|
||||
emit_insn (gen_add2_insn (stack_pointer_rtx, gen_rtx (CONST_INT, VOIDmode,
|
||||
(HOST_WIDE_INT)m88k_debugger_offset (arg_pointer_rtx, 0))));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* is called from expand_excpetion_blocks () to generate the code in a function
|
||||
to "throw" if anything in the function needs to preform a throw.
|
||||
|
@ -1306,6 +1347,12 @@ expand_builtin_throw ()
|
|||
|
||||
emit_jump_insn (gen_beq (gotta_call_terminate));
|
||||
|
||||
#ifndef sparc
|
||||
/* On the SPARC, __builtin_return_address is already -8, no need to
|
||||
subtract any more from it. */
|
||||
emit_insn (gen_add2_insn (return_val_rtx, GEN_INT (-1)));
|
||||
#endif
|
||||
|
||||
/* yes it did */
|
||||
emit_move_insn (saved_pc, return_val_rtx);
|
||||
do_unwind (throw_label);
|
||||
|
@ -1344,7 +1391,8 @@ expand_exception_blocks ()
|
|||
{
|
||||
static int have_done = 0;
|
||||
if (! have_done && TREE_PUBLIC (current_function_decl)
|
||||
&& ! DECL_INLINE (current_function_decl))
|
||||
&& DECL_INTERFACE_KNOWN (current_function_decl)
|
||||
&& ! DECL_EXTERNAL (current_function_decl))
|
||||
{
|
||||
have_done = 1;
|
||||
expand_builtin_throw ();
|
||||
|
@ -1394,7 +1442,7 @@ expand_throw (exp)
|
|||
rtx throw_value_rtx;
|
||||
|
||||
emit_move_insn (saved_throw_type, throw_type_rtx);
|
||||
exp = convert_to_reference (build_reference_type (build_type_variant (TREE_TYPE (exp), 1, 0)), exp, CONV_STATIC, LOOKUP_COMPLAIN, NULL_TREE);
|
||||
exp = convert_to_reference (build_reference_type (build_type_variant (TREE_TYPE (exp), 1, 0)), exp, CONV_STATIC, LOOKUP_COMPLAIN, error_mark_node);
|
||||
if (exp == error_mark_node)
|
||||
error (" in thrown expression");
|
||||
throw_value_rtx = expand_expr (build_unary_op (ADDR_EXPR, exp, 0), NULL_RTX, VOIDmode, 0);
|
||||
|
@ -1437,7 +1485,8 @@ build_exception_table ()
|
|||
/* Beginning marker for table. */
|
||||
ASM_OUTPUT_ALIGN (asm_out_file, 2);
|
||||
ASM_OUTPUT_LABEL (asm_out_file, "__EXCEPTION_TABLE__");
|
||||
fprintf (asm_out_file, " .word 0, 0, 0\n");
|
||||
output_exception_table_entry (asm_out_file,
|
||||
const0_rtx, const0_rtx, const0_rtx);
|
||||
}
|
||||
count++;
|
||||
output_exception_table_entry (asm_out_file,
|
||||
|
@ -1449,7 +1498,8 @@ build_exception_table ()
|
|||
{
|
||||
/* Ending marker for table. */
|
||||
ASM_OUTPUT_LABEL (asm_out_file, "__EXCEPTION_END__");
|
||||
fprintf (asm_out_file, " .word -1, -1, -1\n");
|
||||
output_exception_table_entry (asm_out_file,
|
||||
constm1_rtx, constm1_rtx, constm1_rtx);
|
||||
}
|
||||
|
||||
#endif /* TRY_NEW_EH */
|
||||
|
@ -1472,7 +1522,10 @@ tree
|
|||
build_throw (e)
|
||||
tree e;
|
||||
{
|
||||
e = build1 (THROW_EXPR, void_type_node, e);
|
||||
TREE_SIDE_EFFECTS (e) = 1;
|
||||
if (e != error_mark_node)
|
||||
{
|
||||
e = build1 (THROW_EXPR, void_type_node, e);
|
||||
TREE_SIDE_EFFECTS (e) = 1;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,11 @@ __volatile, TYPE_QUAL, RID_VOLATILE
|
|||
__volatile__, TYPE_QUAL, RID_VOLATILE
|
||||
__wchar_t, TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,
|
||||
asm, ASM_KEYWORD, NORID,
|
||||
and, ANDAND, NORID,
|
||||
and_eq, ASSIGN, NORID,
|
||||
auto, SCSPEC, RID_AUTO,
|
||||
bitand, '&', NORID,
|
||||
bitor, '|', NORID,
|
||||
bool, TYPESPEC, RID_BOOL,
|
||||
break, BREAK, NORID,
|
||||
case, CASE, NORID,
|
||||
|
@ -35,6 +39,7 @@ catch, CATCH, NORID,
|
|||
char, TYPESPEC, RID_CHAR,
|
||||
class, AGGR, RID_CLASS,
|
||||
classof, CLASSOF, NORID,
|
||||
compl, '~', NORID,
|
||||
const, TYPE_QUAL, RID_CONST,
|
||||
const_cast, CONST_CAST, NORID,
|
||||
continue, CONTINUE, NORID,
|
||||
|
@ -45,6 +50,7 @@ double, TYPESPEC, RID_DOUBLE,
|
|||
dynamic_cast, DYNAMIC_CAST, NORID,
|
||||
else, ELSE, NORID,
|
||||
enum, ENUM, NORID,
|
||||
explicit, SCSPEC, RID_EXPLICIT,
|
||||
extern, SCSPEC, RID_EXTERN,
|
||||
false, CXX_FALSE, NORID,
|
||||
float, TYPESPEC, RID_FLOAT,
|
||||
|
@ -57,8 +63,13 @@ inline, SCSPEC, RID_INLINE,
|
|||
int, TYPESPEC, RID_INT,
|
||||
long, TYPESPEC, RID_LONG,
|
||||
mutable, SCSPEC, RID_MUTABLE,
|
||||
namespace, NAMESPACE, NORID,
|
||||
new, NEW, NORID,
|
||||
not, '!', NORID,
|
||||
not_eq, EQCOMPARE, NORID,
|
||||
operator, OPERATOR, NORID,
|
||||
or, OROR, NORID,
|
||||
or_eq, ASSIGN, NORID,
|
||||
overload, OVERLOAD, NORID,
|
||||
private, VISSPEC, RID_PRIVATE,
|
||||
protected, VISSPEC, RID_PROTECTED,
|
||||
|
@ -75,17 +86,21 @@ static, SCSPEC, RID_STATIC,
|
|||
static_cast, STATIC_CAST, NORID,
|
||||
struct, AGGR, RID_RECORD,
|
||||
switch, SWITCH, NORID,
|
||||
template, TEMPLATE, RID_TEMPLATE,
|
||||
this, THIS, NORID,
|
||||
throw, THROW, NORID,
|
||||
template, TEMPLATE, RID_TEMPLATE,
|
||||
true, CXX_TRUE, NORID,
|
||||
try, TRY, NORID,
|
||||
typedef, SCSPEC, RID_TYPEDEF,
|
||||
typeof, TYPEOF, NORID,
|
||||
typename, TYPENAME_KEYWORD, NORID,
|
||||
typeid, TYPEID, NORID,
|
||||
typeof, TYPEOF, NORID,
|
||||
union, AGGR, RID_UNION,
|
||||
unsigned, TYPESPEC, RID_UNSIGNED,
|
||||
using, USING, NORID,
|
||||
virtual, SCSPEC, RID_VIRTUAL,
|
||||
void, TYPESPEC, RID_VOID,
|
||||
volatile, TYPE_QUAL, RID_VOLATILE,
|
||||
while, WHILE, NORID,
|
||||
xor, '^', NORID,
|
||||
xor_eq, ASSIGN, NORID,
|
||||
|
|
|
@ -1185,7 +1185,7 @@ On an rs6000, xlC stores exception objects on that stack, under the try
|
|||
block. When is unwinds down into a handler, the frame pointer is
|
||||
adjusted back to the normal value for the frame in which the handler
|
||||
resides, and the stack pointer is left unchanged from the time at which
|
||||
the object was throwed. This is so that there is always someplace for
|
||||
the object was thrown. This is so that there is always someplace for
|
||||
the exception object, and nothing can overwrite it, once we start
|
||||
throwing. The only bad part, is that the stack remains large.
|
||||
|
||||
|
|
220
gcc/cp/hash.h
220
gcc/cp/hash.h
|
@ -1,14 +1,14 @@
|
|||
/* C code produced by gperf version 2.5 (GNU C++ version) */
|
||||
/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ /deneb/blob/jason/g++/small/devo/gcc/cp/gxx.gperf */
|
||||
/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ ../../../devo/gcc/cp/gxx.gperf */
|
||||
/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */
|
||||
struct resword { char *name; short token; enum rid rid;};
|
||||
|
||||
#define TOTAL_KEYWORDS 86
|
||||
#define TOTAL_KEYWORDS 101
|
||||
#define MIN_WORD_LENGTH 2
|
||||
#define MAX_WORD_LENGTH 16
|
||||
#define MIN_HASH_VALUE 4
|
||||
#define MAX_HASH_VALUE 171
|
||||
/* maximum key range = 168, duplicates = 0 */
|
||||
#define MAX_HASH_VALUE 210
|
||||
/* maximum key range = 207, duplicates = 0 */
|
||||
|
||||
#ifdef __GNUC__
|
||||
inline
|
||||
|
@ -20,19 +20,19 @@ hash (str, len)
|
|||
{
|
||||
static unsigned char asso_values[] =
|
||||
{
|
||||
172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
|
||||
172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
|
||||
172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
|
||||
172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
|
||||
172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
|
||||
172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
|
||||
172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
|
||||
172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
|
||||
172, 172, 172, 172, 172, 172, 172, 172, 172, 172,
|
||||
172, 172, 172, 172, 172, 0, 172, 36, 1, 61,
|
||||
0, 0, 30, 44, 44, 35, 172, 7, 12, 53,
|
||||
40, 17, 6, 172, 28, 2, 4, 35, 31, 51,
|
||||
5, 7, 172, 172, 172, 172, 172, 172,
|
||||
211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
|
||||
211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
|
||||
211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
|
||||
211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
|
||||
211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
|
||||
211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
|
||||
211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
|
||||
211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
|
||||
211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
|
||||
211, 211, 211, 211, 211, 0, 211, 35, 1, 69,
|
||||
61, 0, 19, 65, 20, 100, 211, 5, 11, 52,
|
||||
3, 25, 6, 2, 31, 26, 4, 41, 24, 64,
|
||||
10, 24, 211, 211, 211, 211, 211, 211,
|
||||
};
|
||||
register int hval = len;
|
||||
|
||||
|
@ -65,120 +65,144 @@ is_reserved_word (str, len)
|
|||
{
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"else", ELSE, NORID,},
|
||||
{"",},
|
||||
{"delete", DELETE, NORID,},
|
||||
{"double", TYPESPEC, RID_DOUBLE,},
|
||||
{"",}, {"",}, {"",},
|
||||
{"true", CXX_TRUE, NORID,},
|
||||
{"__asm__", GCC_ASM_KEYWORD, NORID},
|
||||
{"typeid", TYPEID, NORID,},
|
||||
{"extern", SCSPEC, RID_EXTERN,},
|
||||
{"not", '!', NORID,},
|
||||
{"not_eq", EQCOMPARE, NORID,},
|
||||
{"",}, {"",},
|
||||
{"__inline", SCSPEC, RID_INLINE},
|
||||
{"",},
|
||||
{"this", THIS, NORID,},
|
||||
{"__inline__", SCSPEC, RID_INLINE},
|
||||
{"",},
|
||||
{"xor_eq", ASSIGN, NORID,},
|
||||
{"",}, {"",}, {"",},
|
||||
{"template", TEMPLATE, RID_TEMPLATE,},
|
||||
{"",}, {"",},
|
||||
{"__alignof__", ALIGNOF, NORID},
|
||||
{"__extension__", EXTENSION, NORID},
|
||||
{"bool", TYPESPEC, RID_BOOL,},
|
||||
{"",},
|
||||
{"typeof", TYPEOF, NORID,},
|
||||
{"",},
|
||||
{"try", TRY, NORID,},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"do", DO, NORID,},
|
||||
{"",},
|
||||
{"static_cast", STATIC_CAST, NORID,},
|
||||
{"template", TEMPLATE, RID_TEMPLATE,},
|
||||
{"protected", VISSPEC, RID_PROTECTED,},
|
||||
{"",},
|
||||
{"__classof__", CLASSOF, NORID},
|
||||
{"or_eq", ASSIGN, NORID,},
|
||||
{"__asm__", GCC_ASM_KEYWORD, NORID},
|
||||
{"",},
|
||||
{"__headof__", HEADOF, NORID},
|
||||
{"",},
|
||||
{"bool", TYPESPEC, RID_BOOL,},
|
||||
{"private", VISSPEC, RID_PRIVATE,},
|
||||
{"__const__", TYPE_QUAL, RID_CONST},
|
||||
{"__volatile", TYPE_QUAL, RID_VOLATILE},
|
||||
{"__const", TYPE_QUAL, RID_CONST},
|
||||
{"__volatile__", TYPE_QUAL, RID_VOLATILE},
|
||||
{"__typeof__", TYPEOF, NORID},
|
||||
{"void", TYPESPEC, RID_VOID,},
|
||||
{"friend", SCSPEC, RID_FRIEND,},
|
||||
{"__alignof", ALIGNOF, NORID},
|
||||
{"and_eq", ASSIGN, NORID,},
|
||||
{"xor", '^', NORID,},
|
||||
{"static_cast", STATIC_CAST, NORID,},
|
||||
{"break", BREAK, NORID,},
|
||||
{"namespace", NAMESPACE, NORID,},
|
||||
{"__classof__", CLASSOF, NORID},
|
||||
{"typedef", SCSPEC, RID_TYPEDEF,},
|
||||
{"false", CXX_FALSE, NORID,},
|
||||
{"sizeof", SIZEOF, NORID,},
|
||||
{"short", TYPESPEC, RID_SHORT,},
|
||||
{"typeof", TYPEOF, NORID,},
|
||||
{"",},
|
||||
{"int", TYPESPEC, RID_INT,},
|
||||
{"__signed", TYPESPEC, RID_SIGNED},
|
||||
{"private", VISSPEC, RID_PRIVATE,},
|
||||
{"__signed__", TYPESPEC, RID_SIGNED},
|
||||
{"extern", SCSPEC, RID_EXTERN,},
|
||||
{"struct", AGGR, RID_RECORD,},
|
||||
{"signed", TYPESPEC, RID_SIGNED,},
|
||||
{"break", BREAK, NORID,},
|
||||
{"__attribute", ATTRIBUTE, NORID},
|
||||
{"default", DEFAULT, NORID,},
|
||||
{"__attribute__", ATTRIBUTE, NORID},
|
||||
{"__classof", CLASSOF, NORID},
|
||||
{"sigof", SIGOF, NORID /* Extension */,},
|
||||
{"__headof", HEADOF, NORID},
|
||||
{"switch", SWITCH, NORID,},
|
||||
{"__label__", LABEL, NORID},
|
||||
{"__extension__", EXTENSION, NORID},
|
||||
{"",},
|
||||
{"__asm", GCC_ASM_KEYWORD, NORID},
|
||||
{"for", FOR, NORID,},
|
||||
{"__typeof", TYPEOF, NORID},
|
||||
{"__alignof__", ALIGNOF, NORID},
|
||||
{"",},
|
||||
{"case", CASE, NORID,},
|
||||
{"__label__", LABEL, NORID},
|
||||
{"switch", SWITCH, NORID,},
|
||||
{"virtual", SCSPEC, RID_VIRTUAL,},
|
||||
{"if", IF, NORID,},
|
||||
{"while", WHILE, NORID,},
|
||||
{"or", OROR, NORID,},
|
||||
{"__typeof__", TYPEOF, NORID},
|
||||
{"this", THIS, NORID,},
|
||||
{"",},
|
||||
{"class", AGGR, RID_CLASS,},
|
||||
{"typedef", SCSPEC, RID_TYPEDEF,},
|
||||
{"const", TYPE_QUAL, RID_CONST,},
|
||||
{"static", SCSPEC, RID_STATIC,},
|
||||
{"auto", SCSPEC, RID_AUTO,},
|
||||
{"bitor", '|', NORID,},
|
||||
{"float", TYPESPEC, RID_FLOAT,},
|
||||
{"inline", SCSPEC, RID_INLINE,},
|
||||
{"throw", THROW, NORID,},
|
||||
{"unsigned", TYPESPEC, RID_UNSIGNED,},
|
||||
{"",},
|
||||
{"headof", HEADOF, NORID,},
|
||||
{"",},
|
||||
{"goto", GOTO, NORID,},
|
||||
{"",}, {"",},
|
||||
{"public", VISSPEC, RID_PUBLIC,},
|
||||
{"signature", AGGR, RID_SIGNATURE /* Extension */,},
|
||||
{"volatile", TYPE_QUAL, RID_VOLATILE,},
|
||||
{"__inline", SCSPEC, RID_INLINE},
|
||||
{"overload", OVERLOAD, NORID,},
|
||||
{"__inline__", SCSPEC, RID_INLINE},
|
||||
{"__alignof", ALIGNOF, NORID},
|
||||
{"asm", ASM_KEYWORD, NORID,},
|
||||
{"typename", TYPENAME_KEYWORD, NORID,},
|
||||
{"__classof", CLASSOF, NORID},
|
||||
{"short", TYPESPEC, RID_SHORT,},
|
||||
{"delete", DELETE, NORID,},
|
||||
{"double", TYPESPEC, RID_DOUBLE,},
|
||||
{"",},
|
||||
{"new", NEW, NORID,},
|
||||
{"typeid", TYPEID, NORID,},
|
||||
{"",},
|
||||
{"case", CASE, NORID,},
|
||||
{"union", AGGR, RID_UNION,},
|
||||
{"sigof", SIGOF, NORID /* Extension */,},
|
||||
{"__typeof", TYPEOF, NORID},
|
||||
{"struct", AGGR, RID_RECORD,},
|
||||
{"volatile", TYPE_QUAL, RID_VOLATILE,},
|
||||
{"signature", AGGR, RID_SIGNATURE /* Extension */,},
|
||||
{"while", WHILE, NORID,},
|
||||
{"return", RETURN, NORID,},
|
||||
{"",},
|
||||
{"__asm", GCC_ASM_KEYWORD, NORID},
|
||||
{"protected", VISSPEC, RID_PROTECTED,},
|
||||
{"reinterpret_cast", REINTERPRET_CAST, NORID,},
|
||||
{"friend", SCSPEC, RID_FRIEND,},
|
||||
{"",},
|
||||
{"do", DO, NORID,},
|
||||
{"auto", SCSPEC, RID_AUTO,},
|
||||
{"asm", ASM_KEYWORD, NORID,},
|
||||
{"compl", '~', NORID,},
|
||||
{"public", VISSPEC, RID_PUBLIC,},
|
||||
{"",},
|
||||
{"mutable", SCSPEC, RID_MUTABLE,},
|
||||
{"union", AGGR, RID_UNION,},
|
||||
{"operator", OPERATOR, NORID,},
|
||||
{"register", SCSPEC, RID_REGISTER,},
|
||||
{"",}, {"",},
|
||||
{"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,},
|
||||
{"",},
|
||||
{"long", TYPESPEC, RID_LONG,},
|
||||
{"signed", TYPESPEC, RID_SIGNED,},
|
||||
{"",},
|
||||
{"throw", THROW, NORID,},
|
||||
{"and", ANDAND, NORID,},
|
||||
{"",}, {"",}, {"",},
|
||||
{"continue", CONTINUE, NORID,},
|
||||
{"return", RETURN, NORID,},
|
||||
{"bitand", '&', NORID,},
|
||||
{"const", TYPE_QUAL, RID_CONST,},
|
||||
{"static", SCSPEC, RID_STATIC,},
|
||||
{"headof", HEADOF, NORID,},
|
||||
{"int", TYPESPEC, RID_INT,},
|
||||
{"enum", ENUM, NORID,},
|
||||
{"",},
|
||||
{"__signed__", TYPESPEC, RID_SIGNED},
|
||||
{"default", DEFAULT, NORID,},
|
||||
{"",},
|
||||
{"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,},
|
||||
{"using", USING, NORID,},
|
||||
{"__attribute", ATTRIBUTE, NORID},
|
||||
{"",},
|
||||
{"__attribute__", ATTRIBUTE, NORID},
|
||||
{"",},
|
||||
{"goto", GOTO, NORID,},
|
||||
{"operator", OPERATOR, NORID,},
|
||||
{"if", IF, NORID,},
|
||||
{"continue", CONTINUE, NORID,},
|
||||
{"explicit", SCSPEC, RID_EXPLICIT,},
|
||||
{"",}, {"",},
|
||||
{"dynamic_cast", DYNAMIC_CAST, NORID,},
|
||||
{"",}, {"",},
|
||||
{"reinterpret_cast", REINTERPRET_CAST, NORID,},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"char", TYPESPEC, RID_CHAR,},
|
||||
{"class", AGGR, RID_CLASS,},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"char", TYPESPEC, RID_CHAR,},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"classof", CLASSOF, NORID,},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"long", TYPESPEC, RID_LONG,},
|
||||
{"",}, {"",}, {"",}, {"",},
|
||||
{"void", TYPESPEC, RID_VOID,},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"overload", OVERLOAD, NORID,},
|
||||
{"",}, {"",},
|
||||
{"catch", CATCH, NORID,},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"__signed", TYPESPEC, RID_SIGNED},
|
||||
{"register", SCSPEC, RID_REGISTER,},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"const_cast", CONST_CAST, NORID,},
|
||||
{"",}, {"",},
|
||||
{"dynamic_cast", DYNAMIC_CAST, NORID,},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"catch", CATCH, NORID,},
|
||||
{"",}, {"",}, {"",}, {"",}, {"",}, {"",},
|
||||
{"inline", SCSPEC, RID_INLINE,},
|
||||
{"",}, {"",}, {"",},
|
||||
{"unsigned", TYPESPEC, RID_UNSIGNED,},
|
||||
};
|
||||
|
||||
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
|
||||
|
|
176
gcc/cp/init.c
176
gcc/cp/init.c
|
@ -125,6 +125,7 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
|
|||
tree real_binfos = BINFO_BASETYPES (real_binfo);
|
||||
tree binfos = BINFO_BASETYPES (binfo);
|
||||
int i, n_baselinks = real_binfos ? TREE_VEC_LENGTH (real_binfos) : 0;
|
||||
int has_expanded = 0;
|
||||
|
||||
for (i = 0; i < n_baselinks; i++)
|
||||
{
|
||||
|
@ -133,8 +134,12 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
|
|||
int is_not_base_vtable =
|
||||
i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (real_binfo));
|
||||
if (! TREE_VIA_VIRTUAL (real_base_binfo))
|
||||
expand_direct_vtbls_init (real_base_binfo, base_binfo,
|
||||
is_not_base_vtable, can_elide, addr);
|
||||
{
|
||||
expand_direct_vtbls_init (real_base_binfo, base_binfo,
|
||||
(is_not_base_vtable || flag_rtti), can_elide, addr);
|
||||
if (is_not_base_vtable && flag_rtti)
|
||||
has_expanded = 1;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
/* Before turning this on, make sure it is correct. */
|
||||
|
@ -142,7 +147,7 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
|
|||
return;
|
||||
#endif
|
||||
/* Should we use something besides CLASSTYPE_VFIELDS? */
|
||||
if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo)))
|
||||
if (init_self && !has_expanded && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo)))
|
||||
{
|
||||
tree base_ptr = convert_pointer_to_real (binfo, addr);
|
||||
expand_virtual_init (real_binfo, base_ptr);
|
||||
|
@ -421,13 +426,14 @@ emit_base_init (t, immediately)
|
|||
switch (n_baseclasses)
|
||||
{
|
||||
case 0:
|
||||
error ("type `%s' does not have a base class to initialize",
|
||||
IDENTIFIER_POINTER (current_class_name));
|
||||
cp_error ("`%T' does not have a base class to initialize",
|
||||
current_class_type);
|
||||
return;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
error ("unnamed initializer ambiguous for type `%s' which uses multiple inheritance", IDENTIFIER_POINTER (current_class_name));
|
||||
cp_error ("unnamed initializer ambiguous for `%T' which uses multiple inheritance",
|
||||
current_class_type);
|
||||
return;
|
||||
}
|
||||
binfo = TREE_VEC_ELT (binfos, 0);
|
||||
|
@ -449,9 +455,9 @@ emit_base_init (t, immediately)
|
|||
break;
|
||||
if (i < 0)
|
||||
{
|
||||
error ("type `%s' is not an immediate base class of type `%s'",
|
||||
IDENTIFIER_POINTER (basename),
|
||||
IDENTIFIER_POINTER (current_class_name));
|
||||
cp_error ("`%T' is not an immediate base class of `%T'",
|
||||
IDENTIFIER_TYPE_VALUE (basename),
|
||||
current_class_type);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -641,9 +647,8 @@ emit_base_init (t, immediately)
|
|||
|
||||
if (TREE_STATIC (member))
|
||||
{
|
||||
error_with_aggr_type (DECL_FIELD_CONTEXT (member),
|
||||
"field `%s::%s' is static; only point of initialization is its declaration",
|
||||
IDENTIFIER_POINTER (TREE_PURPOSE (init_list)));
|
||||
cp_error ("field `%#D' is static; only point of initialization is its declaration",
|
||||
member);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -745,8 +750,7 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list)
|
|||
if (init)
|
||||
init = TREE_PURPOSE (init);
|
||||
/* Call constructors, but don't set up vtables. */
|
||||
expand_aggr_init_1 (binfo, exp, ref, init, 0,
|
||||
LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY);
|
||||
expand_aggr_init_1 (binfo, exp, ref, init, 0, LOOKUP_COMPLAIN);
|
||||
expand_cleanups_to (NULL_TREE);
|
||||
CLEAR_BINFO_VBASE_INIT_MARKED (binfo);
|
||||
}
|
||||
|
@ -1196,12 +1200,12 @@ expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
|
|||
out, then look hard. */
|
||||
tree rval;
|
||||
tree parms;
|
||||
int xxref_init_possible;
|
||||
|
||||
if (init == NULL_TREE || TREE_CODE (init) == TREE_LIST)
|
||||
{
|
||||
parms = init;
|
||||
if (parms) init = TREE_VALUE (parms);
|
||||
if (parms)
|
||||
init = TREE_VALUE (parms);
|
||||
}
|
||||
else if (TREE_CODE (init) == INDIRECT_REF && TREE_HAS_CONSTRUCTOR (init))
|
||||
{
|
||||
|
@ -1213,16 +1217,6 @@ expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
|
|||
else
|
||||
parms = build_tree_list (NULL_TREE, init);
|
||||
|
||||
if (TYPE_HAS_INIT_REF (type)
|
||||
|| init == NULL_TREE
|
||||
|| TREE_CHAIN (parms) != NULL_TREE)
|
||||
xxref_init_possible = 0;
|
||||
else
|
||||
{
|
||||
xxref_init_possible = LOOKUP_SPECULATIVELY;
|
||||
flags &= ~LOOKUP_COMPLAIN;
|
||||
}
|
||||
|
||||
if (TYPE_USES_VIRTUAL_BASECLASSES (type))
|
||||
{
|
||||
if (true_exp == exp)
|
||||
|
@ -1232,114 +1226,43 @@ expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
|
|||
flags |= LOOKUP_HAS_IN_CHARGE;
|
||||
}
|
||||
|
||||
rval = build_method_call (exp, constructor_name_full (type),
|
||||
parms, binfo, flags|xxref_init_possible);
|
||||
if (rval == NULL_TREE && xxref_init_possible)
|
||||
if (init && TREE_CHAIN (parms) == NULL_TREE
|
||||
&& TYPE_HAS_CONSTRUCTOR (type)
|
||||
&& ! TYPE_NEEDS_CONSTRUCTING (type)
|
||||
&& TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (init)))
|
||||
{
|
||||
/* It is an error to implement a default copy constructor if
|
||||
(see ARM 12.8 for details) ... one case being if another
|
||||
copy constructor already exists. */
|
||||
tree init_type = TREE_TYPE (init);
|
||||
if (TREE_CODE (init_type) == REFERENCE_TYPE)
|
||||
init_type = TREE_TYPE (init_type);
|
||||
if (TYPE_MAIN_VARIANT (init_type) == TYPE_MAIN_VARIANT (type)
|
||||
|| (IS_AGGR_TYPE (init_type)
|
||||
&& UNIQUELY_DERIVED_FROM_P (type, init_type)))
|
||||
{
|
||||
if (type == BINFO_TYPE (binfo)
|
||||
&& TYPE_USES_VIRTUAL_BASECLASSES (type))
|
||||
{
|
||||
tree addr = build_unary_op (ADDR_EXPR, exp, 0);
|
||||
expand_aggr_vbase_init (binfo, exp, addr, NULL_TREE);
|
||||
|
||||
expand_indirect_vtbls_init (binfo, exp, addr, 1);
|
||||
}
|
||||
expand_expr_stmt (build_modify_expr (exp, INIT_EXPR, init));
|
||||
return;
|
||||
}
|
||||
else
|
||||
rval = build_method_call (exp, constructor_name_full (type), parms,
|
||||
binfo, flags);
|
||||
}
|
||||
|
||||
/* Private, protected, or otherwise unavailable. */
|
||||
if (rval == error_mark_node && (flags&LOOKUP_COMPLAIN))
|
||||
cp_error ("in base initialization for class `%T'", binfo);
|
||||
/* A valid initialization using constructor. */
|
||||
else if (rval != error_mark_node && rval != NULL_TREE)
|
||||
{
|
||||
/* p. 222: if the base class assigns to `this', then that
|
||||
value is used in the derived class. */
|
||||
if ((flag_this_is_variable & 1) && alias_this)
|
||||
{
|
||||
TREE_TYPE (rval) = TREE_TYPE (current_class_decl);
|
||||
expand_assignment (current_class_decl, rval, 0, 0);
|
||||
}
|
||||
else
|
||||
expand_expr_stmt (rval);
|
||||
}
|
||||
else if (parms && TREE_CHAIN (parms) == NULL_TREE)
|
||||
{
|
||||
/* If we are initializing one aggregate value
|
||||
from another, and though there are constructors,
|
||||
and none accept the initializer, just do a bitwise
|
||||
copy.
|
||||
|
||||
The above sounds wrong, ``If a class has any copy
|
||||
constructor defined, the default copy constructor will
|
||||
not be generated.'' 12.8 Copying Class Objects (mrs)
|
||||
|
||||
@@ This should reject initializer which a constructor
|
||||
@@ rejected on access gounds, but there is
|
||||
@@ no way right now to recognize that case with
|
||||
@@ just `error_mark_node'. */
|
||||
tree itype;
|
||||
init = TREE_VALUE (parms);
|
||||
itype = TREE_TYPE (init);
|
||||
if (TREE_CODE (itype) == REFERENCE_TYPE)
|
||||
{
|
||||
init = convert_from_reference (init);
|
||||
itype = TREE_TYPE (init);
|
||||
}
|
||||
itype = TYPE_MAIN_VARIANT (itype);
|
||||
|
||||
/* This is currently how the default X(X&) constructor
|
||||
is implemented. */
|
||||
if (comptypes (TYPE_MAIN_VARIANT (type), itype, 0))
|
||||
{
|
||||
#if 0
|
||||
warning ("bitwise copy in initialization of type `%s'",
|
||||
TYPE_NAME_STRING (type));
|
||||
#endif
|
||||
rval = build (INIT_EXPR, type, exp, init);
|
||||
expand_expr_stmt (rval);
|
||||
}
|
||||
else
|
||||
{
|
||||
cp_error ("in base initialization for class `%T',", binfo);
|
||||
cp_error ("invalid initializer to constructor for type `%T'", type);
|
||||
return;
|
||||
}
|
||||
rval = build (INIT_EXPR, type, exp, init);
|
||||
TREE_SIDE_EFFECTS (rval) = 1;
|
||||
expand_expr_stmt (rval);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (init == NULL_TREE)
|
||||
my_friendly_assert (parms == NULL_TREE, 210);
|
||||
if (parms == NULL_TREE && TREE_VIA_VIRTUAL (binfo))
|
||||
cp_error ("virtual baseclass `%T' does not have default initializer", binfo);
|
||||
rval = build_method_call (exp, constructor_name_full (type),
|
||||
parms, binfo, flags);
|
||||
|
||||
/* Private, protected, or otherwise unavailable. */
|
||||
if (rval == error_mark_node)
|
||||
{
|
||||
if (flags & LOOKUP_COMPLAIN)
|
||||
cp_error ("in base initialization for %sclass `%T'",
|
||||
TREE_VIA_VIRTUAL (binfo) ? "virtual base " : "",
|
||||
binfo);
|
||||
}
|
||||
else if (rval == NULL_TREE)
|
||||
my_friendly_abort (361);
|
||||
else
|
||||
{
|
||||
cp_error ("in base initialization for class `%T',", binfo);
|
||||
/* This will make an error message for us. */
|
||||
build_method_call (exp, constructor_name_full (type), parms, binfo,
|
||||
(TYPE_USES_VIRTUAL_BASECLASSES (type)
|
||||
? LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE
|
||||
: LOOKUP_NORMAL));
|
||||
/* p. 222: if the base class assigns to `this', then that
|
||||
value is used in the derived class. */
|
||||
if ((flag_this_is_variable & 1) && alias_this)
|
||||
{
|
||||
TREE_TYPE (rval) = TREE_TYPE (current_class_decl);
|
||||
expand_assignment (current_class_decl, rval, 0, 0);
|
||||
}
|
||||
else
|
||||
expand_expr_stmt (rval);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* Constructor has been called, but vtables may be for TYPE
|
||||
rather than for FOR_TYPE. */
|
||||
}
|
||||
|
||||
/* This function is responsible for initializing EXP with INIT
|
||||
|
@ -2707,7 +2630,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
|
|||
{
|
||||
/* raw "main", and builtin functions never gets overloaded,
|
||||
but they can become friends. */
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
add_friend (current_class_type, decl);
|
||||
DECL_FRIEND_P (decl) = 1;
|
||||
decl = void_type_node;
|
||||
|
|
127
gcc/cp/lex.c
127
gcc/cp/lex.c
|
@ -660,6 +660,9 @@ init_lex ()
|
|||
ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual");
|
||||
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL],
|
||||
build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL]));
|
||||
ridpointers[(int) RID_EXPLICIT] = get_identifier ("explicit");
|
||||
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXPLICIT],
|
||||
build_tree_list (NULL_TREE, ridpointers[(int) RID_EXPLICIT]));
|
||||
ridpointers[(int) RID_FRIEND] = get_identifier ("friend");
|
||||
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND],
|
||||
build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND]));
|
||||
|
@ -681,11 +684,6 @@ init_lex ()
|
|||
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE],
|
||||
build_tree_list (NULL_TREE, ridpointers[(int) RID_MUTABLE]));
|
||||
|
||||
/* Exception handling extensions. */
|
||||
exception_type_node = build_int_2 (exception_type, 0);
|
||||
TREE_TYPE (exception_type_node) = exception_type_node;
|
||||
ridpointers[(int) RID_EXCEPTION] = exception_type_node;
|
||||
|
||||
/* Signature handling extensions. */
|
||||
signature_type_node = build_int_2 (signature_type, 0);
|
||||
TREE_TYPE (signature_type_node) = signature_type_node;
|
||||
|
@ -790,7 +788,7 @@ init_lex ()
|
|||
}
|
||||
#endif
|
||||
|
||||
if (! (flag_gc || flag_dossier))
|
||||
if (! (flag_gc || flag_rtti))
|
||||
{
|
||||
UNSET_RESERVED_WORD ("classof");
|
||||
UNSET_RESERVED_WORD ("headof");
|
||||
|
@ -806,6 +804,17 @@ init_lex ()
|
|||
UNSET_RESERVED_WORD ("asm");
|
||||
if (flag_no_asm || flag_traditional)
|
||||
UNSET_RESERVED_WORD ("typeof");
|
||||
if (!flag_ansi)
|
||||
{
|
||||
/* These are new ANSI keywords that may break code. */
|
||||
UNSET_RESERVED_WORD ("and");
|
||||
UNSET_RESERVED_WORD ("bitand");
|
||||
UNSET_RESERVED_WORD ("bitor");
|
||||
UNSET_RESERVED_WORD ("compl");
|
||||
UNSET_RESERVED_WORD ("not");
|
||||
UNSET_RESERVED_WORD ("or");
|
||||
UNSET_RESERVED_WORD ("xor");
|
||||
}
|
||||
|
||||
token_count = init_parse ();
|
||||
interface_unknown = 1;
|
||||
|
@ -1125,19 +1134,7 @@ do_pending_inlines ()
|
|||
DECL_PENDING_INLINE_INFO (f) = 0;
|
||||
interface_unknown = t->interface == 1;
|
||||
interface_only = t->interface == 0;
|
||||
switch (- t->lineno)
|
||||
{
|
||||
case 0: case 1:
|
||||
build_dtor (f); break;
|
||||
case 2:
|
||||
build_default_constructor (f); break;
|
||||
case 3: case 4:
|
||||
build_copy_constructor (f); break;
|
||||
case 5: case 6:
|
||||
build_assign_ref (f); break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
synthesize_method (f);
|
||||
if (tail)
|
||||
tail->next = t->next;
|
||||
else
|
||||
|
@ -1712,6 +1709,7 @@ cons_up_default_function (type, name, kind)
|
|||
tree fn, args;
|
||||
tree argtype;
|
||||
int retref = 0;
|
||||
int complex = 0;
|
||||
|
||||
name = constructor_name (name);
|
||||
switch (kind)
|
||||
|
@ -1722,10 +1720,13 @@ cons_up_default_function (type, name, kind)
|
|||
/* Fall through... */
|
||||
case 0:
|
||||
name = build_parse_node (BIT_NOT_EXPR, name);
|
||||
/* Fall through... */
|
||||
args = void_list_node;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* Default constructor. */
|
||||
args = void_list_node;
|
||||
complex = TYPE_NEEDS_CONSTRUCTING (type);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
@ -1739,6 +1740,7 @@ cons_up_default_function (type, name, kind)
|
|||
build_tree_list (hash_tree_chain (argtype, NULL_TREE),
|
||||
get_identifier ("_ctor_arg")),
|
||||
void_list_node);
|
||||
complex = TYPE_HAS_COMPLEX_INIT_REF (type);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
|
@ -1755,6 +1757,7 @@ cons_up_default_function (type, name, kind)
|
|||
build_tree_list (hash_tree_chain (argtype, NULL_TREE),
|
||||
get_identifier ("_ctor_arg")),
|
||||
void_list_node);
|
||||
complex = TYPE_HAS_COMPLEX_ASSIGN_REF (type);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1777,20 +1780,34 @@ cons_up_default_function (type, name, kind)
|
|||
if (fn == void_type_node)
|
||||
return fn;
|
||||
|
||||
if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
|
||||
if (processing_template_defn)
|
||||
SET_DECL_IMPLICIT_INSTANTIATION (fn);
|
||||
|
||||
/* This kludge should go away when synthesized methods are handled
|
||||
properly, i.e. only when needed. */
|
||||
{
|
||||
struct pending_inline *t;
|
||||
t = (struct pending_inline *)
|
||||
obstack_alloc (&synth_obstack, sizeof (struct pending_inline));
|
||||
t->lineno = -kind;
|
||||
t->can_free = 0;
|
||||
t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
|
||||
store_pending_inline (fn, t);
|
||||
}
|
||||
if (CLASSTYPE_INTERFACE_KNOWN (type))
|
||||
{
|
||||
DECL_INTERFACE_KNOWN (fn) = 1;
|
||||
DECL_EXTERNAL (fn) = (CLASSTYPE_INTERFACE_ONLY (type)
|
||||
|| ! flag_implement_inlines);
|
||||
TREE_STATIC (fn) = ! DECL_EXTERNAL (fn);
|
||||
}
|
||||
|
||||
/* When on-the-fly synthesis works properly, remove the second and third
|
||||
conditions here. */
|
||||
if (flag_keep_inline_functions
|
||||
|| ! flag_no_inline
|
||||
|| complex
|
||||
|| ! DECL_EXTERNAL (fn))
|
||||
{
|
||||
struct pending_inline *t;
|
||||
t = (struct pending_inline *)
|
||||
obstack_alloc (&synth_obstack, sizeof (struct pending_inline));
|
||||
t->lineno = -kind;
|
||||
t->can_free = 0;
|
||||
t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
|
||||
store_pending_inline (fn, t);
|
||||
}
|
||||
else
|
||||
mark_inline_for_output (fn);
|
||||
|
||||
#ifdef DEBUG_DEFAULT_FUNCTIONS
|
||||
{ char *fn_type = NULL;
|
||||
|
@ -3474,6 +3491,52 @@ real_yylex ()
|
|||
else
|
||||
yylval.ttype = old_ttype;
|
||||
}
|
||||
else if (ptr->token == EQCOMPARE)
|
||||
{
|
||||
yylval.code = NE_EXPR;
|
||||
token_buffer[0] = '!';
|
||||
token_buffer[1] = '=';
|
||||
token_buffer[2] = 0;
|
||||
}
|
||||
else if (ptr->token == ASSIGN)
|
||||
{
|
||||
if (strcmp ("and_eq", token_buffer) == 0)
|
||||
{
|
||||
yylval.code = BIT_AND_EXPR;
|
||||
token_buffer[0] = '&';
|
||||
}
|
||||
else if (strcmp ("or_eq", token_buffer) == 0)
|
||||
{
|
||||
yylval.code = BIT_IOR_EXPR;
|
||||
token_buffer[0] = '|';
|
||||
}
|
||||
else if (strcmp ("xor_eq", token_buffer) == 0)
|
||||
{
|
||||
yylval.code = BIT_XOR_EXPR;
|
||||
token_buffer[0] = '^';
|
||||
}
|
||||
token_buffer[1] = '=';
|
||||
token_buffer[2] = 0;
|
||||
}
|
||||
else if (ptr->token == '&')
|
||||
{
|
||||
yylval.code = BIT_AND_EXPR;
|
||||
token_buffer[0] = '&';
|
||||
token_buffer[1] = 0;
|
||||
}
|
||||
else if (ptr->token == '|')
|
||||
{
|
||||
yylval.code = BIT_IOR_EXPR;
|
||||
token_buffer[0] = '|';
|
||||
token_buffer[1] = 0;
|
||||
}
|
||||
else if (ptr->token == '^')
|
||||
{
|
||||
yylval.code = BIT_XOR_EXPR;
|
||||
token_buffer[0] = '^';
|
||||
token_buffer[1] = 0;
|
||||
}
|
||||
|
||||
value = (int) ptr->token;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ enum rid
|
|||
RID_VOLATILE,
|
||||
RID_FRIEND,
|
||||
RID_VIRTUAL,
|
||||
RID_EXPLICIT,
|
||||
RID_SIGNED,
|
||||
RID_AUTO,
|
||||
RID_MUTABLE,
|
||||
|
|
111
gcc/cp/method.c
111
gcc/cp/method.c
|
@ -59,6 +59,7 @@ static char *scratch_firstobj;
|
|||
IDENTIFIER_LENGTH (ID)))
|
||||
# define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))
|
||||
# define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
|
||||
# define OB_LAST() (obstack_next_free (&scratch_obstack)[-1])
|
||||
|
||||
#ifdef NO_AUTO_OVERLOAD
|
||||
int is_overloaded ();
|
||||
|
@ -317,19 +318,39 @@ static int numeric_outputed_need_bar;
|
|||
static void build_overload_identifier ();
|
||||
|
||||
static void
|
||||
build_overload_nested_name (context)
|
||||
tree context;
|
||||
build_overload_nested_name (decl)
|
||||
tree decl;
|
||||
{
|
||||
/* We use DECL_NAME here, because pushtag now sets the DECL_ASSEMBLER_NAME. */
|
||||
tree name = DECL_NAME (context);
|
||||
if (DECL_CONTEXT (context))
|
||||
if (DECL_CONTEXT (decl))
|
||||
{
|
||||
context = DECL_CONTEXT (context);
|
||||
tree context = DECL_CONTEXT (decl);
|
||||
if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
|
||||
context = TYPE_NAME (context);
|
||||
context = TYPE_MAIN_DECL (context);
|
||||
build_overload_nested_name (context);
|
||||
}
|
||||
build_overload_identifier (name);
|
||||
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
{
|
||||
tree name = DECL_ASSEMBLER_NAME (decl);
|
||||
char *label;
|
||||
extern int var_labelno;
|
||||
|
||||
ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), var_labelno);
|
||||
var_labelno++;
|
||||
|
||||
if (numeric_outputed_need_bar)
|
||||
{
|
||||
OB_PUTC ('_');
|
||||
numeric_outputed_need_bar = 0;
|
||||
}
|
||||
icat (strlen (label));
|
||||
OB_PUTCP (label);
|
||||
}
|
||||
else /* TYPE_DECL */
|
||||
{
|
||||
tree name = DECL_NAME (decl);
|
||||
build_overload_identifier (name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -514,6 +535,7 @@ build_overload_name (parmtypes, begin, end)
|
|||
tree parmtype;
|
||||
|
||||
if (begin) OB_INIT ();
|
||||
numeric_outputed_need_bar = 0;
|
||||
|
||||
if ((just_one = (TREE_CODE (parmtypes) != TREE_LIST)))
|
||||
{
|
||||
|
@ -761,6 +783,13 @@ build_overload_name (parmtypes, begin, end)
|
|||
if (TREE_CODE (name) == TYPE_DECL)
|
||||
{
|
||||
tree context = name;
|
||||
|
||||
/* If DECL_ASSEMBLER_NAME has been set properly, use it. */
|
||||
if (DECL_ASSEMBLER_NAME (context) != DECL_NAME (context))
|
||||
{
|
||||
OB_PUTID (DECL_ASSEMBLER_NAME (context));
|
||||
break;
|
||||
}
|
||||
while (DECL_CONTEXT (context))
|
||||
{
|
||||
i += 1;
|
||||
|
@ -779,8 +808,8 @@ build_overload_name (parmtypes, begin, end)
|
|||
icat (i);
|
||||
if (i > 9)
|
||||
OB_PUTC ('_');
|
||||
numeric_outputed_need_bar = 0;
|
||||
build_overload_nested_name (TYPE_NAME (parmtype));
|
||||
numeric_outputed_need_bar = 0;
|
||||
build_overload_nested_name (TYPE_MAIN_DECL (parmtype));
|
||||
}
|
||||
else
|
||||
build_overload_identifier (name);
|
||||
|
@ -920,7 +949,6 @@ build_decl_overload (dname, parms, for_method)
|
|||
{
|
||||
ALLOCATE_TYPEVEC (parms);
|
||||
nofold = 0;
|
||||
numeric_outputed_need_bar = 0;
|
||||
if (for_method)
|
||||
{
|
||||
build_overload_name (TREE_VALUE (parms), 0, 0);
|
||||
|
@ -1906,6 +1934,10 @@ emit_thunk (thunk_fndecl)
|
|||
|
||||
unshare_all_rtl (insns);
|
||||
|
||||
/* Instantiate all virtual registers. */
|
||||
|
||||
instantiate_virtual_regs (current_function_decl, get_insns ());
|
||||
|
||||
/* We are no longer anticipating cse in this function, at least. */
|
||||
|
||||
cse_not_expected = 1;
|
||||
|
@ -1971,16 +2003,6 @@ emit_thunk (thunk_fndecl)
|
|||
|
||||
/* Code for synthesizing methods which have default semantics defined. */
|
||||
|
||||
void
|
||||
build_default_constructor (fndecl)
|
||||
tree fndecl;
|
||||
{
|
||||
start_function (NULL_TREE, fndecl, NULL_TREE, 1);
|
||||
store_parm_decls ();
|
||||
setup_vtbl_ptr ();
|
||||
finish_function (lineno, 0);
|
||||
}
|
||||
|
||||
/* For the anonymous union in TYPE, return the member that is at least as
|
||||
large as the rest of the members, so we can copy it. */
|
||||
static tree
|
||||
|
@ -2000,14 +2022,12 @@ largest_union_member (type)
|
|||
|
||||
/* Generate code for default X(X&) constructor. */
|
||||
void
|
||||
build_copy_constructor (fndecl)
|
||||
do_build_copy_constructor (fndecl)
|
||||
tree fndecl;
|
||||
{
|
||||
tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
|
||||
tree t;
|
||||
|
||||
start_function (NULL_TREE, fndecl, NULL_TREE, 1);
|
||||
store_parm_decls ();
|
||||
clear_last_expr ();
|
||||
push_momentary ();
|
||||
|
||||
|
@ -2085,17 +2105,15 @@ build_copy_constructor (fndecl)
|
|||
}
|
||||
|
||||
pop_momentary ();
|
||||
finish_function (lineno, 0);
|
||||
}
|
||||
|
||||
void
|
||||
build_assign_ref (fndecl)
|
||||
do_build_assign_ref (fndecl)
|
||||
tree fndecl;
|
||||
{
|
||||
tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
|
||||
|
||||
start_function (NULL_TREE, fndecl, NULL_TREE, 1);
|
||||
store_parm_decls ();
|
||||
clear_last_expr ();
|
||||
push_momentary ();
|
||||
|
||||
parm = convert_from_reference (parm);
|
||||
|
@ -2158,14 +2176,45 @@ build_assign_ref (fndecl)
|
|||
}
|
||||
c_expand_return (C_C_D);
|
||||
pop_momentary ();
|
||||
finish_function (lineno, 0);
|
||||
}
|
||||
|
||||
void push_cp_function_context ();
|
||||
void pop_cp_function_context ();
|
||||
|
||||
void
|
||||
build_dtor (fndecl)
|
||||
synthesize_method (fndecl)
|
||||
tree fndecl;
|
||||
{
|
||||
int nested = (current_function_decl != NULL_TREE);
|
||||
int toplev = (decl_function_context (fndecl) == NULL_TREE);
|
||||
char *f = input_filename;
|
||||
|
||||
if (nested)
|
||||
push_cp_function_context (toplev);
|
||||
|
||||
input_filename = DECL_SOURCE_FILE (fndecl);
|
||||
extract_interface_info ();
|
||||
start_function (NULL_TREE, fndecl, NULL_TREE, 1);
|
||||
store_parm_decls ();
|
||||
finish_function (lineno, 0);
|
||||
|
||||
if (DECL_NAME (fndecl) == ansi_opname[MODIFY_EXPR])
|
||||
do_build_assign_ref (fndecl);
|
||||
else if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
|
||||
;
|
||||
else
|
||||
{
|
||||
tree arg_chain = FUNCTION_ARG_CHAIN (fndecl);
|
||||
if (DECL_CONSTRUCTOR_FOR_VBASE_P (fndecl))
|
||||
arg_chain = TREE_CHAIN (arg_chain);
|
||||
if (arg_chain != void_list_node)
|
||||
do_build_copy_constructor (fndecl);
|
||||
else if (TYPE_NEEDS_CONSTRUCTING (current_class_type))
|
||||
setup_vtbl_ptr ();
|
||||
}
|
||||
|
||||
finish_function (lineno, 0, nested);
|
||||
input_filename = f;
|
||||
extract_interface_info ();
|
||||
if (nested)
|
||||
pop_cp_function_context (toplev);
|
||||
}
|
||||
|
|
|
@ -150,6 +150,7 @@ empty_parms ()
|
|||
%token <ttype> AGGR
|
||||
%token <itype> VISSPEC
|
||||
%token DELETE NEW OVERLOAD THIS OPERATOR CXX_TRUE CXX_FALSE
|
||||
%token NAMESPACE TYPENAME_KEYWORD USING
|
||||
%token LEFT_RIGHT TEMPLATE
|
||||
%token TYPEID DYNAMIC_CAST STATIC_CAST REINTERPRET_CAST CONST_CAST
|
||||
%token <itype> SCOPE
|
||||
|
@ -170,6 +171,7 @@ empty_parms ()
|
|||
|
||||
%left '{' ',' ';'
|
||||
|
||||
%nonassoc THROW
|
||||
%right <code> ASSIGN '='
|
||||
%right <code> '?' ':'
|
||||
%left <code> OROR
|
||||
|
@ -190,7 +192,7 @@ empty_parms ()
|
|||
%left <code> POINTSAT '.' '(' '['
|
||||
|
||||
%right SCOPE /* C++ extension */
|
||||
%nonassoc NEW DELETE TRY CATCH THROW
|
||||
%nonassoc NEW DELETE TRY CATCH
|
||||
|
||||
%type <code> unop
|
||||
|
||||
|
@ -430,9 +432,7 @@ template_def:
|
|||
{
|
||||
yychar = ':';
|
||||
template1:
|
||||
if (current_aggr == exception_type_node)
|
||||
error ("template type must define an aggregate or union");
|
||||
else if (current_aggr == signature_type_node)
|
||||
if (current_aggr == signature_type_node)
|
||||
sorry ("template type defining a signature");
|
||||
/* Maybe pedantic warning for union?
|
||||
How about an enum? :-) */
|
||||
|
@ -564,7 +564,7 @@ datadef:
|
|||
fndef:
|
||||
fn.def1 base_init compstmt_or_error
|
||||
{
|
||||
finish_function (lineno, 1);
|
||||
finish_function (lineno, 1, 0);
|
||||
/* finish_function performs these three statements:
|
||||
|
||||
expand_end_bindings (getdecls (), 1, 0);
|
||||
|
@ -577,7 +577,7 @@ fndef:
|
|||
}
|
||||
| fn.def1 return_init base_init compstmt_or_error
|
||||
{
|
||||
finish_function (lineno, 1);
|
||||
finish_function (lineno, 1, 0);
|
||||
/* finish_function performs these three statements:
|
||||
|
||||
expand_end_bindings (getdecls (), 1, 0);
|
||||
|
@ -589,13 +589,13 @@ fndef:
|
|||
if ($<ttype>$) process_next_inline ($<ttype>$);
|
||||
}
|
||||
| fn.def1 nodecls compstmt_or_error
|
||||
{ finish_function (lineno, 0);
|
||||
{ finish_function (lineno, 0, 0);
|
||||
if ($<ttype>$) process_next_inline ($<ttype>$); }
|
||||
| fn.def1 return_init ';' nodecls compstmt_or_error
|
||||
{ finish_function (lineno, 0);
|
||||
{ finish_function (lineno, 0, 0);
|
||||
if ($<ttype>$) process_next_inline ($<ttype>$); }
|
||||
| fn.def1 return_init nodecls compstmt_or_error
|
||||
{ finish_function (lineno, 0);
|
||||
{ finish_function (lineno, 0, 0);
|
||||
if ($<ttype>$) process_next_inline ($<ttype>$); }
|
||||
| typed_declspecs declarator error
|
||||
{}
|
||||
|
@ -1148,7 +1148,7 @@ sub_cast_expr:
|
|||
{
|
||||
tree type = IDENTIFIER_TYPE_VALUE ($3);
|
||||
if (! IS_SIGNATURE(type))
|
||||
$$ = CLASSTYPE_DOSSIER (type);
|
||||
$$ = CLASSTYPE_RTTI (type);
|
||||
else
|
||||
{
|
||||
sorry ("signature name as argument of `classof'");
|
||||
|
@ -2109,9 +2109,6 @@ structsp:
|
|||
|
||||
if (TREE_CODE ($$) == ENUMERAL_TYPE)
|
||||
/* $$ = $1 from default rule. */;
|
||||
else if (CLASSTYPE_DECLARED_EXCEPTION ($$))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
$$ = finish_struct ($$, $3, semi);
|
||||
|
@ -2435,8 +2432,12 @@ left_curly: '{'
|
|||
int needs_writing;
|
||||
tree name = TYPE_IDENTIFIER (t);
|
||||
|
||||
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
|
||||
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
|
||||
if (! ANON_AGGRNAME_P (name))
|
||||
{
|
||||
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
|
||||
SET_CLASSTYPE_INTERFACE_UNKNOWN_X
|
||||
(t, interface_unknown);
|
||||
}
|
||||
|
||||
/* Record how to set the access of this class's
|
||||
virtual functions. If write_virtuals == 2 or 3, then
|
||||
|
@ -3422,7 +3423,7 @@ handler_args:
|
|||
{ expand_start_catch_block ($2, $3); }
|
||||
| '(' typed_typespecs after_type_declarator ')'
|
||||
{ expand_start_catch_block ($2, $3); }
|
||||
*/
|
||||
This allows reference parameters... */
|
||||
| '(' parm ')'
|
||||
{ expand_start_catch_block (TREE_PURPOSE ($2),
|
||||
TREE_VALUE ($2)); }
|
||||
|
|
157
gcc/cp/pt.c
157
gcc/cp/pt.c
|
@ -97,8 +97,7 @@ process_template_parm (list, next)
|
|||
PARM, 0, NULL_TREE);
|
||||
/* A template parameter is not modifiable. */
|
||||
TREE_READONLY (parm) = 1;
|
||||
if (TREE_CODE (TREE_TYPE (parm)) == RECORD_TYPE
|
||||
|| TREE_CODE (TREE_TYPE (parm)) == UNION_TYPE)
|
||||
if (IS_AGGR_TYPE (TREE_TYPE (parm)))
|
||||
{
|
||||
sorry ("aggregate template parameter types");
|
||||
TREE_TYPE (parm) = void_type_node;
|
||||
|
@ -466,7 +465,7 @@ coerce_template_parms (parms, arglist, in_decl)
|
|||
tree a = TREE_OPERAND (val, 0);
|
||||
if ((TREE_CODE (a) == VAR_DECL
|
||||
|| TREE_CODE (a) == FUNCTION_DECL)
|
||||
&& !TREE_PUBLIC (a))
|
||||
&& ! DECL_PUBLIC (a))
|
||||
{
|
||||
cp_error ("address of non-extern `%E' cannot be used as template argument", a);
|
||||
val = error_mark_node;
|
||||
|
@ -683,7 +682,8 @@ push_template_decls (parmlist, arglist, class_level)
|
|||
val = digest_init (TREE_TYPE (parm), arg, (tree *) 0);
|
||||
if (val != error_mark_node)
|
||||
{
|
||||
decl = build_decl (VAR_DECL, DECL_NAME (parm), TREE_TYPE (parm));
|
||||
decl = build_decl (CONST_DECL, DECL_NAME (parm),
|
||||
TREE_TYPE (parm));
|
||||
DECL_INITIAL (decl) = val;
|
||||
TREE_READONLY (decl) = 1;
|
||||
}
|
||||
|
@ -834,6 +834,11 @@ uses_template_parms (t)
|
|||
case UNINSTANTIATED_P_TYPE:
|
||||
return 1;
|
||||
|
||||
case CONSTRUCTOR:
|
||||
if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
|
||||
return uses_template_parms (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
|
||||
/* else fall through */
|
||||
|
||||
default:
|
||||
switch (TREE_CODE_CLASS (TREE_CODE (t)))
|
||||
{
|
||||
|
@ -898,19 +903,6 @@ instantiate_member_templates (classname)
|
|||
&TREE_VEC_ELT (parmvec, 0));
|
||||
type = IDENTIFIER_TYPE_VALUE (id);
|
||||
my_friendly_assert (type != 0, 277);
|
||||
if (flag_external_templates)
|
||||
{
|
||||
if (CLASSTYPE_INTERFACE_UNKNOWN (type))
|
||||
{
|
||||
DECL_EXTERNAL (t2) = 0;
|
||||
TREE_PUBLIC (t2) = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DECL_EXTERNAL (t2) = CLASSTYPE_INTERFACE_ONLY (type);
|
||||
TREE_PUBLIC (t2) = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* Failure. */
|
||||
|
@ -1116,15 +1108,11 @@ lookup_nested_type_by_name (ctype, name)
|
|||
{
|
||||
tree t;
|
||||
|
||||
t = TREE_VALUE(CLASSTYPE_TAGS(ctype));
|
||||
while (t)
|
||||
{
|
||||
if (strcmp(IDENTIFIER_POINTER(name), IDENTIFIER_POINTER(TYPE_IDENTIFIER(t)))
|
||||
== 0)
|
||||
return t;
|
||||
else
|
||||
t = TREE_CHAIN(t);
|
||||
}
|
||||
for (t = CLASSTYPE_TAGS (ctype); t; t = TREE_CHAIN (t))
|
||||
{
|
||||
if (name == TREE_PURPOSE (t))
|
||||
return TREE_VALUE (t);
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
|
@ -1198,9 +1186,12 @@ tsubst (t, args, nargs, in_decl)
|
|||
tsubst (TYPE_MAX_VALUE (t), args, nargs, in_decl));
|
||||
|
||||
case TEMPLATE_TYPE_PARM:
|
||||
return cp_build_type_variant (args[TEMPLATE_TYPE_IDX (t)],
|
||||
TYPE_READONLY (t),
|
||||
TYPE_VOLATILE (t));
|
||||
{
|
||||
tree arg = args[TEMPLATE_TYPE_IDX (t)];
|
||||
return cp_build_type_variant
|
||||
(arg, TYPE_READONLY (arg) || TYPE_READONLY (t),
|
||||
TYPE_VOLATILE (arg) || TYPE_VOLATILE (t));
|
||||
}
|
||||
|
||||
case TEMPLATE_CONST_PARM:
|
||||
return args[TEMPLATE_CONST_IDX (t)];
|
||||
|
@ -1404,9 +1395,10 @@ tsubst (t, args, nargs, in_decl)
|
|||
}
|
||||
}
|
||||
}
|
||||
TREE_PUBLIC (r) = TREE_PUBLIC (t);
|
||||
DECL_EXTERNAL (r) = DECL_EXTERNAL (t);
|
||||
TREE_STATIC (r) = TREE_STATIC (t);
|
||||
TREE_PUBLIC (r) = 1;
|
||||
DECL_EXTERNAL (r) = 1;
|
||||
TREE_STATIC (r) = 0;
|
||||
DECL_INTERFACE_KNOWN (r) = 0;
|
||||
DECL_INLINE (r) = DECL_INLINE (t);
|
||||
{
|
||||
#if 0 /* Maybe later. -jason */
|
||||
|
@ -1719,10 +1711,21 @@ instantiate_template (tmpl, targ_ptr)
|
|||
input_filename = p->filename = t->filename;
|
||||
|
||||
extract_interface_info ();
|
||||
|
||||
if (interface_unknown && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (tmpl))
|
||||
warn_if_unknown_interface ();
|
||||
if (interface_unknown || !flag_external_templates)
|
||||
|
||||
if (interface_unknown && flag_external_templates)
|
||||
{
|
||||
if (DECL_CLASS_CONTEXT (fndecl)
|
||||
&& CLASSTYPE_INTERFACE_KNOWN (DECL_CLASS_CONTEXT (fndecl)))
|
||||
{
|
||||
interface_unknown = 0;
|
||||
interface_only
|
||||
= CLASSTYPE_INTERFACE_ONLY (DECL_CLASS_CONTEXT (fndecl));
|
||||
}
|
||||
else if (! DECL_IN_SYSTEM_HEADER (tmpl))
|
||||
warn_if_unknown_interface ();
|
||||
}
|
||||
|
||||
if (interface_unknown || ! flag_external_templates)
|
||||
p->interface = 1; /* unknown */
|
||||
else
|
||||
p->interface = interface_only ? 0 : 2;
|
||||
|
@ -2008,6 +2011,9 @@ type_unification (tparms, targs, parms, args, nsubsts, subr)
|
|||
arg = TREE_TYPE (arg);
|
||||
}
|
||||
#endif
|
||||
if (TREE_CODE (arg) == REFERENCE_TYPE)
|
||||
arg = TREE_TYPE (arg);
|
||||
|
||||
if (TREE_CODE (parm) != REFERENCE_TYPE)
|
||||
{
|
||||
if (TREE_CODE (arg) == FUNCTION_TYPE
|
||||
|
@ -2068,9 +2074,6 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
|
|||
if (arg == parm)
|
||||
return 0;
|
||||
|
||||
if (TREE_CODE (arg) == REFERENCE_TYPE)
|
||||
arg = TREE_TYPE (arg);
|
||||
|
||||
switch (TREE_CODE (parm))
|
||||
{
|
||||
case TEMPLATE_TYPE_PARM:
|
||||
|
@ -2082,6 +2085,7 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
|
|||
return 1;
|
||||
}
|
||||
idx = TEMPLATE_TYPE_IDX (parm);
|
||||
#if 0
|
||||
/* Template type parameters cannot contain cv-quals; i.e.
|
||||
template <class T> void f (T& a, T& b) will not generate
|
||||
void f (const int& a, const int& b). */
|
||||
|
@ -2089,6 +2093,13 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
|
|||
|| TYPE_VOLATILE (arg) > TYPE_VOLATILE (parm))
|
||||
return 1;
|
||||
arg = TYPE_MAIN_VARIANT (arg);
|
||||
#else
|
||||
{
|
||||
int constp = TYPE_READONLY (arg) > TYPE_READONLY (parm);
|
||||
int volatilep = TYPE_VOLATILE (arg) > TYPE_VOLATILE (parm);
|
||||
arg = cp_build_type_variant (arg, constp, volatilep);
|
||||
}
|
||||
#endif
|
||||
/* Simple cases: Value already set, does match or doesn't. */
|
||||
if (targs[idx] == arg)
|
||||
return 0;
|
||||
|
@ -2205,22 +2216,19 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
|
|||
case UNINSTANTIATED_P_TYPE:
|
||||
{
|
||||
tree a;
|
||||
/* Unification of something that is not a template fails. (mrs) */
|
||||
if (TYPE_NAME (arg) == 0)
|
||||
/* Unification of something that is not a class fails. */
|
||||
if (! IS_AGGR_TYPE (arg))
|
||||
return 1;
|
||||
a = IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (arg));
|
||||
/* Unification of something that is not a template fails. (mrs) */
|
||||
if (a == 0)
|
||||
return 1;
|
||||
if (UPT_TEMPLATE (parm) != TREE_PURPOSE (a))
|
||||
/* different templates */
|
||||
return 1;
|
||||
return unify (tparms, targs, ntparms, UPT_PARMS (parm), TREE_VALUE (a),
|
||||
nsubsts);
|
||||
if (a && UPT_TEMPLATE (parm) == TREE_PURPOSE (a))
|
||||
return unify (tparms, targs, ntparms, UPT_PARMS (parm),
|
||||
TREE_VALUE (a), nsubsts);
|
||||
/* FIXME: Should check base conversions here. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
case RECORD_TYPE:
|
||||
if (TYPE_PTRMEMFUNC_P (parm))
|
||||
if (TYPE_PTRMEMFUNC_FLAG (parm))
|
||||
return unify (tparms, targs, ntparms, TYPE_PTRMEMFUNC_FN_TYPE (parm),
|
||||
arg, nsubsts);
|
||||
|
||||
|
@ -2295,6 +2303,9 @@ do_pending_expansions ()
|
|||
else if (! flag_implicit_templates)
|
||||
DECIDE (0);
|
||||
|
||||
/* OK, it was an implicit instantiation. */
|
||||
TREE_PUBLIC (t) = 0;
|
||||
|
||||
/* If it's a method, let the class type decide it.
|
||||
@@ What if the method template is in a separate file?
|
||||
Maybe both file contexts should be taken into account?
|
||||
|
@ -2425,17 +2436,14 @@ do_function_instantiation (declspecs, declarator, storage)
|
|||
if (flag_external_templates)
|
||||
return;
|
||||
|
||||
if (DECL_EXPLICIT_INSTANTIATION (result) && TREE_PUBLIC (result))
|
||||
return;
|
||||
|
||||
SET_DECL_EXPLICIT_INSTANTIATION (result);
|
||||
TREE_PUBLIC (result) = 1;
|
||||
|
||||
if (storage == NULL_TREE)
|
||||
{
|
||||
TREE_PUBLIC (result) = 1;
|
||||
DECL_EXTERNAL (result) = (DECL_INLINE (result)
|
||||
&& ! flag_implement_inlines);
|
||||
TREE_STATIC (result) = ! DECL_EXTERNAL (result);
|
||||
DECL_INTERFACE_KNOWN (result) = 1;
|
||||
DECL_EXTERNAL (result) = 0;
|
||||
TREE_STATIC (result) = 1;
|
||||
}
|
||||
else if (storage == ridpointers[(int) RID_EXTERN])
|
||||
;
|
||||
|
@ -2475,7 +2483,7 @@ do_type_instantiation (name, storage)
|
|||
}
|
||||
|
||||
/* We've already instantiated this. */
|
||||
if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && CLASSTYPE_INTERFACE_KNOWN (t))
|
||||
if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t))
|
||||
{
|
||||
if (! extern_p)
|
||||
cp_pedwarn ("multiple explicit instantiation of `%#T'", t);
|
||||
|
@ -2485,22 +2493,29 @@ do_type_instantiation (name, storage)
|
|||
if (! CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
|
||||
{
|
||||
SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
|
||||
SET_CLASSTYPE_INTERFACE_KNOWN (t);
|
||||
CLASSTYPE_INTERFACE_ONLY (t) = extern_p;
|
||||
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! extern_p;
|
||||
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = extern_p;
|
||||
if (! extern_p)
|
||||
{
|
||||
SET_CLASSTYPE_INTERFACE_KNOWN (t);
|
||||
CLASSTYPE_INTERFACE_ONLY (t) = 0;
|
||||
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = 1;
|
||||
CLASSTYPE_DEBUG_REQUESTED (t) = 1;
|
||||
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0;
|
||||
rest_of_type_compilation (t, 1);
|
||||
}
|
||||
}
|
||||
|
||||
instantiate_member_templates (TYPE_IDENTIFIER (t));
|
||||
|
||||
/* this should really be done by instantiate_member_templates */
|
||||
|
||||
{
|
||||
tree tmp = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
|
||||
tree tmp;
|
||||
/* Classes nested in template classes currently don't have an
|
||||
IDENTIFIER_TEMPLATE--their out-of-line members are handled
|
||||
by the enclosing template class. Note that there are name
|
||||
conflict bugs with this approach. */
|
||||
tmp = TYPE_IDENTIFIER (t);
|
||||
if (IDENTIFIER_TEMPLATE (tmp))
|
||||
instantiate_member_templates (tmp);
|
||||
|
||||
/* this should really be done by instantiate_member_templates */
|
||||
tmp = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
|
||||
for (; tmp; tmp = TREE_CHAIN (tmp))
|
||||
{
|
||||
if (DECL_TEMPLATE_SPECIALIZATION (tmp)
|
||||
|
@ -2509,12 +2524,12 @@ do_type_instantiation (name, storage)
|
|||
continue;
|
||||
|
||||
SET_DECL_EXPLICIT_INSTANTIATION (tmp);
|
||||
TREE_PUBLIC (tmp) = 1;
|
||||
if (! extern_p)
|
||||
{
|
||||
TREE_PUBLIC (tmp) = 1;
|
||||
DECL_EXTERNAL (tmp) = (DECL_INLINE (tmp)
|
||||
&& ! flag_implement_inlines);
|
||||
TREE_STATIC (tmp) = ! DECL_EXTERNAL (tmp);
|
||||
DECL_INTERFACE_KNOWN (tmp) = 1;
|
||||
DECL_EXTERNAL (tmp) = 0;
|
||||
TREE_STATIC (tmp) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -377,8 +377,8 @@ pop_memoized_context (use_old)
|
|||
type_stack = (struct type_level *)type_stack->base.prev;
|
||||
}
|
||||
|
||||
#if 0 /* unused */
|
||||
/* This is the newer recursive depth first search routine. */
|
||||
#if 0 /* unused */
|
||||
/* Return non-zero if PARENT is directly derived from TYPE. By directly
|
||||
we mean it's only one step up the inheritance lattice. We check this
|
||||
by walking horizontally across the types that TYPE directly inherits
|
||||
|
@ -1995,12 +1995,9 @@ get_abstract_virtuals_1 (binfo, do_self, abstract_virtuals)
|
|||
/* Should we use something besides CLASSTYPE_VFIELDS? */
|
||||
if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
|
||||
{
|
||||
/* Get around first entry reserved for RTTI. */
|
||||
tree tmp = TREE_CHAIN (BINFO_VIRTUALS (binfo));
|
||||
|
||||
/* Get around dossier entry if there is one. */
|
||||
if (flag_dossier)
|
||||
tmp = TREE_CHAIN (tmp);
|
||||
|
||||
while (tmp)
|
||||
{
|
||||
tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (tmp));
|
||||
|
@ -2417,10 +2414,10 @@ dfs_init_vbase_pointers (binfo)
|
|||
|
||||
CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
|
||||
|
||||
/* If there is a dossier, it is the first field, though perhaps from
|
||||
/* If there is a rtti, it is the first field, though perhaps from
|
||||
the base class. Otherwise, the first fields are virtual base class
|
||||
pointer fields. */
|
||||
if (CLASSTYPE_DOSSIER (type) && VFIELD_NAME_P (DECL_NAME (fields)))
|
||||
if (CLASSTYPE_RTTI (type) && VFIELD_NAME_P (DECL_NAME (fields)))
|
||||
/* Get past vtable for the object. */
|
||||
fields = TREE_CHAIN (fields);
|
||||
|
||||
|
|
|
@ -1250,9 +1250,8 @@ debug_binfo (elem)
|
|||
virtuals = BINFO_VIRTUALS (elem);
|
||||
if (virtuals != 0)
|
||||
{
|
||||
/* skip the rtti type descriptor entry */
|
||||
virtuals = TREE_CHAIN (virtuals);
|
||||
if (flag_dossier)
|
||||
virtuals = TREE_CHAIN (virtuals);
|
||||
}
|
||||
i = 1;
|
||||
while (virtuals)
|
||||
|
|
|
@ -3404,6 +3404,10 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
|
|||
unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0));
|
||||
|
||||
if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
|
||||
/* We can shorten only if the shift count is less than the
|
||||
number of bits in the smaller type size. */
|
||||
&& TREE_INT_CST_HIGH (op1) == 0
|
||||
&& TYPE_PRECISION (TREE_TYPE (arg0)) > TREE_INT_CST_LOW (op1)
|
||||
/* If arg is sign-extended and then unsigned-shifted,
|
||||
we can simulate this with a signed shift in arg's type
|
||||
only if the extended result is at least twice as wide
|
||||
|
@ -3756,8 +3760,12 @@ build_x_unary_op (code, xarg)
|
|||
{
|
||||
/* & rec, on incomplete RECORD_TYPEs is the simple opr &, not an
|
||||
error message. */
|
||||
if (code != ADDR_EXPR || TREE_CODE (TREE_TYPE (xarg)) != RECORD_TYPE
|
||||
|| TYPE_SIZE (TREE_TYPE (xarg)))
|
||||
if (code == ADDR_EXPR
|
||||
&& ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (xarg)))
|
||||
&& TYPE_SIZE (TREE_TYPE (xarg)) == NULL_TREE)
|
||||
|| (TREE_CODE (xarg) == OFFSET_REF)))
|
||||
/* don't look for a function */;
|
||||
else
|
||||
{
|
||||
tree rval = build_opfncall (code, LOOKUP_SPECULATIVELY, xarg,
|
||||
NULL_TREE, NULL_TREE);
|
||||
|
@ -3813,6 +3821,9 @@ build_unary_op (code, xarg, noconvert)
|
|||
if (typecode == ENUMERAL_TYPE)
|
||||
typecode = INTEGER_TYPE;
|
||||
|
||||
if (typecode == BOOLEAN_TYPE && ! noconvert)
|
||||
typecode = INTEGER_TYPE;
|
||||
|
||||
isaggrtype = IS_AGGR_TYPE_CODE (typecode);
|
||||
|
||||
switch (code)
|
||||
|
@ -5435,7 +5446,14 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
|
||||
if (modifycode == INIT_EXPR)
|
||||
{
|
||||
if (TYPE_LANG_SPECIFIC (lhstype) && TYPE_HAS_CONSTRUCTOR (lhstype))
|
||||
if (! IS_AGGR_TYPE (lhstype))
|
||||
/* Do the default thing */;
|
||||
else if (! TYPE_HAS_CONSTRUCTOR (lhstype))
|
||||
cp_error ("`%T' has no constructors", lhstype);
|
||||
else if (! TYPE_NEEDS_CONSTRUCTING (lhstype)
|
||||
&& TYPE_MAIN_VARIANT (lhstype) == TYPE_MAIN_VARIANT (TREE_TYPE (newrhs)))
|
||||
/* Do the default thing */;
|
||||
else
|
||||
{
|
||||
result = build_method_call (lhs, constructor_name_full (lhstype),
|
||||
build_tree_list (NULL_TREE, rhs),
|
||||
|
@ -5449,7 +5467,17 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
{
|
||||
#if 1
|
||||
/* `operator=' is not an inheritable operator. */
|
||||
if (TYPE_LANG_SPECIFIC (lhstype) && TYPE_HAS_ASSIGNMENT (lhstype))
|
||||
if (! IS_AGGR_TYPE (lhstype))
|
||||
/* Do the default thing */;
|
||||
else if (! TYPE_HAS_ASSIGNMENT (lhstype))
|
||||
cp_error ("`%T' does not define operator=", lhstype);
|
||||
else if (! TYPE_HAS_REAL_ASSIGNMENT (lhstype)
|
||||
&& ! TYPE_HAS_COMPLEX_ASSIGN_REF (lhstype)
|
||||
/* FIXME find some way to deal with TARGET_EXPRs here. */
|
||||
&& TREE_CODE (newrhs) != TARGET_EXPR
|
||||
&& TYPE_MAIN_VARIANT (lhstype) == TYPE_MAIN_VARIANT (TREE_TYPE (newrhs)))
|
||||
/* Do the default thing */;
|
||||
else
|
||||
{
|
||||
result = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL,
|
||||
lhs, rhs, make_node (NOP_EXPR));
|
||||
|
@ -5655,6 +5683,8 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
if (TREE_SIDE_EFFECTS (newrhs))
|
||||
newrhs = stabilize_reference (newrhs);
|
||||
|
||||
#if 0
|
||||
/* This is now done by generating X(X&) and operator=(X&). */
|
||||
/* C++: The semantics of C++ differ from those of C when an
|
||||
assignment of an aggregate is desired. Assignment in C++ is
|
||||
now defined as memberwise assignment of non-static members
|
||||
|
@ -5673,14 +5703,6 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
|| (TREE_CODE (TREE_TYPE (newrhs)) == RECORD_TYPE
|
||||
&& UNIQUELY_DERIVED_FROM_P (lhstype, TREE_TYPE (newrhs)))))
|
||||
{
|
||||
/* This was decided in finish_struct. */
|
||||
if (modifycode == INIT_EXPR)
|
||||
cp_error ("can't generate default copy constructor for `%T'", lhstype);
|
||||
else
|
||||
cp_error ("can't generate default assignment operator for `%T'",
|
||||
lhstype);
|
||||
#if 0
|
||||
/* This is now done by generating X(X&) and operator=(X&). */
|
||||
tree vbases = CLASSTYPE_VBASECLASSES (lhstype);
|
||||
tree lhs_addr = build_unary_op (ADDR_EXPR, lhs, 0);
|
||||
tree rhs_addr;
|
||||
|
@ -5756,8 +5778,8 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
TYPE_BINFO (lhstype)),
|
||||
result);
|
||||
return build_compound_expr (result);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Convert new value to destination type. */
|
||||
|
||||
|
@ -5811,6 +5833,7 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
if (IS_AGGR_TYPE (lhstype))
|
||||
{
|
||||
if (result = build_opfncall (MODIFY_EXPR,
|
||||
|
@ -5818,6 +5841,7 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
make_node (NOP_EXPR)))
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
/* Avoid warnings on enum bit fields. */
|
||||
if (TREE_CODE (olhstype) == ENUMERAL_TYPE
|
||||
&& TREE_CODE (lhstype) == INTEGER_TYPE)
|
||||
|
@ -6603,8 +6627,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
|
|||
`convert_for_initialization'. They should otherwise be
|
||||
bashed before coming here. */
|
||||
else if (codel == REFERENCE_TYPE)
|
||||
/* Force an abort. */
|
||||
my_friendly_assert (codel != REFERENCE_TYPE, 317);
|
||||
my_friendly_abort (317);
|
||||
else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (rhs)))
|
||||
{
|
||||
tree nrhs = build1 (NOP_EXPR, type, rhs);
|
||||
|
@ -6742,6 +6765,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
|
|||
}
|
||||
/* Handle the case of default parameter initialization and
|
||||
initialization of static variables. */
|
||||
else if (TREE_CODE (rhs) == TARGET_EXPR)
|
||||
return rhs;
|
||||
else if (TREE_CODE (rhs) == INDIRECT_REF && TREE_HAS_CONSTRUCTOR (rhs))
|
||||
{
|
||||
my_friendly_assert (TREE_CODE (TREE_OPERAND (rhs, 0)) == CALL_EXPR, 318);
|
||||
|
|
|
@ -329,7 +329,7 @@ ack (s, v, v2)
|
|||
silly. So instead, we just do the equivalent of a call to fatal in the
|
||||
same situation (call exit). */
|
||||
|
||||
/* First used: 0 (reserved), Last used: 360. Free: 261. */
|
||||
/* First used: 0 (reserved), Last used: 361. Free: */
|
||||
|
||||
static int abortcount = 0;
|
||||
|
||||
|
@ -1342,6 +1342,7 @@ build_m_component_ref (datum, component)
|
|||
|
||||
if (TREE_CODE (objtype) == REFERENCE_TYPE)
|
||||
objtype = TREE_TYPE (objtype);
|
||||
objtype = TYPE_MAIN_VARIANT (objtype);
|
||||
|
||||
if (! IS_AGGR_TYPE (objtype))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue