49th Cygnus<->FSF merge

From-SVN: r8570
This commit is contained in:
Mike Stump 1994-11-29 00:59:16 +00:00
parent c7a7ac465e
commit db5ae43ff2
24 changed files with 1804 additions and 984 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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));

View File

@ -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);

View File

@ -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);
}

View File

@ -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) */

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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,

View File

@ -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.

View File

@ -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)

View File

@ -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;

View File

@ -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;
}
}

View File

@ -58,6 +58,7 @@ enum rid
RID_VOLATILE,
RID_FRIEND,
RID_VIRTUAL,
RID_EXPLICIT,
RID_SIGNED,
RID_AUTO,
RID_MUTABLE,

View File

@ -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);
}

View File

@ -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)); }

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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))
{