1994-02-24 02:02:37 +01:00
|
|
|
|
/* Functions related to building classes and their related objects.
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
|
|
|
|
1999, 2000 Free Software Foundation, Inc.
|
1994-02-24 02:02:37 +01:00
|
|
|
|
Contributed by Michael Tiemann (tiemann@cygnus.com)
|
|
|
|
|
|
|
|
|
|
This file is part of GNU CC.
|
|
|
|
|
|
|
|
|
|
GNU CC is free software; you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
|
any later version.
|
|
|
|
|
|
|
|
|
|
GNU CC is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with GNU CC; see the file COPYING. If not, write to
|
1995-06-15 14:29:51 +02:00
|
|
|
|
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
|
|
|
Boston, MA 02111-1307, USA. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
|
1996-07-11 03:13:25 +02:00
|
|
|
|
/* High-level class interface. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
#include "config.h"
|
call.c: Include system.h.
* call.c: Include system.h. Remove includes, declarations and
defines provided by system.h.
* class.c, cvt.c, decl.c, decl2.c, errfn.c error.c: Likewise.
* except.c, expr.c friend.c, g++spec.c, init.c, input.c: Likewise.
* lex.c, parse.y, pt.c, ptree.c repo.c rtti.c, search.c: Likewise.
* semantics.c, sig.c, spew.c, tree.c, typeck.c: Likewise.
* typeck2.c, xref.c: Likewise.
* Makefile.in: Dependencies updated as appropriate.
* Make-lang.in: Likewise.
system.h cutover from the cp subdir
From-SVN: r18917
1998-03-31 15:25:46 +02:00
|
|
|
|
#include "system.h"
|
1998-04-01 19:25:12 +02:00
|
|
|
|
#include "tree.h"
|
1994-02-24 02:02:37 +01:00
|
|
|
|
#include "cp-tree.h"
|
|
|
|
|
#include "flags.h"
|
1995-03-23 01:44:31 +01:00
|
|
|
|
#include "rtl.h"
|
1995-04-24 19:27:46 +02:00
|
|
|
|
#include "output.h"
|
call.c, [...]: Add include of toplev.h.
Wed May 6 06:36:41 1998 Robert Lipe <robertl@dgii.com>
* cp/call.c, cp/class.c, cp/decl.c, cp/decl2.c,
cp/errfn.c, cp/error.c, cp/except.c, cp/expr.c,
cp/friend.c, cp/init.c, cp/lex.c, cp/method.c,
cp/pt.c, cp/repo.c, cp/rtti.c, cp/search.c,
cp/semantics.c, cp/sig.c, cp/tree.c, cp/typeck.c,
cp/typeck2.c, cp/xref.c: Add include of toplev.h.
From-SVN: r19565
1998-05-06 07:01:35 +02:00
|
|
|
|
#include "toplev.h"
|
Get ready for garbage collection.
* Makefile.in (CXX_TREE_H): Add varray.h
(lex.o): Depend on ggc.h.
(decl.o): Likewise.
(decl2.o): Likewise.
(method.o): Likewise.
(search.o): Likewise.
(pt.o): Likewise.
(repo.o): Likewise.
* class.c: Include ggc.h.
(current_class_name): Remove.
(current_class_type): Likewise.
(current_access_specifier): Likewise.
(previous_class_type): Likewise.
(previous_class_values): Likewise.
(class_cache_firstobj): Likewise.
(current_lang_base): Likewise.
(current_lang_stack): Likewise.
(current_lang_stacksize): Likewise.
(lang_name_c): Likewise.
(lang_name_cplusplus): Likewise.
(lang_name_java): Likewise.
(current_lang_name): Likewise.
(base_layout_decl): Likewise.
(access_default_node): Likewise.
(access_public_node): Likewise.
(access_protected_node): Likewise.
(access_private_node): Likewise.
(access_default_virtual_node): Likewise.
(access_public_virtual_node): Likewise.
(access_protected_virtual_node): Likewise.
(access_private_virtual_node): Likewise.
(signed_zero_node): Likewise.
(init_class_processing): Don't build base_layout_decl.
(push_lang_context): Adjust now that current_lang_base is a varray.
(pop_lang_context): Likewise.
* cp-tree.h: Include varray.h.
(cp_global_trees): Add access_default, access_public,
access_protected, access_private, access_default_virtual,
access_public_virtual, access_protected_virtual,
access_private_virtual, ctor_identifier, delta2_identifier,
delta_identifier, dtor_identifier, in_charge_identifier,
index_identifier, nelts_identifier, this_identifier,
pfn_identifier, pfn_or_delta2_identifier, vptr_identifier,
lang_name_c, lang_name_cplusplus, lang_name_java,
empty_except_spec, null, jclass, minus_one, terminate.
(saved_scope): Move here from decl.c. Define globals in terms of
saved_scope: current_namespace, current_class_name,
current_class_type, current_access_specifier, current_lang_stack,
current_lang_base, current_lang_name, current_function_parms,
current_template_parms, processing_template_decl,
processing_specialization, processing_explicit_instantiation,
previous_class_type, previous_class_values, class_cache_firstobj.
(scope_chain): New variable.
(init_pt): New function.
* decl.c (current_namespace): Remove.
(this_identifier, in_charge_identifier, ctor_identifier): Likewise.
(dtor_identifier, pfn_identifier, index_identifier): Likewise.
(delta_identifier, delta2_identifier): Likewise.
(pfn_or_delta2_identifier, tag_identifier): Likewise
(vt_off_identifier, empty_except_spec, null_node): Likewise.
(current_function_parms, current_lang_base): Remove.
(current_lang_stack, previous_class_values): Remove.
(class_binding_level): Macroize.
(saved_scope): Remove.
(current_saved_scope): Rename to scope_chain.
(mark_saved_scope): Adjust for new scope structure.
(maybe_push_to_top_level): Likewise.
(pop_from_top_level): Likewise.
(duplicate_decls): Adjust now that current_lang_base is a varray.
(build_typename_type): Call ggc_add_tree_hash_table_root.
(init_decl_processing): Call init_pt. Call push_to_top_level to
set up globals. Add GC roots.
(xref_basetypes): Adjust now that current_lang_base is a varray.
* decl.h (this_identifier): Remove.
(in_charge_identifier): Likewise.
* decl2.c: Don't include varray.h.
(current_namespace): Remove.
(init_decl2): Add GC roots.
* except.c (Terminate): Remove.
(init_exception_processing): Use terminate_node instead.
(build_terminate_handler): Likewise.
* init.c (nc_nelts_field_id): Remove.
(minus_one): Likewise.
(init_init_processing): Use minus_one_node and nelts_identifier
instead. Add GC roots.
(jclass_node): Remove.
(build_new_1): Use nelts_identifier.
(build_vec_init): Likewise.
(build_vec_delete): Likewise.
* lex.c: Include ggc.h.
(defarg_fn): Move declaration early.
(defarg_parms): Likewise.
(init_parse): Add GC roots.
(handle_cp_pragma): Remove redundant declaration of
pending_vtables.
* method.c: Include ggc.h.
(btypelist): Make it a varray. All uses changed.
(ktypelist): Likewise.
(init_method): Add GC roots.
* pt.c: Don't include varray.h. Include ggc.h.
(current_template_parms): Remove.
(processing_template_decl): Likewise.
(processing_specialization): Likewise.
(processing_explicit_instantiation): Likewise.
(init_pt): New function.
* repo.c: Include ggc.h.
(init_repo): Add GC roots.
* search.c: Don't include varray.h.
(_vptr_name): Remove.
(lookup_field_1): Use vtpr_identifier instead.
(expand_indirect_vtbls_init): Remove redundant declaration of
in_charge_identifier.
(init_search_processing): Use vptr_identifier.
From-SVN: r29135
1999-09-06 04:43:09 +02:00
|
|
|
|
#include "ggc.h"
|
1999-10-08 02:08:23 +02:00
|
|
|
|
#include "lex.h"
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
#include "obstack.h"
|
|
|
|
|
#define obstack_chunk_alloc xmalloc
|
|
|
|
|
#define obstack_chunk_free free
|
|
|
|
|
|
|
|
|
|
/* This is how we tell when two virtual member functions are really the
|
1996-07-11 03:13:25 +02:00
|
|
|
|
same. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
#define SAME_FN(FN1DECL, FN2DECL) (DECL_ASSEMBLER_NAME (FN1DECL) == DECL_ASSEMBLER_NAME (FN2DECL))
|
|
|
|
|
|
2000-01-26 21:51:37 +01:00
|
|
|
|
extern void set_class_shadows PARAMS ((tree));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1998-10-06 16:20:30 +02:00
|
|
|
|
/* The number of nested classes being processed. If we are not in the
|
|
|
|
|
scope of any class, this is zero. */
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
int current_class_depth;
|
|
|
|
|
|
1998-10-06 16:20:30 +02:00
|
|
|
|
/* In order to deal with nested classes, we keep a stack of classes.
|
|
|
|
|
The topmost entry is the innermost class, and is the entry at index
|
|
|
|
|
CURRENT_CLASS_DEPTH */
|
|
|
|
|
|
|
|
|
|
typedef struct class_stack_node {
|
|
|
|
|
/* The name of the class. */
|
|
|
|
|
tree name;
|
|
|
|
|
|
|
|
|
|
/* The _TYPE node for the class. */
|
|
|
|
|
tree type;
|
|
|
|
|
|
|
|
|
|
/* The access specifier pending for new declarations in the scope of
|
|
|
|
|
this class. */
|
|
|
|
|
tree access;
|
tinfo.h (__class_type_info): Fix illegal declaration.
1999-04-02 Mark Mitchell <mark@codesourcery.com>
* tinfo.h (__class_type_info): Fix illegal declaration.
* cp-tree.def (TEMPLATE_ID_EXPR): Update comment.
* cp-tree.h (INHERITED_VALUE_BINDING_P): New macro.
(IDENTIFIER_CLASS_VALUE): Improve documentation.
(is_properly_derived_from): Declare.
(invalidate_class_lookup_cache): Likewise.
(maybe_maybe_note_name_used_in_class): Likewise.
(note_name_declared_in_class): Likewise.
(push_using_decl): Remove duplicate declaration.
(id_in_current_class): Remove declaration.
(push_class_binding): Change prototype.
(clear_identitifer_class_values): Declare.
* call.c (is_properly_derived_from): Make it global.
(build_new_function_call): Be careful about updating candidates.
(build_new_method_call): Handle COMPONENT_REFs. Don't crash when
asked to make illegal calls.
* class.c: Include splay-tree.h.
(class_stack_node): Add names_used slot.
(check_member_decl_is_same_in_complete_scope): Remove.
(add_method): Fix comment. Push the declaration into class
scope.
(finish_struct_1): When popping the class, pop the bindings too.
Remove check for data member/function member conflict.
(finish_struct): Remove calls to
check_member_decl_is_same_in_complete_scope. Change calls to
popclass.
(pushclass): Clear names_used in the class stack entry.
Use invalidate_class_lookup_cache to remove cached entries, rather
than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE
before entering a new class. Remove dead code. Don't mess with
current_function_decl when pushing declarations.
(invalidate_class_lookup_cache): New function, split out from ...
(popclass): Here. Clean up names_used on our way out.
(instantiate_type): Adjust.
(build_self_reference): Don't push the declaration here.
(maybe_note_name_used_in_class): New function.
(note_name_declared_in_class): Likewise.
* decl.c (add_binding): Change prototype.
(find_class_binding_level): New function.
(innermost_nonclass_level): Likewise.
(current_binding_level): Update documentation.
(inner_binding_level): Remove. Replace with current_binding_level
throughout.
(push_binding_level): Remove special handling of
class_binding_level.
(pop_binding_level): Likewise. Use find_class_binding_level.
(suspend_binding_level): Likewise.
(global_bindings_p): Use innermost_nonclass_level.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(pseudo_global_level_p): Likewise.
(push_binding): Clear INHERITED_VALUE_BINDING_P.
(add_binding): Check for illegal multiple declarations. Return a
value indicating whether or not the new binding was legal.
(push_local_binding): Skip over class binding levels. Check
return value from add_binding.
(push_class_binding): Set INHERITED_VALUE_BINDING_P. Call
note_name_declared_in_class.
(pushlevel_class): Remove "fake out the rest of the compiler"
code.
(poplevel_class): Reset IDENTIFIER_CLASS_VALUEs.
(clear_identifier_class_values): New function.
(pop_from_top_level): Use it.
(pop_everything): Tweak.
(maybe_process_template_type_declaration): Don't push the
declaration for the template here.
(pushtag): Don't push tag declarations into class scope here.
(pushdecl): Apply DeMorgan's law for readability.
(pushdecl_class_level): Remove special-case code for
TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions.
(push_class_level_bindng): Deal with inherited bindings.
(lookup_name_real): Remove special-case code for
TYPE_BEING_DEFINED, and some implicit typename magic.
(grokdeclarator): Handle COMPONENT_REF for a template function.
(build_enumerator): Don't call pushdecl_class_level here.
(id_in_current_class): Remove.
* decl2.c (grokfield): Don't call pushdecl_class_level or
check_template_shadow.
* errfn.c (cp_file_of): Don't declare.
(cp_line_of): Likewise.
* error.c (dump_decl): Handle an OVERLOAD.
(cp_file_of): Likewise.
(cp_line_of): Likewise.
* init.c (build_member_call): Handle a COMPONENT_REF.
* lex.c (do_identifier): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* method.c (hack_identifier): Build COMPONENT_REFs for references
to member templates as well as member functions. Remove dead
code.
* parse.y (left_curly): Remove.
(nonnested_type): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* parse.c: Regenerated.
(nested_name_specifier_1): Likewise.
* pt.c (check_explicit_specialization): Adjust, for robustness.
(check_template_shadow): Handle OVERLOADs.
(build_template_decl): Set DECL_CONSTRUCTOR_P on the
TEMPLATE_DECL, if appropriate.
* search.c (envelope_add_decl): Remove.
(dfs_pushdecls): Likewise.
(dfs_compress_decls): Likewise.
(dfs_push_decls): New function.
(dfs_push_type_decls): Likewise.
(setup_class_bindings): Likewise.
(template_self_reference_p): Likewise.
(lookup_field_r): Use it.
(looup_member): Remove old comment. Deal with ambiguity.
(push_class_decls): Use dfs_push_decls and dfs_push_type_decls,
and remove envelope processing.
* semantics.c (begin_class_definition): Let pushclass push
declarations for base classes.
(finish_member_declaration): Push declarations into class scope.
* typeck.c (build_component_ref): Just put an OVERLOAD into the
COMPONENT_REF, not a TREE_LIST of an OVERLOAD.
(build_x_function_call): Deal with OVERLOAD. Handle template-ids.
* Makefile.in (class.o): Depend on splay-tree.h.
From-SVN: r26133
1999-04-02 17:36:57 +02:00
|
|
|
|
|
|
|
|
|
/* If were defining TYPE, the names used in this class. */
|
|
|
|
|
splay_tree names_used;
|
1998-10-06 16:20:30 +02:00
|
|
|
|
}* class_stack_node_t;
|
|
|
|
|
|
|
|
|
|
/* The stack itself. This is an dynamically resized array. The
|
|
|
|
|
number of elements allocated is CURRENT_CLASS_STACK_SIZE. */
|
|
|
|
|
static int current_class_stack_size;
|
|
|
|
|
static class_stack_node_t current_class_stack;
|
|
|
|
|
|
2000-01-26 21:51:37 +01:00
|
|
|
|
static tree get_vfield_name PARAMS ((tree));
|
|
|
|
|
static void finish_struct_anon PARAMS ((tree));
|
|
|
|
|
static tree build_vbase_pointer PARAMS ((tree, tree));
|
2000-01-29 04:59:09 +01:00
|
|
|
|
static tree build_vtable_entry PARAMS ((tree, tree, tree));
|
2000-01-26 21:51:37 +01:00
|
|
|
|
static tree get_vtable_name PARAMS ((tree));
|
|
|
|
|
static tree get_derived_offset PARAMS ((tree, tree));
|
|
|
|
|
static tree get_basefndecls PARAMS ((tree, tree));
|
|
|
|
|
static void set_rtti_entry PARAMS ((tree, tree, tree));
|
2000-01-31 05:03:01 +01:00
|
|
|
|
static int build_primary_vtable PARAMS ((tree, tree));
|
|
|
|
|
static int build_secondary_vtable PARAMS ((tree, tree));
|
2000-01-26 21:51:37 +01:00
|
|
|
|
static tree dfs_finish_vtbls PARAMS ((tree, void *));
|
2000-02-21 05:19:12 +01:00
|
|
|
|
static tree dfs_accumulate_vtbl_inits PARAMS ((tree, void *));
|
2000-01-26 21:51:37 +01:00
|
|
|
|
static void finish_vtbls PARAMS ((tree));
|
2000-01-31 22:00:01 +01:00
|
|
|
|
static void modify_vtable_entry PARAMS ((tree, tree, tree, tree, tree *));
|
2000-01-26 21:51:37 +01:00
|
|
|
|
static void add_virtual_function PARAMS ((tree *, tree *, int *, tree, tree));
|
|
|
|
|
static tree delete_duplicate_fields_1 PARAMS ((tree, tree));
|
|
|
|
|
static void delete_duplicate_fields PARAMS ((tree));
|
|
|
|
|
static void finish_struct_bits PARAMS ((tree));
|
|
|
|
|
static int alter_access PARAMS ((tree, tree, tree, tree));
|
|
|
|
|
static void handle_using_decl PARAMS ((tree, tree));
|
|
|
|
|
static int overrides PARAMS ((tree, tree));
|
|
|
|
|
static int strictly_overrides PARAMS ((tree, tree));
|
|
|
|
|
static void mark_overriders PARAMS ((tree, tree));
|
|
|
|
|
static void check_for_override PARAMS ((tree, tree));
|
|
|
|
|
static tree dfs_modify_vtables PARAMS ((tree, void *));
|
|
|
|
|
static tree modify_all_vtables PARAMS ((tree, int *, tree));
|
|
|
|
|
static void determine_primary_base PARAMS ((tree, int *));
|
|
|
|
|
static void finish_struct_methods PARAMS ((tree));
|
|
|
|
|
static void maybe_warn_about_overly_private_class PARAMS ((tree));
|
|
|
|
|
static int field_decl_cmp PARAMS ((const tree *, const tree *));
|
|
|
|
|
static int method_name_cmp PARAMS ((const tree *, const tree *));
|
|
|
|
|
static tree add_implicitly_declared_members PARAMS ((tree, int, int, int));
|
|
|
|
|
static tree fixed_type_or_null PARAMS ((tree, int *));
|
|
|
|
|
static tree resolve_address_of_overloaded_function PARAMS ((tree, tree, int,
|
Warning fixes:
* call.c (op_error): Const-ify a char*.
(add_candidate, source_type, add_warning): Add static prototype.
(print_z_candidates): Const-ify a char*.
* class.c (resolve_address_of_overloaded_function,
fixed_type_or_null, build_vtable_entry_ref): Add static prototype.
(get_vtable_name, finish_struct_1): Const-ify a char*.
* cvt.c (convert_to_reference): Likewise.
* decl.c (redeclaration_error_message, record_builtin_type,
record_unknown_type, member_function_or_else, bad_specifiers):
Likewise.
(find_binding, select_decl, unqualified_namespace_lookup,
lookup_flags, qualify_lookup, record_builtin_java_type, tag_name):
Add static prototype.
(warn_extern_redeclared_static, duplicate_decls, pushdecl,
implicitly_declare, record_builtin_java_type, define_function,
grok_op_properties, tag_name): Const-ify a char*.
* cp-tree.h (FORMAT_VBASE_NAME): Allow parameter `BUF' to be const.
(define_function, finish_builtin_type): Const-ify a char*.
(cp_error, cp_error_at, cp_warning, cp_warning_at, cp_pedwarn,
cp_pedwarn_at, cp_compiler_error, cp_sprintf): Add prototype args.
(file_name_nondirectory): Const-ify a char*.
(init_filename_times): Don't prototype.
(compiler_error): Prototype.
(yyerror, init_repo): Const-ify a char*.
(build_srcloc): Don't prototype.
(build_x_indirect_ref, build_indirect_ref, build_component_addr):
Const-ify a char*.
(warn_for_assignment): Don't prototype.
(convert_for_initialization, readonly_error, check_for_new_type,
GNU_xref_begin, GNU_xref_file, GNU_xref_ref, GNU_xref_call):
Const-ify a char*.
* decl2.c (acceptable_java_type, output_vtable_inherit,
setup_initp, start_objects, finish_objects, do_dtors, do_ctors,
merge_functions, decl_namespace, validate_nonmember_using_decl,
do_nonmember_using_decl): Add static prototype.
(lang_f_options): Const-ify a char*.
(finish_builtin_type): Likewise.
(add_function, arg_assoc_namespace, arg_assoc_class): Add static
prototype.
* errfn.c: Include cp-tree.h.
(cp_thing): Add static prototype.
(compiler_error): Don't protoptype.
(cp_compiler_error): Cast `compiler_error' to `errorfn' before
passing it to `cp_thing'.
* error.c (interesting_scope_p): Add static prototype.
* except.c (build_eh_type_type, build_eh_type_type_ref): Const-ify
a char*.
* init.c (compiler_error): Don't prototype.
(member_init_ok_or_else): Const-ify a char*.
(build_java_class_ref): Add static prototype.
* lex.c (compiler_error): Don't prototype.
(get_time_identifier, interface_strcmp, extend_token_buffer,
handle_cp_pragma): Const-ify a char*.
(is_global, init_filename_times): Add static prototype.
(file_name_nondirectory, cplus_tree_code_name): Const-ify a char*.
(compiler_error): Change from fixed args to variable args.
(yyerror): Const-ify a char*.
* parse.y (cond_stmt_keyword): Const-ify a char*.
(parse_decl): Add static prototype.
* pt.c (template_args_equal, print_template_context): Likewise.
(print_candidates, check_default_tmpl_args): Const-ify a char*.
(instantiate_class_template): Likewise.
* repo.c (get_base_filename, open_repo_file, init_repo): Likewise.
* rtti.c (call_void_fn, expand_generic_desc, expand_si_desc,
expand_class_desc, expand_ptr_desc, expand_attr_desc): Likewise.
* search.c (lookup_field_info, lookup_member): Likewise.
(lookup_member): Cast the first argument of `bzero' to a PTR.
* sig.c (compiler_error): Don't prototype.
(build_signature_pointer_or_reference_nam): Const-ify a char*.
(get_sigtable_name, build_member_function_pointer): Likewise.
* tree.c (compiler_error): Don't prototype.
(no_linkage_helper, build_srcloc): Add static prototype.
(build_vbase_pointer_fields): Const-ify a char*.
(__eprintf): Don't unnecessarily handle `const' when !__STDC__.
* typeck.c (compiler_error): Don't prototype.
(convert_for_assignment): Const-ify a char*.
(comp_cv_target_types): Add static prototype.
(build_x_indirect_ref, build_indirect_ref, convert_arguments,
build_component_addr, build_unary_op, convert_for_initialization):
Const-ify a char*.
* typeck2.c (ack): Add static prototype and change from fixed args
to variable args.
(readonly_error, check_for_new_type): Const-ify a char*.
* xref.c (_XREF_FILE, find_file, filename, fctname, declname,
fixname, open_xref_file, classname, GNU_xref_begin): Likewise.
(GNU_xref_file): Likewise. Also use `xmalloc' instead of `malloc'.
(GNU_xref_end_scope, GNU_xref_ref, GNU_xref_decl, GNU_xref_call,
gen_assign, GNU_xref_member): Const-ify a char*.
From-SVN: r25994
1999-03-26 08:45:00 +01:00
|
|
|
|
int, tree));
|
2000-01-26 21:51:37 +01:00
|
|
|
|
static void build_vtable_entry_ref PARAMS ((tree, tree, tree));
|
|
|
|
|
static tree build_vtbl_initializer PARAMS ((tree, tree));
|
|
|
|
|
static int count_fields PARAMS ((tree));
|
|
|
|
|
static int add_fields_to_vec PARAMS ((tree, tree, int));
|
|
|
|
|
static void check_bitfield_decl PARAMS ((tree));
|
|
|
|
|
static void check_field_decl PARAMS ((tree, tree, int *, int *, int *, int *));
|
|
|
|
|
static void check_field_decls PARAMS ((tree, tree *, int *, int *, int *,
|
1999-12-16 23:18:22 +01:00
|
|
|
|
int *));
|
2000-01-26 21:51:37 +01:00
|
|
|
|
static int avoid_overlap PARAMS ((tree, tree, int *));
|
|
|
|
|
static tree build_base_field PARAMS ((tree, tree, int *, int *, unsigned int *));
|
|
|
|
|
static tree build_base_fields PARAMS ((tree, int *));
|
|
|
|
|
static tree build_vbase_pointer_fields PARAMS ((tree, int *));
|
2000-02-01 03:17:06 +01:00
|
|
|
|
static tree build_vtbl_or_vbase_field PARAMS ((tree, tree, tree, tree, tree,
|
|
|
|
|
int *));
|
2000-01-26 21:51:37 +01:00
|
|
|
|
static void check_methods PARAMS ((tree));
|
|
|
|
|
static void remove_zero_width_bit_fields PARAMS ((tree));
|
|
|
|
|
static void check_bases PARAMS ((tree, int *, int *, int *));
|
|
|
|
|
static void check_bases_and_members PARAMS ((tree, int *));
|
|
|
|
|
static void create_vtable_ptr PARAMS ((tree, int *, int *, tree *, tree *));
|
|
|
|
|
static void layout_class_type PARAMS ((tree, int *, int *, tree *, tree *));
|
|
|
|
|
static void fixup_pending_inline PARAMS ((struct pending_inline *));
|
|
|
|
|
static void fixup_inline_methods PARAMS ((tree));
|
|
|
|
|
static void set_primary_base PARAMS ((tree, int, int *));
|
|
|
|
|
static tree dfs_propagate_binfo_offsets PARAMS ((tree, void *));
|
|
|
|
|
static void propagate_binfo_offsets PARAMS ((tree, tree));
|
|
|
|
|
static void layout_basetypes PARAMS ((tree));
|
|
|
|
|
static void layout_virtual_bases PARAMS ((tree));
|
|
|
|
|
static void remove_base_field PARAMS ((tree, tree, tree *));
|
|
|
|
|
static void remove_base_fields PARAMS ((tree));
|
|
|
|
|
static tree dfs_set_offset_for_shared_vbases PARAMS ((tree, void *));
|
|
|
|
|
static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *));
|
|
|
|
|
static tree dfs_build_vbase_offset_vtbl_entries PARAMS ((tree, void *));
|
|
|
|
|
static tree build_vbase_offset_vtbl_entries PARAMS ((tree, tree));
|
|
|
|
|
static tree dfs_vcall_offset_queue_p PARAMS ((tree, void *));
|
|
|
|
|
static tree dfs_build_vcall_offset_vtbl_entries PARAMS ((tree, void *));
|
|
|
|
|
static tree build_vcall_offset_vtbl_entries PARAMS ((tree, tree));
|
|
|
|
|
static tree dfs_count_virtuals PARAMS ((tree, void *));
|
|
|
|
|
static void start_vtable PARAMS ((tree, int *));
|
|
|
|
|
static void layout_vtable_decl PARAMS ((tree, int));
|
|
|
|
|
static int num_vfun_entries PARAMS ((tree));
|
2000-01-31 22:00:01 +01:00
|
|
|
|
static tree dfs_find_final_overrider PARAMS ((tree, void *));
|
|
|
|
|
static tree find_final_overrider PARAMS ((tree, tree, tree));
|
|
|
|
|
static tree dfs_find_base PARAMS ((tree, void *));
|
2000-01-31 05:03:01 +01:00
|
|
|
|
static int make_new_vtable PARAMS ((tree, tree));
|
2000-02-06 05:27:53 +01:00
|
|
|
|
extern void dump_class_hierarchy PARAMS ((tree, int));
|
2000-02-21 00:24:58 +01:00
|
|
|
|
static tree build_vtable PARAMS ((tree, tree, tree));
|
2000-02-21 05:19:12 +01:00
|
|
|
|
static void initialize_vtable PARAMS ((tree, tree));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1994-03-24 00:33:53 +01:00
|
|
|
|
/* Variables shared between class.c and call.c. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1996-02-28 23:01:56 +01:00
|
|
|
|
#ifdef GATHER_STATISTICS
|
1994-02-24 02:02:37 +01:00
|
|
|
|
int n_vtables = 0;
|
|
|
|
|
int n_vtable_entries = 0;
|
|
|
|
|
int n_vtable_searches = 0;
|
|
|
|
|
int n_vtable_elems = 0;
|
|
|
|
|
int n_convert_harshness = 0;
|
|
|
|
|
int n_compute_conversion_costs = 0;
|
|
|
|
|
int n_build_method_call = 0;
|
|
|
|
|
int n_inner_fields_searched = 0;
|
1996-02-28 23:01:56 +01:00
|
|
|
|
#endif
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
2000-01-16 18:38:06 +01:00
|
|
|
|
/* Virtual base class layout. */
|
|
|
|
|
|
|
|
|
|
/* Returns a list of virtual base class pointers as a chain of
|
|
|
|
|
FIELD_DECLS. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1997-04-02 05:58:33 +02:00
|
|
|
|
static tree
|
2000-01-16 18:38:06 +01:00
|
|
|
|
build_vbase_pointer_fields (rec, empty_p)
|
|
|
|
|
tree rec;
|
|
|
|
|
int *empty_p;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
2000-01-16 18:38:06 +01:00
|
|
|
|
/* Chain to hold all the new FIELD_DECLs which point at virtual
|
|
|
|
|
base classes. */
|
|
|
|
|
tree vbase_decls = NULL_TREE;
|
|
|
|
|
tree binfos = TYPE_BINFO_BASETYPES (rec);
|
|
|
|
|
int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec);
|
|
|
|
|
tree decl;
|
|
|
|
|
int i;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
2000-01-17 05:08:01 +01:00
|
|
|
|
/* Under the new ABI, there are no vbase pointers in the object.
|
|
|
|
|
Instead, the offsets are stored in the vtable. */
|
|
|
|
|
if (vbase_offsets_in_vtable_p ())
|
|
|
|
|
return NULL_TREE;
|
2000-01-16 18:38:06 +01:00
|
|
|
|
|
2000-01-17 05:08:01 +01:00
|
|
|
|
/* Loop over the baseclasses, adding vbase pointers as needed. */
|
2000-01-16 18:38:06 +01:00
|
|
|
|
for (i = 0; i < n_baseclasses; i++)
|
|
|
|
|
{
|
|
|
|
|
register tree base_binfo = TREE_VEC_ELT (binfos, i);
|
|
|
|
|
register tree basetype = BINFO_TYPE (base_binfo);
|
|
|
|
|
|
|
|
|
|
if (TYPE_SIZE (basetype) == 0)
|
|
|
|
|
/* This error is now reported in xref_tag, thus giving better
|
|
|
|
|
location information. */
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* All basetypes are recorded in the association list of the
|
|
|
|
|
derived type. */
|
|
|
|
|
|
|
|
|
|
if (TREE_VIA_VIRTUAL (base_binfo))
|
|
|
|
|
{
|
|
|
|
|
int j;
|
|
|
|
|
const char *name;
|
|
|
|
|
|
|
|
|
|
/* The offset for a virtual base class is only used in computing
|
|
|
|
|
virtual function tables and for initializing virtual base
|
|
|
|
|
pointers. It is built once `get_vbase_types' is called. */
|
|
|
|
|
|
|
|
|
|
/* If this basetype can come from another vbase pointer
|
|
|
|
|
without an additional indirection, we will share
|
|
|
|
|
that pointer. If an indirection is involved, we
|
|
|
|
|
make our own pointer. */
|
|
|
|
|
for (j = 0; j < n_baseclasses; j++)
|
|
|
|
|
{
|
|
|
|
|
tree other_base_binfo = TREE_VEC_ELT (binfos, j);
|
|
|
|
|
if (! TREE_VIA_VIRTUAL (other_base_binfo)
|
|
|
|
|
&& BINFO_FOR_VBASE (basetype, BINFO_TYPE (other_base_binfo)))
|
|
|
|
|
goto got_it;
|
|
|
|
|
}
|
|
|
|
|
FORMAT_VBASE_NAME (name, basetype);
|
|
|
|
|
decl = build_vtbl_or_vbase_field (get_identifier (name),
|
|
|
|
|
get_identifier (VTABLE_BASE),
|
|
|
|
|
build_pointer_type (basetype),
|
|
|
|
|
rec,
|
2000-02-01 03:17:06 +01:00
|
|
|
|
basetype,
|
2000-01-16 18:38:06 +01:00
|
|
|
|
empty_p);
|
|
|
|
|
BINFO_VPTR_FIELD (base_binfo) = decl;
|
|
|
|
|
TREE_CHAIN (decl) = vbase_decls;
|
|
|
|
|
vbase_decls = decl;
|
|
|
|
|
*empty_p = 0;
|
|
|
|
|
|
|
|
|
|
got_it:
|
|
|
|
|
/* The space this decl occupies has already been accounted for. */
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return vbase_decls;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
2000-01-16 18:38:06 +01:00
|
|
|
|
/* Called from build_vbase_offset_vtbl_entries via dfs_walk. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
2000-01-16 18:38:06 +01:00
|
|
|
|
static tree
|
|
|
|
|
dfs_build_vbase_offset_vtbl_entries (binfo, data)
|
|
|
|
|
tree binfo;
|
|
|
|
|
void *data;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
2000-01-16 18:38:06 +01:00
|
|
|
|
tree list = (tree) data;
|
|
|
|
|
|
|
|
|
|
if (TREE_TYPE (list) == binfo)
|
|
|
|
|
/* The TREE_TYPE of LIST is the base class from which we started
|
|
|
|
|
walking. If that BINFO is virtual it's not a virtual baseclass
|
|
|
|
|
of itself. */
|
|
|
|
|
;
|
|
|
|
|
else if (TREE_VIA_VIRTUAL (binfo))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
2000-01-16 18:38:06 +01:00
|
|
|
|
tree init;
|
2000-01-17 05:08:01 +01:00
|
|
|
|
tree vbase;
|
|
|
|
|
|
|
|
|
|
/* Remember the index to the vbase offset for this virtual
|
|
|
|
|
base. */
|
|
|
|
|
vbase = BINFO_FOR_VBASE (TREE_TYPE (binfo), TREE_PURPOSE (list));
|
|
|
|
|
if (!TREE_VALUE (list))
|
|
|
|
|
BINFO_VPTR_FIELD (vbase) = build_int_2 (-1, 0);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
BINFO_VPTR_FIELD (vbase) = TREE_PURPOSE (TREE_VALUE (list));
|
|
|
|
|
BINFO_VPTR_FIELD (vbase) = ssize_binop (MINUS_EXPR,
|
|
|
|
|
BINFO_VPTR_FIELD (vbase),
|
|
|
|
|
integer_one_node);
|
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
2000-01-17 05:08:01 +01:00
|
|
|
|
/* And record the offset at which this virtual base lies in the
|
|
|
|
|
vtable. */
|
2000-01-16 18:38:06 +01:00
|
|
|
|
init = BINFO_OFFSET (binfo);
|
2000-01-17 05:08:01 +01:00
|
|
|
|
TREE_VALUE (list) = tree_cons (BINFO_VPTR_FIELD (vbase),
|
|
|
|
|
init,
|
|
|
|
|
TREE_VALUE (list));
|
2000-01-16 18:38:06 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SET_BINFO_VTABLE_PATH_MARKED (binfo);
|
|
|
|
|
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-17 05:08:01 +01:00
|
|
|
|
/* Returns the initializers for the vbase offset entries in the vtable
|
|
|
|
|
for BINFO (which is part of the class hierarchy dominated by T), in
|
|
|
|
|
reverse order. */
|
2000-01-16 18:38:06 +01:00
|
|
|
|
|
|
|
|
|
static tree
|
2000-01-17 05:08:01 +01:00
|
|
|
|
build_vbase_offset_vtbl_entries (binfo, t)
|
2000-01-16 18:38:06 +01:00
|
|
|
|
tree binfo;
|
2000-01-17 05:08:01 +01:00
|
|
|
|
tree t;
|
2000-01-16 18:38:06 +01:00
|
|
|
|
{
|
|
|
|
|
tree inits;
|
|
|
|
|
tree init;
|
2000-01-17 05:08:01 +01:00
|
|
|
|
tree list;
|
2000-01-16 18:38:06 +01:00
|
|
|
|
|
|
|
|
|
/* Under the old ABI, pointers to virtual bases are stored in each
|
|
|
|
|
object. */
|
2000-01-17 05:08:01 +01:00
|
|
|
|
if (!vbase_offsets_in_vtable_p ())
|
2000-01-16 18:38:06 +01:00
|
|
|
|
return NULL_TREE;
|
|
|
|
|
|
|
|
|
|
/* If there are no virtual baseclasses, then there is nothing to
|
|
|
|
|
do. */
|
2000-01-17 05:08:01 +01:00
|
|
|
|
if (!TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo)))
|
2000-01-16 18:38:06 +01:00
|
|
|
|
return NULL_TREE;
|
|
|
|
|
|
|
|
|
|
inits = NULL_TREE;
|
|
|
|
|
|
2000-01-17 05:08:01 +01:00
|
|
|
|
/* The offsets are allocated in the reverse order of a
|
|
|
|
|
depth-first left-to-right traversal of the hierarchy. We use
|
|
|
|
|
BINFO_VTABLE_PATH_MARKED because we are ourselves during a
|
|
|
|
|
dfs_walk, and so BINFO_MARKED is already in use. */
|
|
|
|
|
list = build_tree_list (t, NULL_TREE);
|
|
|
|
|
TREE_TYPE (list) = binfo;
|
|
|
|
|
dfs_walk (binfo,
|
|
|
|
|
dfs_build_vbase_offset_vtbl_entries,
|
|
|
|
|
dfs_vtable_path_unmarked_real_bases_queue_p,
|
|
|
|
|
list);
|
|
|
|
|
dfs_walk (binfo,
|
|
|
|
|
dfs_vtable_path_unmark,
|
|
|
|
|
dfs_vtable_path_marked_real_bases_queue_p,
|
|
|
|
|
list);
|
|
|
|
|
inits = nreverse (TREE_VALUE (list));
|
2000-01-16 18:38:06 +01:00
|
|
|
|
|
2000-01-26 00:26:21 +01:00
|
|
|
|
/* We've now got offsets in the right order. However, the offsets
|
2000-01-16 18:38:06 +01:00
|
|
|
|
we've stored are offsets from the beginning of the complete
|
|
|
|
|
object, and we need offsets from this BINFO. */
|
|
|
|
|
for (init = inits; init; init = TREE_CHAIN (init))
|
|
|
|
|
{
|
|
|
|
|
tree exp = TREE_VALUE (init);
|
|
|
|
|
|
|
|
|
|
exp = ssize_binop (MINUS_EXPR, exp, BINFO_OFFSET (binfo));
|
2000-01-17 05:08:01 +01:00
|
|
|
|
exp = build1 (NOP_EXPR, vtable_entry_type, exp);
|
2000-01-16 18:38:06 +01:00
|
|
|
|
exp = fold (exp);
|
|
|
|
|
TREE_CONSTANT (exp) = 1;
|
2000-01-17 05:08:01 +01:00
|
|
|
|
/* The dfs_build_vbase_offset_vtbl_entries routine uses the
|
|
|
|
|
TREE_PURPOSE to scribble in. But, we need to clear it now so
|
|
|
|
|
that the values are not perceived as labeled initializers. */
|
|
|
|
|
TREE_PURPOSE (init) = NULL_TREE;
|
2000-01-16 18:38:06 +01:00
|
|
|
|
TREE_VALUE (init) = exp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return inits;
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-26 00:26:21 +01:00
|
|
|
|
typedef struct vcall_offset_data_s
|
|
|
|
|
{
|
|
|
|
|
/* The binfo for the most-derived type. */
|
|
|
|
|
tree derived;
|
|
|
|
|
/* The binfo for the virtual base for which we're building
|
|
|
|
|
initializers. */
|
|
|
|
|
tree vbase;
|
|
|
|
|
/* The vcall offset initializers built up so far. */
|
|
|
|
|
tree inits;
|
|
|
|
|
/* The number of vcall offsets accumulated. */
|
|
|
|
|
int offsets;
|
|
|
|
|
} vcall_offset_data;
|
|
|
|
|
|
|
|
|
|
/* Called from build_vcall_offset_vtbl_entries via dfs_walk. */
|
|
|
|
|
|
|
|
|
|
static tree
|
|
|
|
|
dfs_vcall_offset_queue_p (binfo, data)
|
|
|
|
|
tree binfo;
|
|
|
|
|
void *data;
|
|
|
|
|
{
|
|
|
|
|
vcall_offset_data* vod = (vcall_offset_data *) data;
|
|
|
|
|
|
|
|
|
|
return (binfo == vod->vbase) ? binfo : dfs_skip_vbases (binfo, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Called from build_vcall_offset_vtbl_entries via dfs_walk. */
|
|
|
|
|
|
|
|
|
|
static tree
|
|
|
|
|
dfs_build_vcall_offset_vtbl_entries (binfo, data)
|
|
|
|
|
tree binfo;
|
|
|
|
|
void *data;
|
|
|
|
|
{
|
|
|
|
|
vcall_offset_data* vod;
|
|
|
|
|
tree virtuals;
|
|
|
|
|
tree binfo_inits;
|
|
|
|
|
|
|
|
|
|
/* Primary bases are not interesting; all of the virtual
|
|
|
|
|
function table entries have been overridden. */
|
|
|
|
|
if (BINFO_PRIMARY_MARKED_P (binfo))
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
|
|
|
|
|
vod = (vcall_offset_data *) data;
|
|
|
|
|
binfo_inits = NULL_TREE;
|
|
|
|
|
|
|
|
|
|
/* We chain the offsets on in reverse order. That's correct --
|
|
|
|
|
build_vtbl_initializer will straighten them out. */
|
|
|
|
|
for (virtuals = skip_rtti_stuff (binfo,
|
|
|
|
|
BINFO_TYPE (binfo),
|
|
|
|
|
NULL);
|
|
|
|
|
virtuals;
|
|
|
|
|
virtuals = TREE_CHAIN (virtuals))
|
|
|
|
|
{
|
|
|
|
|
tree fn;
|
|
|
|
|
tree base;
|
|
|
|
|
tree base_binfo;
|
|
|
|
|
tree offset;
|
|
|
|
|
|
|
|
|
|
/* Figure out what function we're looking at. */
|
|
|
|
|
fn = TREE_VALUE (virtuals);
|
Make DECL_CONTEXT mean the class in which a member function was declared, even for a virtual function.
Make DECL_CONTEXT mean the class in which a member function was
declared, even for a virtual function.
* cp-tree.h (DECL_CLASS_CONTEXT): Adjust.
(DECL_FRIEND_CONTEXT): New macro.
(DECL_REAL_CONTEXT): Remove.
(SET_DECL_FRIEND_CONTEXT): Likewise.
(DECL_VIRTUAL_CONTEXT): Adjust.
(DECL_CLASS_SCOPE_P): Use TYPE_P.
(add_friends): Remove.
(hack_decl_function_context): Likewise.
* call.c (build_new_function_call): Replace DECL_REAL_CONTEXT with
CP_DECL_CONTEXT.
(build_over_call): Fix indentation. Use DECL_CONTEXT
instead of DECL_CLASS_CONTEXT.
* class.c (dfs_build_vcall_offset_vtbl_entries): Likewise.
(add_method): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT.
(strictly_overrides): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
(build_vtbl_or_vbase_field): Don't set DECL_CLASS_CONTEXT.
(build_base_field): Likewise.
(finish_struct_1): Likewise.
(build_self_reference): Likewise.
* decl.c (push_class_binding): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(pushtag): Use decl_function_context, not
hack_decl_function_context.
(decls_match): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
(duplicate_decls): Use DECL_VIRTUAL_CONTEXT.
(pushdecl): Remove bogus code.
(start_decl): Use DECL_CONTEXT rather than DECL_CLASS_CONTEXT.
(cp_finish_decl): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
(grokfndecl): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
Use decl_function_context, nothack_decl_function_context.
(grokvardecl): Don't set DECL_CLASS_CONTEXT.
(grokdeclarator): Likewise. Use decl_function_context, not
hack_decl_function_context.
(copy_args_p): Document. Don't use DECL_CLASS_CONTEXT.
(start_function): Use DECL_FRIEND_CONTEXT, not
DECL_CLASS_CONTEXT. Use decl_function_context, not
hack_decl_function_context.
(finish_function): Use decl_function_context, not
hack_decl_function_context.
(maybe_retrofit_in_chrg): Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
(grokclassfn): Set DECL_VIRTUAL_CONTEXT, not DECL_CONTEXT.
(finish_static_data_member_decl): Don't set DECL_CLASS_CONTEXT.
(grokfield): Likewise.
(finish_builtin_type): Likewise.
(finish_vtable_vardec): Use decl_function_context, not
hack_decl_function_context.
(import_export_decl): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
(start_static_initialization_or_destruction): Likewise.
(finish_static_initialization_or_destruction): Likewise.
(mark_used): Adjust logic for deciding when to synthesize methods.
* dump.c (dequeue_and_dump): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
* error.c (dump_function_decl): Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
* friend.c (is_friend): Likewise.
(add_friends): Remove.
(do_friend): Use SET_DECL_FRIEND_CONTEXT.
* lex.c (begin_definition_of_inclass_inline): Use
decl_function_context, not hack_decl_function_context.
(process_next_inline): Likewise.
(do_identifier): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
* method.c (set_mangled_name_for_decl): Use DECL_CONTEXT, not
DECL_CLASSS_CONTEXT.
(hack_identifier): Likewise.
(synthesize_method): Use decl_function_context, not
hack_decl_function_context.
* pt.c (template_class_depth_real): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(is_member_template): Use decl_function_context, not
hack_decl_function_context. Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
(build_template_decl): Set DECL_VIRTUAL_CONTEXT, not
DECL_CLASS_CONTEXT.
(check_default_tmpl_args): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(push_template_decl_real): Likewise.
(instantiate_class_template): Don't call add_friends.
(tsubst_default_argument): Use DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(tsubst_decl): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT.
Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
(set_meangled_name_for_template_decl): Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
* repo.c (repo_inline_used): Likewise.
* search.c (current_scope): Adjust for new _CONTEXT macros.
(context_for_name_lookup): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(friend_accessible_p): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
(lookup_fnfields_here):Likewise.
(check_final_overrider): Likewise.
(init_vbase_pointers): Likewise.
(virtual_context): Likewise.
* semantics.c (finish_member_declaration): Just set DECL_CONTEXT.
(expand_body): Use decl_function_context, not
hack_decl_function_context.
* tree.c (hack_decl_function_context): Remove.
* typeck.c (build_x_function_call): Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
* typeck2.c (error_not_base_type): Likewise.
From-SVN: r32018
2000-02-17 00:54:23 +01:00
|
|
|
|
base = DECL_CONTEXT (fn);
|
2000-01-26 00:26:21 +01:00
|
|
|
|
|
2000-02-20 03:46:56 +01:00
|
|
|
|
/* The FN comes from BASE. So, we must caculate the adjustment
|
|
|
|
|
from the virtual base that derived from BINFO to BASE. */
|
2000-01-26 00:26:21 +01:00
|
|
|
|
base_binfo = get_binfo (base, vod->derived, /*protect=*/0);
|
|
|
|
|
offset = ssize_binop (MINUS_EXPR,
|
|
|
|
|
BINFO_OFFSET (base_binfo),
|
|
|
|
|
BINFO_OFFSET (vod->vbase));
|
|
|
|
|
offset = build1 (NOP_EXPR, vtable_entry_type, offset);
|
|
|
|
|
offset = fold (offset);
|
|
|
|
|
TREE_CONSTANT (offset) = 1;
|
|
|
|
|
binfo_inits = tree_cons (NULL_TREE, offset, binfo_inits);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now add the initializers we've just created to the list that will
|
|
|
|
|
be returned to our caller. */
|
|
|
|
|
vod->inits = chainon (vod->inits, binfo_inits);
|
|
|
|
|
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns the initializers for the vcall offset entries in the vtable
|
|
|
|
|
for BINFO (which is part of the class hierarchy dominated by T), in
|
|
|
|
|
reverse order. */
|
|
|
|
|
|
|
|
|
|
static tree
|
|
|
|
|
build_vcall_offset_vtbl_entries (binfo, t)
|
|
|
|
|
tree binfo;
|
|
|
|
|
tree t;
|
|
|
|
|
{
|
|
|
|
|
vcall_offset_data vod;
|
|
|
|
|
|
|
|
|
|
/* Under the old ABI, the adjustments to the `this' pointer were made
|
|
|
|
|
elsewhere. */
|
|
|
|
|
if (!vcall_offsets_in_vtable_p ())
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
|
|
|
|
|
/* We only need these entries if this base is a virtual base. */
|
|
|
|
|
if (!TREE_VIA_VIRTUAL (binfo))
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
|
|
|
|
|
/* We need a vcall offset for each of the virtual functions in this
|
|
|
|
|
vtable. For example:
|
|
|
|
|
|
|
|
|
|
class A { virtual void f (); };
|
|
|
|
|
class B : virtual public A { };
|
|
|
|
|
class C: virtual public A, public B {};
|
|
|
|
|
|
|
|
|
|
Now imagine:
|
|
|
|
|
|
|
|
|
|
B* b = new C;
|
|
|
|
|
b->f();
|
|
|
|
|
|
|
|
|
|
The location of `A' is not at a fixed offset relative to `B'; the
|
|
|
|
|
offset depends on the complete object derived from `B'. So,
|
|
|
|
|
`B' vtable contains an entry for `f' that indicates by what
|
|
|
|
|
amount the `this' pointer for `B' needs to be adjusted to arrive
|
|
|
|
|
at `A'.
|
|
|
|
|
|
|
|
|
|
We need entries for all the functions in our primary vtable and
|
|
|
|
|
in our non-virtual bases vtables. For each base, the entries
|
|
|
|
|
appear in the same order as in the base; but the bases themselves
|
|
|
|
|
appear in reverse depth-first, left-to-right order. */
|
|
|
|
|
vod.derived = t;
|
|
|
|
|
vod.vbase = binfo;
|
|
|
|
|
vod.inits = NULL_TREE;
|
|
|
|
|
dfs_walk (binfo,
|
|
|
|
|
dfs_build_vcall_offset_vtbl_entries,
|
|
|
|
|
dfs_vcall_offset_queue_p,
|
|
|
|
|
&vod);
|
|
|
|
|
|
|
|
|
|
return vod.inits;
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-16 18:38:06 +01:00
|
|
|
|
/* Returns a pointer to the virtual base class of EXP that has the
|
2000-01-17 05:08:01 +01:00
|
|
|
|
indicated TYPE. EXP is of class type, not a pointer type. */
|
2000-01-16 18:38:06 +01:00
|
|
|
|
|
|
|
|
|
static tree
|
|
|
|
|
build_vbase_pointer (exp, type)
|
|
|
|
|
tree exp, type;
|
|
|
|
|
{
|
2000-01-17 05:08:01 +01:00
|
|
|
|
if (vbase_offsets_in_vtable_p ())
|
|
|
|
|
{
|
|
|
|
|
tree vbase;
|
|
|
|
|
tree vbase_ptr;
|
|
|
|
|
|
|
|
|
|
/* Find the shared copy of TYPE; that's where the vtable offset
|
|
|
|
|
is recorded. */
|
|
|
|
|
vbase = BINFO_FOR_VBASE (type, TREE_TYPE (exp));
|
|
|
|
|
/* Find the virtual function table pointer. */
|
|
|
|
|
vbase_ptr = build_vfield_ref (exp, TREE_TYPE (exp));
|
|
|
|
|
/* Compute the location where the offset will lie. */
|
|
|
|
|
vbase_ptr = build_binary_op (PLUS_EXPR,
|
|
|
|
|
vbase_ptr,
|
|
|
|
|
BINFO_VPTR_FIELD (vbase));
|
|
|
|
|
vbase_ptr = build1 (NOP_EXPR,
|
|
|
|
|
build_pointer_type (ptrdiff_type_node),
|
|
|
|
|
vbase_ptr);
|
|
|
|
|
/* Add the contents of this location to EXP. */
|
|
|
|
|
return build (PLUS_EXPR,
|
|
|
|
|
build_pointer_type (type),
|
|
|
|
|
build_unary_op (ADDR_EXPR, exp, /*noconvert=*/0),
|
|
|
|
|
build1 (INDIRECT_REF, ptrdiff_type_node, vbase_ptr));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
char *name;
|
|
|
|
|
FORMAT_VBASE_NAME (name, type);
|
|
|
|
|
return build_component_ref (exp, get_identifier (name), NULL_TREE, 0);
|
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Build multi-level access to EXPR using hierarchy path PATH.
|
|
|
|
|
CODE is PLUS_EXPR if we are going with the grain,
|
|
|
|
|
and MINUS_EXPR if we are not (in which case, we cannot traverse
|
|
|
|
|
virtual baseclass links).
|
|
|
|
|
|
|
|
|
|
TYPE is the type we want this path to have on exit.
|
|
|
|
|
|
1998-08-25 03:48:47 +02:00
|
|
|
|
NONNULL is non-zero if we know (for any reason) that EXPR is
|
|
|
|
|
not, in fact, zero. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
tree
|
1998-08-25 03:48:47 +02:00
|
|
|
|
build_vbase_path (code, type, expr, path, nonnull)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
enum tree_code code;
|
|
|
|
|
tree type, expr, path;
|
1998-08-25 03:48:47 +02:00
|
|
|
|
int nonnull;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
|
|
|
|
register int changed = 0;
|
|
|
|
|
tree last = NULL_TREE, last_virtual = NULL_TREE;
|
1997-06-18 04:25:37 +02:00
|
|
|
|
int fixed_type_p;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
tree null_expr = 0, nonnull_expr;
|
|
|
|
|
tree basetype;
|
|
|
|
|
tree offset = integer_zero_node;
|
|
|
|
|
|
1997-06-18 04:25:37 +02:00
|
|
|
|
if (BINFO_INHERITANCE_CHAIN (path) == NULL_TREE)
|
|
|
|
|
return build1 (NOP_EXPR, type, expr);
|
|
|
|
|
|
1998-08-25 03:48:47 +02:00
|
|
|
|
/* We could do better if we had additional logic to convert back to the
|
|
|
|
|
unconverted type (the static type of the complete object), and then
|
|
|
|
|
convert back to the type we want. Until that is done, we only optimize
|
|
|
|
|
if the complete type is the same type as expr has. */
|
1997-06-18 04:25:37 +02:00
|
|
|
|
fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
if (!fixed_type_p && TREE_SIDE_EFFECTS (expr))
|
|
|
|
|
expr = save_expr (expr);
|
|
|
|
|
nonnull_expr = expr;
|
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
path = reverse_path (path);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
basetype = BINFO_TYPE (path);
|
|
|
|
|
|
|
|
|
|
while (path)
|
|
|
|
|
{
|
2000-01-31 22:00:01 +01:00
|
|
|
|
if (TREE_VIA_VIRTUAL (TREE_VALUE (path)))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
2000-01-31 22:00:01 +01:00
|
|
|
|
last_virtual = BINFO_TYPE (TREE_VALUE (path));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (code == PLUS_EXPR)
|
|
|
|
|
{
|
|
|
|
|
changed = ! fixed_type_p;
|
|
|
|
|
|
|
|
|
|
if (changed)
|
|
|
|
|
{
|
|
|
|
|
tree ind;
|
|
|
|
|
|
|
|
|
|
/* We already check for ambiguous things in the caller, just
|
1996-07-11 03:13:25 +02:00
|
|
|
|
find a path. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (last)
|
|
|
|
|
{
|
|
|
|
|
tree binfo = get_binfo (last, TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (nonnull_expr))), 0);
|
|
|
|
|
nonnull_expr = convert_pointer_to_real (binfo, nonnull_expr);
|
|
|
|
|
}
|
|
|
|
|
ind = build_indirect_ref (nonnull_expr, NULL_PTR);
|
|
|
|
|
nonnull_expr = build_vbase_pointer (ind, last_virtual);
|
1995-05-16 23:10:32 +02:00
|
|
|
|
if (nonnull == 0
|
1998-08-31 14:54:18 +02:00
|
|
|
|
&& TREE_CODE (type) == POINTER_TYPE
|
1994-02-24 02:02:37 +01:00
|
|
|
|
&& null_expr == NULL_TREE)
|
|
|
|
|
{
|
1995-10-12 03:33:51 +01:00
|
|
|
|
null_expr = build1 (NOP_EXPR, build_pointer_type (last_virtual), integer_zero_node);
|
|
|
|
|
expr = build (COND_EXPR, build_pointer_type (last_virtual),
|
1995-03-16 00:03:59 +01:00
|
|
|
|
build (EQ_EXPR, boolean_type_node, expr,
|
1994-02-24 02:02:37 +01:00
|
|
|
|
integer_zero_node),
|
|
|
|
|
null_expr, nonnull_expr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* else we'll figure out the offset below. */
|
|
|
|
|
|
|
|
|
|
/* Happens in the case of parse errors. */
|
|
|
|
|
if (nonnull_expr == error_mark_node)
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_error ("cannot cast up from virtual baseclass `%T'",
|
1994-02-24 02:02:37 +01:00
|
|
|
|
last_virtual);
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-01-31 22:00:01 +01:00
|
|
|
|
last = TREE_VALUE (path);
|
|
|
|
|
path = TREE_CHAIN (path);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
/* LAST is now the last basetype assoc on the path. */
|
|
|
|
|
|
|
|
|
|
/* A pointer to a virtual base member of a non-null object
|
|
|
|
|
is non-null. Therefore, we only need to test for zeroness once.
|
|
|
|
|
Make EXPR the canonical expression to deal with here. */
|
|
|
|
|
if (null_expr)
|
|
|
|
|
{
|
|
|
|
|
TREE_OPERAND (expr, 2) = nonnull_expr;
|
1997-11-03 00:07:03 +01:00
|
|
|
|
TREE_TYPE (expr) = TREE_TYPE (TREE_OPERAND (expr, 1))
|
|
|
|
|
= TREE_TYPE (nonnull_expr);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
expr = nonnull_expr;
|
|
|
|
|
|
|
|
|
|
/* If we go through any virtual base pointers, make sure that
|
|
|
|
|
casts to BASETYPE from the last virtual base class use
|
|
|
|
|
the right value for BASETYPE. */
|
|
|
|
|
if (changed)
|
|
|
|
|
{
|
|
|
|
|
tree intype = TREE_TYPE (TREE_TYPE (expr));
|
1995-10-12 03:33:51 +01:00
|
|
|
|
if (TYPE_MAIN_VARIANT (intype) != BINFO_TYPE (last))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
|
|
|
|
tree binfo = get_binfo (last, TYPE_MAIN_VARIANT (intype), 0);
|
|
|
|
|
offset = BINFO_OFFSET (binfo);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2000-01-11 05:13:27 +01:00
|
|
|
|
offset = BINFO_OFFSET (last);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
if (TREE_INT_CST_LOW (offset))
|
|
|
|
|
{
|
1995-02-03 04:45:07 +01:00
|
|
|
|
/* Bash types to make the backend happy. */
|
1997-05-29 01:20:02 +02:00
|
|
|
|
offset = cp_convert (type, offset);
|
|
|
|
|
#if 0
|
|
|
|
|
/* This shouldn't be necessary. (mrs) */
|
1995-02-03 04:45:07 +01:00
|
|
|
|
expr = build1 (NOP_EXPR, type, expr);
|
1997-05-29 01:20:02 +02:00
|
|
|
|
#endif
|
1995-02-03 04:45:07 +01:00
|
|
|
|
|
1998-08-25 03:48:47 +02:00
|
|
|
|
/* If expr might be 0, we need to preserve that zeroness. */
|
1995-10-12 03:33:51 +01:00
|
|
|
|
if (nonnull == 0)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
|
|
|
|
if (null_expr)
|
|
|
|
|
TREE_TYPE (null_expr) = type;
|
|
|
|
|
else
|
|
|
|
|
null_expr = build1 (NOP_EXPR, type, integer_zero_node);
|
|
|
|
|
if (TREE_SIDE_EFFECTS (expr))
|
|
|
|
|
expr = save_expr (expr);
|
|
|
|
|
|
|
|
|
|
return build (COND_EXPR, type,
|
1995-03-16 00:03:59 +01:00
|
|
|
|
build (EQ_EXPR, boolean_type_node, expr, integer_zero_node),
|
1994-02-24 02:02:37 +01:00
|
|
|
|
null_expr,
|
|
|
|
|
build (code, type, expr, offset));
|
|
|
|
|
}
|
|
|
|
|
else return build (code, type, expr, offset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Cannot change the TREE_TYPE of a NOP_EXPR here, since it may
|
|
|
|
|
be used multiple times in initialization of multiple inheritance. */
|
|
|
|
|
if (null_expr)
|
|
|
|
|
{
|
|
|
|
|
TREE_TYPE (expr) = type;
|
|
|
|
|
return expr;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return build1 (NOP_EXPR, type, expr);
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-16 18:38:06 +01:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
/* Virtual function things. */
|
|
|
|
|
|
2000-01-29 04:59:09 +01:00
|
|
|
|
/* Build an entry in the virtual function table. DELTA is the offset
|
|
|
|
|
for the `this' pointer. VCALL_INDEX is the vtable index containing
|
2000-02-20 03:46:56 +01:00
|
|
|
|
the vcall offset; zero if none. ENTRY is the virtual function
|
|
|
|
|
table entry itself. It's TREE_TYPE must be VFUNC_PTR_TYPE_NODE,
|
|
|
|
|
but it may not actually be a virtual function table pointer. (For
|
|
|
|
|
example, it might be the address of the RTTI object, under the new
|
|
|
|
|
ABI.) */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1997-04-02 05:58:33 +02:00
|
|
|
|
static tree
|
2000-02-20 03:46:56 +01:00
|
|
|
|
build_vtable_entry (delta, vcall_index, entry)
|
2000-01-29 04:59:09 +01:00
|
|
|
|
tree delta;
|
|
|
|
|
tree vcall_index;
|
2000-02-20 03:46:56 +01:00
|
|
|
|
tree entry;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1994-04-08 08:08:43 +02:00
|
|
|
|
if (flag_vtable_thunks)
|
|
|
|
|
{
|
2000-01-29 04:59:09 +01:00
|
|
|
|
HOST_WIDE_INT idelta;
|
|
|
|
|
HOST_WIDE_INT ivindex;
|
|
|
|
|
|
|
|
|
|
idelta = TREE_INT_CST_LOW (delta);
|
|
|
|
|
ivindex = TREE_INT_CST_LOW (vcall_index);
|
|
|
|
|
if ((idelta || ivindex)
|
2000-02-20 03:46:56 +01:00
|
|
|
|
&& ! DECL_PURE_VIRTUAL_P (TREE_OPERAND (entry, 0)))
|
1994-04-08 08:08:43 +02:00
|
|
|
|
{
|
2000-02-20 03:46:56 +01:00
|
|
|
|
entry = make_thunk (entry, idelta, ivindex);
|
|
|
|
|
entry = build1 (ADDR_EXPR, vtable_entry_type, entry);
|
|
|
|
|
TREE_READONLY (entry) = 1;
|
|
|
|
|
TREE_CONSTANT (entry) = 1;
|
1994-04-08 08:08:43 +02:00
|
|
|
|
}
|
|
|
|
|
#ifdef GATHER_STATISTICS
|
|
|
|
|
n_vtable_entries += 1;
|
|
|
|
|
#endif
|
2000-02-20 03:46:56 +01:00
|
|
|
|
return entry;
|
1994-04-08 08:08:43 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
extern int flag_huge_objects;
|
1999-09-09 08:17:13 +02:00
|
|
|
|
tree elems = tree_cons (NULL_TREE, delta,
|
|
|
|
|
tree_cons (NULL_TREE, integer_zero_node,
|
2000-02-20 03:46:56 +01:00
|
|
|
|
build_tree_list (NULL_TREE, entry)));
|
1994-04-08 08:08:43 +02:00
|
|
|
|
tree entry = build (CONSTRUCTOR, vtable_entry_type, NULL_TREE, elems);
|
|
|
|
|
|
2000-01-29 04:59:09 +01:00
|
|
|
|
/* We don't use vcall offsets when not using vtable thunks. */
|
|
|
|
|
my_friendly_assert (integer_zerop (vcall_index), 20000125);
|
|
|
|
|
|
1998-05-22 23:05:09 +02:00
|
|
|
|
/* DELTA used to be constructed by `size_int' and/or size_binop,
|
|
|
|
|
which caused overflow problems when it was negative. That should
|
|
|
|
|
be fixed now. */
|
1994-04-08 08:08:43 +02:00
|
|
|
|
|
1998-05-22 23:05:09 +02:00
|
|
|
|
if (! int_fits_type_p (delta, delta_type_node))
|
1998-02-02 01:04:13 +01:00
|
|
|
|
{
|
|
|
|
|
if (flag_huge_objects)
|
|
|
|
|
sorry ("object size exceeds built-in limit for virtual function table implementation");
|
|
|
|
|
else
|
|
|
|
|
sorry ("object size exceeds normal limit for virtual function table implementation, recompile all source and use -fhuge-objects");
|
|
|
|
|
}
|
|
|
|
|
|
1994-04-08 08:08:43 +02:00
|
|
|
|
TREE_CONSTANT (entry) = 1;
|
|
|
|
|
TREE_STATIC (entry) = 1;
|
|
|
|
|
TREE_READONLY (entry) = 1;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
#ifdef GATHER_STATISTICS
|
1994-04-08 08:08:43 +02:00
|
|
|
|
n_vtable_entries += 1;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
#endif
|
|
|
|
|
|
1994-04-08 08:08:43 +02:00
|
|
|
|
return entry;
|
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
1998-08-28 18:11:35 +02:00
|
|
|
|
/* We want to give the assembler the vtable identifier as well as
|
|
|
|
|
the offset to the function pointer. So we generate
|
|
|
|
|
|
1998-09-01 15:17:36 +02:00
|
|
|
|
__asm__ __volatile__ (".vtable_entry %c0, %c1"
|
1998-08-28 18:11:35 +02:00
|
|
|
|
: : "s"(&class_vtable),
|
|
|
|
|
"i"((long)&vtbl[idx].pfn - (long)&vtbl[0])); */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
build_vtable_entry_ref (basetype, vtbl, idx)
|
|
|
|
|
tree basetype, vtbl, idx;
|
|
|
|
|
{
|
1998-09-01 15:17:36 +02:00
|
|
|
|
static char asm_stmt[] = ".vtable_entry %c0, %c1";
|
1998-08-28 18:11:35 +02:00
|
|
|
|
tree s, i, i2;
|
|
|
|
|
|
|
|
|
|
s = build_unary_op (ADDR_EXPR, TYPE_BINFO_VTABLE (basetype), 0);
|
|
|
|
|
s = build_tree_list (build_string (1, "s"), s);
|
|
|
|
|
|
|
|
|
|
i = build_array_ref (vtbl, idx);
|
|
|
|
|
if (!flag_vtable_thunks)
|
|
|
|
|
i = build_component_ref (i, pfn_identifier, vtable_entry_type, 0);
|
|
|
|
|
i = build_c_cast (ptrdiff_type_node, build_unary_op (ADDR_EXPR, i, 0));
|
|
|
|
|
i2 = build_array_ref (vtbl, build_int_2(0,0));
|
|
|
|
|
i2 = build_c_cast (ptrdiff_type_node, build_unary_op (ADDR_EXPR, i2, 0));
|
1999-04-20 23:48:52 +02:00
|
|
|
|
i = build_binary_op (MINUS_EXPR, i, i2);
|
1998-08-28 18:11:35 +02:00
|
|
|
|
i = build_tree_list (build_string (1, "i"), i);
|
|
|
|
|
|
1999-10-08 02:08:23 +02:00
|
|
|
|
finish_asm_stmt (ridpointers[RID_VOLATILE],
|
|
|
|
|
build_string (sizeof(asm_stmt)-1, asm_stmt),
|
|
|
|
|
NULL_TREE, chainon (s, i), NULL_TREE);
|
1998-08-28 18:11:35 +02:00
|
|
|
|
}
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
/* Given an object INSTANCE, return an expression which yields the
|
1996-04-13 01:55:07 +02:00
|
|
|
|
virtual function vtable element corresponding to INDEX. There are
|
|
|
|
|
many special cases for INSTANCE which we take care of here, mainly
|
|
|
|
|
to avoid creating extra tree nodes when we don't have to. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
tree
|
1996-04-13 01:55:07 +02:00
|
|
|
|
build_vtbl_ref (instance, idx)
|
|
|
|
|
tree instance, idx;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
|
|
|
|
tree vtbl, aref;
|
|
|
|
|
tree basetype = TREE_TYPE (instance);
|
|
|
|
|
|
|
|
|
|
if (TREE_CODE (basetype) == REFERENCE_TYPE)
|
|
|
|
|
basetype = TREE_TYPE (basetype);
|
|
|
|
|
|
1996-05-16 20:43:00 +02:00
|
|
|
|
if (instance == current_class_ref)
|
1998-10-07 04:08:55 +02:00
|
|
|
|
vtbl = build_vfield_ref (instance, basetype);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (optimize)
|
|
|
|
|
{
|
|
|
|
|
/* Try to figure out what a reference refers to, and
|
|
|
|
|
access its virtual function table directly. */
|
|
|
|
|
tree ref = NULL_TREE;
|
|
|
|
|
|
|
|
|
|
if (TREE_CODE (instance) == INDIRECT_REF
|
|
|
|
|
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (instance, 0))) == REFERENCE_TYPE)
|
|
|
|
|
ref = TREE_OPERAND (instance, 0);
|
|
|
|
|
else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
|
|
|
|
|
ref = instance;
|
|
|
|
|
|
|
|
|
|
if (ref && TREE_CODE (ref) == VAR_DECL
|
|
|
|
|
&& DECL_INITIAL (ref))
|
|
|
|
|
{
|
|
|
|
|
tree init = DECL_INITIAL (ref);
|
|
|
|
|
|
|
|
|
|
while (TREE_CODE (init) == NOP_EXPR
|
|
|
|
|
|| TREE_CODE (init) == NON_LVALUE_EXPR)
|
|
|
|
|
init = TREE_OPERAND (init, 0);
|
|
|
|
|
if (TREE_CODE (init) == ADDR_EXPR)
|
|
|
|
|
{
|
|
|
|
|
init = TREE_OPERAND (init, 0);
|
|
|
|
|
if (IS_AGGR_TYPE (TREE_TYPE (init))
|
|
|
|
|
&& (TREE_CODE (init) == PARM_DECL
|
|
|
|
|
|| TREE_CODE (init) == VAR_DECL))
|
|
|
|
|
instance = init;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IS_AGGR_TYPE (TREE_TYPE (instance))
|
|
|
|
|
&& (TREE_CODE (instance) == RESULT_DECL
|
|
|
|
|
|| TREE_CODE (instance) == PARM_DECL
|
|
|
|
|
|| TREE_CODE (instance) == VAR_DECL))
|
|
|
|
|
vtbl = TYPE_BINFO_VTABLE (basetype);
|
|
|
|
|
else
|
1998-10-07 04:08:55 +02:00
|
|
|
|
vtbl = build_vfield_ref (instance, basetype);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
1998-08-28 18:11:35 +02:00
|
|
|
|
|
1995-02-18 23:06:40 +01:00
|
|
|
|
assemble_external (vtbl);
|
1998-08-28 18:11:35 +02:00
|
|
|
|
|
|
|
|
|
if (flag_vtable_gc)
|
|
|
|
|
build_vtable_entry_ref (basetype, vtbl, idx);
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
aref = build_array_ref (vtbl, idx);
|
|
|
|
|
|
1996-04-13 01:55:07 +02:00
|
|
|
|
return aref;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Given an object INSTANCE, return an expression which yields the
|
|
|
|
|
virtual function corresponding to INDEX. There are many special
|
|
|
|
|
cases for INSTANCE which we take care of here, mainly to avoid
|
|
|
|
|
creating extra tree nodes when we don't have to. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1996-04-13 01:55:07 +02:00
|
|
|
|
tree
|
|
|
|
|
build_vfn_ref (ptr_to_instptr, instance, idx)
|
|
|
|
|
tree *ptr_to_instptr, instance;
|
|
|
|
|
tree idx;
|
|
|
|
|
{
|
|
|
|
|
tree aref = build_vtbl_ref (instance, idx);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1996-04-13 01:55:07 +02:00
|
|
|
|
/* When using thunks, there is no extra delta, and we get the pfn
|
|
|
|
|
directly. */
|
1994-04-08 08:08:43 +02:00
|
|
|
|
if (flag_vtable_thunks)
|
|
|
|
|
return aref;
|
1996-04-13 01:55:07 +02:00
|
|
|
|
|
|
|
|
|
if (ptr_to_instptr)
|
1994-04-08 08:08:43 +02:00
|
|
|
|
{
|
1996-04-13 01:55:07 +02:00
|
|
|
|
/* Save the intermediate result in a SAVE_EXPR so we don't have to
|
|
|
|
|
compute each component of the virtual function pointer twice. */
|
|
|
|
|
if (TREE_CODE (aref) == INDIRECT_REF)
|
|
|
|
|
TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0));
|
|
|
|
|
|
|
|
|
|
*ptr_to_instptr
|
|
|
|
|
= build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr),
|
|
|
|
|
*ptr_to_instptr,
|
1997-05-29 01:20:02 +02:00
|
|
|
|
cp_convert (ptrdiff_type_node,
|
|
|
|
|
build_component_ref (aref, delta_identifier, NULL_TREE, 0)));
|
1994-04-08 08:08:43 +02:00
|
|
|
|
}
|
1996-04-13 01:55:07 +02:00
|
|
|
|
|
|
|
|
|
return build_component_ref (aref, pfn_identifier, NULL_TREE, 0);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return the name of the virtual function table (as an IDENTIFIER_NODE)
|
|
|
|
|
for the given TYPE. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
static tree
|
|
|
|
|
get_vtable_name (type)
|
|
|
|
|
tree type;
|
|
|
|
|
{
|
|
|
|
|
tree type_id = build_typename_overload (type);
|
1999-12-11 20:02:10 +01:00
|
|
|
|
char *buf = (char *) alloca (strlen (VTABLE_NAME_PREFIX)
|
1997-10-16 09:20:46 +02:00
|
|
|
|
+ IDENTIFIER_LENGTH (type_id) + 2);
|
Warning fixes:
* call.c (op_error): Const-ify a char*.
(add_candidate, source_type, add_warning): Add static prototype.
(print_z_candidates): Const-ify a char*.
* class.c (resolve_address_of_overloaded_function,
fixed_type_or_null, build_vtable_entry_ref): Add static prototype.
(get_vtable_name, finish_struct_1): Const-ify a char*.
* cvt.c (convert_to_reference): Likewise.
* decl.c (redeclaration_error_message, record_builtin_type,
record_unknown_type, member_function_or_else, bad_specifiers):
Likewise.
(find_binding, select_decl, unqualified_namespace_lookup,
lookup_flags, qualify_lookup, record_builtin_java_type, tag_name):
Add static prototype.
(warn_extern_redeclared_static, duplicate_decls, pushdecl,
implicitly_declare, record_builtin_java_type, define_function,
grok_op_properties, tag_name): Const-ify a char*.
* cp-tree.h (FORMAT_VBASE_NAME): Allow parameter `BUF' to be const.
(define_function, finish_builtin_type): Const-ify a char*.
(cp_error, cp_error_at, cp_warning, cp_warning_at, cp_pedwarn,
cp_pedwarn_at, cp_compiler_error, cp_sprintf): Add prototype args.
(file_name_nondirectory): Const-ify a char*.
(init_filename_times): Don't prototype.
(compiler_error): Prototype.
(yyerror, init_repo): Const-ify a char*.
(build_srcloc): Don't prototype.
(build_x_indirect_ref, build_indirect_ref, build_component_addr):
Const-ify a char*.
(warn_for_assignment): Don't prototype.
(convert_for_initialization, readonly_error, check_for_new_type,
GNU_xref_begin, GNU_xref_file, GNU_xref_ref, GNU_xref_call):
Const-ify a char*.
* decl2.c (acceptable_java_type, output_vtable_inherit,
setup_initp, start_objects, finish_objects, do_dtors, do_ctors,
merge_functions, decl_namespace, validate_nonmember_using_decl,
do_nonmember_using_decl): Add static prototype.
(lang_f_options): Const-ify a char*.
(finish_builtin_type): Likewise.
(add_function, arg_assoc_namespace, arg_assoc_class): Add static
prototype.
* errfn.c: Include cp-tree.h.
(cp_thing): Add static prototype.
(compiler_error): Don't protoptype.
(cp_compiler_error): Cast `compiler_error' to `errorfn' before
passing it to `cp_thing'.
* error.c (interesting_scope_p): Add static prototype.
* except.c (build_eh_type_type, build_eh_type_type_ref): Const-ify
a char*.
* init.c (compiler_error): Don't prototype.
(member_init_ok_or_else): Const-ify a char*.
(build_java_class_ref): Add static prototype.
* lex.c (compiler_error): Don't prototype.
(get_time_identifier, interface_strcmp, extend_token_buffer,
handle_cp_pragma): Const-ify a char*.
(is_global, init_filename_times): Add static prototype.
(file_name_nondirectory, cplus_tree_code_name): Const-ify a char*.
(compiler_error): Change from fixed args to variable args.
(yyerror): Const-ify a char*.
* parse.y (cond_stmt_keyword): Const-ify a char*.
(parse_decl): Add static prototype.
* pt.c (template_args_equal, print_template_context): Likewise.
(print_candidates, check_default_tmpl_args): Const-ify a char*.
(instantiate_class_template): Likewise.
* repo.c (get_base_filename, open_repo_file, init_repo): Likewise.
* rtti.c (call_void_fn, expand_generic_desc, expand_si_desc,
expand_class_desc, expand_ptr_desc, expand_attr_desc): Likewise.
* search.c (lookup_field_info, lookup_member): Likewise.
(lookup_member): Cast the first argument of `bzero' to a PTR.
* sig.c (compiler_error): Don't prototype.
(build_signature_pointer_or_reference_nam): Const-ify a char*.
(get_sigtable_name, build_member_function_pointer): Likewise.
* tree.c (compiler_error): Don't prototype.
(no_linkage_helper, build_srcloc): Add static prototype.
(build_vbase_pointer_fields): Const-ify a char*.
(__eprintf): Don't unnecessarily handle `const' when !__STDC__.
* typeck.c (compiler_error): Don't prototype.
(convert_for_assignment): Const-ify a char*.
(comp_cv_target_types): Add static prototype.
(build_x_indirect_ref, build_indirect_ref, convert_arguments,
build_component_addr, build_unary_op, convert_for_initialization):
Const-ify a char*.
* typeck2.c (ack): Add static prototype and change from fixed args
to variable args.
(readonly_error, check_for_new_type): Const-ify a char*.
* xref.c (_XREF_FILE, find_file, filename, fctname, declname,
fixname, open_xref_file, classname, GNU_xref_begin): Likewise.
(GNU_xref_file): Likewise. Also use `xmalloc' instead of `malloc'.
(GNU_xref_end_scope, GNU_xref_ref, GNU_xref_decl, GNU_xref_call,
gen_assign, GNU_xref_member): Const-ify a char*.
From-SVN: r25994
1999-03-26 08:45:00 +01:00
|
|
|
|
const char *ptr = IDENTIFIER_POINTER (type_id);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ;
|
|
|
|
|
#if 0
|
2000-01-31 05:03:01 +01:00
|
|
|
|
/* We don't take off the numbers; build_secondary_vtable uses the
|
1994-02-24 02:02:37 +01:00
|
|
|
|
DECL_ASSEMBLER_NAME for the type, which includes the number
|
|
|
|
|
in `3foo'. If we were to pull them off here, we'd end up with
|
|
|
|
|
something like `_vt.foo.3bar', instead of a uniform definition. */
|
|
|
|
|
while (ptr[i] >= '0' && ptr[i] <= '9')
|
|
|
|
|
i += 1;
|
|
|
|
|
#endif
|
1999-12-11 20:02:10 +01:00
|
|
|
|
sprintf (buf, "%s%s", VTABLE_NAME_PREFIX, ptr+i);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
return get_identifier (buf);
|
|
|
|
|
}
|
|
|
|
|
|
1996-04-13 01:55:07 +02:00
|
|
|
|
/* Return the offset to the main vtable for a given base BINFO. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1996-04-13 01:55:07 +02:00
|
|
|
|
tree
|
|
|
|
|
get_vfield_offset (binfo)
|
|
|
|
|
tree binfo;
|
|
|
|
|
{
|
1998-02-01 12:45:10 +01:00
|
|
|
|
tree tmp
|
|
|
|
|
= size_binop (FLOOR_DIV_EXPR,
|
1999-10-06 21:01:44 +02:00
|
|
|
|
DECL_FIELD_BITPOS (TYPE_VFIELD (BINFO_TYPE (binfo))),
|
1998-02-01 12:45:10 +01:00
|
|
|
|
size_int (BITS_PER_UNIT));
|
|
|
|
|
tmp = convert (sizetype, tmp);
|
|
|
|
|
return size_binop (PLUS_EXPR, tmp, BINFO_OFFSET (binfo));
|
1996-04-13 01:55:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get the offset to the start of the original binfo that we derived
|
|
|
|
|
this binfo from. If we find TYPE first, return the offset only
|
|
|
|
|
that far. The shortened search is useful because the this pointer
|
|
|
|
|
on method calling is expected to point to a DECL_CONTEXT (fndecl)
|
|
|
|
|
object, and not a baseclass of it. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1996-04-13 01:55:07 +02:00
|
|
|
|
static tree
|
|
|
|
|
get_derived_offset (binfo, type)
|
|
|
|
|
tree binfo, type;
|
|
|
|
|
{
|
|
|
|
|
tree offset1 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo)));
|
|
|
|
|
tree offset2;
|
|
|
|
|
int i;
|
|
|
|
|
while (BINFO_BASETYPES (binfo)
|
|
|
|
|
&& (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1)
|
|
|
|
|
{
|
|
|
|
|
tree binfos = BINFO_BASETYPES (binfo);
|
|
|
|
|
if (BINFO_TYPE (binfo) == type)
|
|
|
|
|
break;
|
|
|
|
|
binfo = TREE_VEC_ELT (binfos, i);
|
|
|
|
|
}
|
|
|
|
|
offset2 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo)));
|
|
|
|
|
return size_binop (MINUS_EXPR, offset1, offset2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Update the rtti info for this class. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1996-04-13 01:55:07 +02:00
|
|
|
|
static void
|
|
|
|
|
set_rtti_entry (virtuals, offset, type)
|
|
|
|
|
tree virtuals, offset, type;
|
|
|
|
|
{
|
2000-01-28 14:30:13 +01:00
|
|
|
|
tree decl;
|
1996-04-13 01:55:07 +02:00
|
|
|
|
|
1999-04-13 02:39:32 +02:00
|
|
|
|
if (CLASSTYPE_COM_INTERFACE (type))
|
|
|
|
|
return;
|
|
|
|
|
|
1996-04-13 01:55:07 +02:00
|
|
|
|
if (flag_rtti)
|
2000-01-28 14:30:13 +01:00
|
|
|
|
decl = get_tinfo_decl (type);
|
|
|
|
|
else if (!new_abi_rtti_p ())
|
1999-07-27 20:15:21 +02:00
|
|
|
|
/* If someone tries to get RTTI information for a type compiled
|
|
|
|
|
without RTTI, they're out of luck. By calling __pure_virtual
|
|
|
|
|
in this case, we give a small clue as to what went wrong. We
|
|
|
|
|
could consider having a __no_typeinfo function as well, for a
|
|
|
|
|
more specific hint. */
|
2000-01-28 14:30:13 +01:00
|
|
|
|
decl = abort_fndecl;
|
|
|
|
|
else
|
|
|
|
|
/* For the new-abi, we just point to the type_info object. */
|
|
|
|
|
decl = NULL_TREE;
|
1996-04-13 01:55:07 +02:00
|
|
|
|
|
1999-07-27 20:15:21 +02:00
|
|
|
|
if (flag_vtable_thunks)
|
1996-04-13 01:55:07 +02:00
|
|
|
|
{
|
1999-07-27 20:15:21 +02:00
|
|
|
|
/* The first slot holds the offset. */
|
2000-01-31 22:00:01 +01:00
|
|
|
|
BV_DELTA (virtuals) = offset;
|
|
|
|
|
BV_VCALL_INDEX (virtuals) = integer_zero_node;
|
1996-04-13 01:55:07 +02:00
|
|
|
|
|
2000-01-28 14:30:13 +01:00
|
|
|
|
/* The next node holds the decl. */
|
1999-07-27 20:15:21 +02:00
|
|
|
|
virtuals = TREE_CHAIN (virtuals);
|
|
|
|
|
offset = integer_zero_node;
|
1996-04-13 01:55:07 +02:00
|
|
|
|
}
|
1999-07-27 20:15:21 +02:00
|
|
|
|
|
2000-01-29 04:59:09 +01:00
|
|
|
|
/* This slot holds the function to call. */
|
2000-01-31 22:00:01 +01:00
|
|
|
|
BV_DELTA (virtuals) = offset;
|
|
|
|
|
BV_VCALL_INDEX (virtuals) = integer_zero_node;
|
|
|
|
|
BV_FN (virtuals) = decl;
|
1996-04-13 01:55:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
2000-02-21 00:24:58 +01:00
|
|
|
|
/* Create a VAR_DECL for a primary or secondary vtable for
|
|
|
|
|
CLASS_TYPE. Use NAME for the name of the vtable, and VTABLE_TYPE
|
|
|
|
|
for its type. */
|
|
|
|
|
|
|
|
|
|
static tree
|
|
|
|
|
build_vtable (class_type, name, vtable_type)
|
|
|
|
|
tree class_type;
|
|
|
|
|
tree name;
|
|
|
|
|
tree vtable_type;
|
|
|
|
|
{
|
|
|
|
|
tree decl;
|
|
|
|
|
|
|
|
|
|
decl = build_lang_decl (VAR_DECL, name, vtable_type);
|
|
|
|
|
DECL_CONTEXT (decl) = class_type;
|
|
|
|
|
DECL_ARTIFICIAL (decl) = 1;
|
|
|
|
|
TREE_STATIC (decl) = 1;
|
|
|
|
|
#ifndef WRITABLE_VTABLES
|
|
|
|
|
/* Make them READONLY by default. (mrs) */
|
|
|
|
|
TREE_READONLY (decl) = 1;
|
|
|
|
|
#endif
|
|
|
|
|
DECL_VIRTUAL_P (decl) = 1;
|
|
|
|
|
import_export_vtable (decl, class_type, 0);
|
|
|
|
|
|
|
|
|
|
return decl;
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-24 11:59:02 +01:00
|
|
|
|
/* Get the VAR_DECL of the vtable for TYPE. TYPE need not be polymorphic,
|
|
|
|
|
or even complete. If this does not exist, create it. If COMPLETE is
|
|
|
|
|
non-zero, then complete the definition of it -- that will render it
|
|
|
|
|
impossible to actually build the vtable, but is useful to get at those
|
|
|
|
|
which are known to exist in the runtime. */
|
|
|
|
|
|
2000-02-20 03:46:56 +01:00
|
|
|
|
tree
|
|
|
|
|
get_vtable_decl (type, complete)
|
2000-01-24 11:59:02 +01:00
|
|
|
|
tree type;
|
|
|
|
|
int complete;
|
|
|
|
|
{
|
|
|
|
|
tree name = get_vtable_name (type);
|
|
|
|
|
tree decl = IDENTIFIER_GLOBAL_VALUE (name);
|
|
|
|
|
|
|
|
|
|
if (decl)
|
|
|
|
|
{
|
|
|
|
|
my_friendly_assert (TREE_CODE (decl) == VAR_DECL
|
|
|
|
|
&& DECL_VIRTUAL_P (decl), 20000118);
|
|
|
|
|
return decl;
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-21 00:24:58 +01:00
|
|
|
|
decl = build_vtable (type, name, void_type_node);
|
2000-01-24 11:59:02 +01:00
|
|
|
|
decl = pushdecl_top_level (decl);
|
|
|
|
|
SET_IDENTIFIER_GLOBAL_VALUE (name, decl);
|
|
|
|
|
|
|
|
|
|
/* At one time the vtable info was grabbed 2 words at a time. This
|
|
|
|
|
fails on sparc unless you have 8-byte alignment. (tiemann) */
|
|
|
|
|
DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),
|
|
|
|
|
DECL_ALIGN (decl));
|
|
|
|
|
|
|
|
|
|
if (complete)
|
|
|
|
|
cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0);
|
|
|
|
|
|
|
|
|
|
return decl;
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-31 05:03:01 +01:00
|
|
|
|
/* Build the primary virtual function table for TYPE. If BINFO is
|
|
|
|
|
non-NULL, build the vtable starting with the initial approximation
|
|
|
|
|
that it is the same as the one which is the head of the association
|
|
|
|
|
list. Returns a non-zero value if a new vtable is actually
|
|
|
|
|
created. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
2000-01-31 05:03:01 +01:00
|
|
|
|
static int
|
|
|
|
|
build_primary_vtable (binfo, type)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
tree binfo, type;
|
|
|
|
|
{
|
|
|
|
|
tree virtuals, decl;
|
|
|
|
|
|
2000-01-24 11:59:02 +01:00
|
|
|
|
decl = get_vtable_decl (type, /*complete=*/0);
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (binfo)
|
|
|
|
|
{
|
1996-04-13 01:55:07 +02:00
|
|
|
|
tree offset;
|
|
|
|
|
|
2000-01-02 03:13:53 +01:00
|
|
|
|
if (BINFO_NEW_VTABLE_MARKED (binfo))
|
|
|
|
|
/* We have already created a vtable for this base, so there's
|
|
|
|
|
no need to do it again. */
|
2000-01-31 05:03:01 +01:00
|
|
|
|
return 0;
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
virtuals = copy_list (BINFO_VIRTUALS (binfo));
|
2000-01-24 11:59:02 +01:00
|
|
|
|
TREE_TYPE (decl) = TREE_TYPE (BINFO_VTABLE (binfo));
|
|
|
|
|
DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (BINFO_VTABLE (binfo)));
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
DECL_SIZE_UNIT (decl)
|
|
|
|
|
= TYPE_SIZE_UNIT (TREE_TYPE (BINFO_VTABLE (binfo)));
|
1996-04-13 01:55:07 +02:00
|
|
|
|
|
|
|
|
|
/* Now do rtti stuff. */
|
|
|
|
|
offset = get_derived_offset (TYPE_BINFO (type), NULL_TREE);
|
1998-05-22 23:05:09 +02:00
|
|
|
|
offset = ssize_binop (MINUS_EXPR, integer_zero_node, offset);
|
1996-04-13 01:55:07 +02:00
|
|
|
|
set_rtti_entry (virtuals, offset, type);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2000-01-24 11:59:02 +01:00
|
|
|
|
my_friendly_assert (TREE_CODE (TREE_TYPE (decl)) == VOID_TYPE,
|
|
|
|
|
20000118);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
virtuals = NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef GATHER_STATISTICS
|
|
|
|
|
n_vtables += 1;
|
|
|
|
|
n_vtable_elems += list_length (virtuals);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Initialize the association list for this type, based
|
|
|
|
|
on our first approximation. */
|
|
|
|
|
TYPE_BINFO_VTABLE (type) = decl;
|
|
|
|
|
TYPE_BINFO_VIRTUALS (type) = virtuals;
|
|
|
|
|
|
|
|
|
|
binfo = TYPE_BINFO (type);
|
|
|
|
|
SET_BINFO_NEW_VTABLE_MARKED (binfo);
|
2000-01-31 05:03:01 +01:00
|
|
|
|
return 1;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Give TYPE a new virtual function table which is initialized
|
|
|
|
|
with a skeleton-copy of its original initialization. The only
|
|
|
|
|
entry that changes is the `delta' entry, so we can really
|
|
|
|
|
share a lot of structure.
|
|
|
|
|
|
|
|
|
|
FOR_TYPE is the derived type which caused this table to
|
|
|
|
|
be needed.
|
|
|
|
|
|
1997-10-16 09:20:46 +02:00
|
|
|
|
BINFO is the type association which provided TYPE for FOR_TYPE.
|
|
|
|
|
|
|
|
|
|
The order in which vtables are built (by calling this function) for
|
|
|
|
|
an object must remain the same, otherwise a binary incompatibility
|
|
|
|
|
can result. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
2000-01-31 05:03:01 +01:00
|
|
|
|
static int
|
|
|
|
|
build_secondary_vtable (binfo, for_type)
|
1994-04-22 01:30:18 +02:00
|
|
|
|
tree binfo, for_type;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1997-10-16 09:20:46 +02:00
|
|
|
|
tree basetype;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
tree orig_decl = BINFO_VTABLE (binfo);
|
1997-10-16 09:20:46 +02:00
|
|
|
|
tree name;
|
|
|
|
|
tree new_decl;
|
1996-02-28 23:01:56 +01:00
|
|
|
|
tree offset;
|
1997-10-16 09:20:46 +02:00
|
|
|
|
tree path = binfo;
|
|
|
|
|
char *buf, *buf2;
|
|
|
|
|
char joiner = '_';
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
#ifdef JOINER
|
|
|
|
|
joiner = JOINER;
|
|
|
|
|
#endif
|
|
|
|
|
|
2000-02-21 05:19:12 +01:00
|
|
|
|
if (TREE_VIA_VIRTUAL (binfo))
|
|
|
|
|
my_friendly_assert (binfo == BINFO_FOR_VBASE (BINFO_TYPE (binfo),
|
|
|
|
|
current_class_type),
|
|
|
|
|
170);
|
|
|
|
|
|
2000-01-02 03:13:53 +01:00
|
|
|
|
if (BINFO_NEW_VTABLE_MARKED (binfo))
|
|
|
|
|
/* We already created a vtable for this base. There's no need to
|
|
|
|
|
do it again. */
|
2000-01-31 05:03:01 +01:00
|
|
|
|
return 0;
|
2000-01-02 03:13:53 +01:00
|
|
|
|
|
2000-02-21 05:19:12 +01:00
|
|
|
|
/* Remember that we've created a vtable for this BINFO, so that we
|
|
|
|
|
don't try to do so again. */
|
|
|
|
|
SET_BINFO_NEW_VTABLE_MARKED (binfo);
|
|
|
|
|
|
|
|
|
|
/* Make fresh virtual list, so we can smash it later. */
|
|
|
|
|
BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo));
|
|
|
|
|
|
|
|
|
|
if (TREE_VIA_VIRTUAL (binfo))
|
|
|
|
|
{
|
|
|
|
|
tree binfo1 = BINFO_FOR_VBASE (BINFO_TYPE (binfo), for_type);
|
|
|
|
|
|
|
|
|
|
/* XXX - This should never happen, if it does, the caller should
|
|
|
|
|
ensure that the binfo is from for_type's binfos, not from any
|
|
|
|
|
base type's. We can remove all this code after a while. */
|
|
|
|
|
if (binfo1 != binfo)
|
|
|
|
|
warning ("internal inconsistency: binfo offset error for rtti");
|
|
|
|
|
|
|
|
|
|
offset = BINFO_OFFSET (binfo1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
offset = BINFO_OFFSET (binfo);
|
|
|
|
|
|
|
|
|
|
set_rtti_entry (BINFO_VIRTUALS (binfo),
|
|
|
|
|
ssize_binop (MINUS_EXPR, integer_zero_node, offset),
|
|
|
|
|
for_type);
|
|
|
|
|
|
|
|
|
|
/* In the new ABI, secondary vtables are laid out as part of the
|
|
|
|
|
same structure as the primary vtable. */
|
|
|
|
|
if (merge_primary_and_secondary_vtables_p ())
|
|
|
|
|
{
|
|
|
|
|
BINFO_VTABLE (binfo) = NULL_TREE;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
1997-10-16 09:20:46 +02:00
|
|
|
|
|
2000-02-21 05:19:12 +01:00
|
|
|
|
/* Create the declaration for the secondary vtable. */
|
|
|
|
|
basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (binfo));
|
1997-10-16 09:20:46 +02:00
|
|
|
|
buf2 = TYPE_ASSEMBLER_NAME_STRING (basetype);
|
|
|
|
|
i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1;
|
|
|
|
|
|
|
|
|
|
/* We know that the vtable that we are going to create doesn't exist
|
|
|
|
|
yet in the global namespace, and when we finish, it will be
|
|
|
|
|
pushed into the global namespace. In complex MI hierarchies, we
|
|
|
|
|
have to loop while the name we are thinking of adding is globally
|
|
|
|
|
defined, adding more name components to the vtable name as we
|
|
|
|
|
loop, until the name is unique. This is because in complex MI
|
|
|
|
|
cases, we might have the same base more than once. This means
|
|
|
|
|
that the order in which this function is called for vtables must
|
|
|
|
|
remain the same, otherwise binary compatibility can be
|
|
|
|
|
compromised. */
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
1997-12-03 04:37:17 +01:00
|
|
|
|
char *buf1 = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (for_type)
|
|
|
|
|
+ 1 + i);
|
1997-10-16 09:20:46 +02:00
|
|
|
|
char *new_buf2;
|
|
|
|
|
|
|
|
|
|
sprintf (buf1, "%s%c%s", TYPE_ASSEMBLER_NAME_STRING (for_type), joiner,
|
|
|
|
|
buf2);
|
1999-12-11 20:02:10 +01:00
|
|
|
|
buf = (char *) alloca (strlen (VTABLE_NAME_PREFIX) + strlen (buf1) + 1);
|
|
|
|
|
sprintf (buf, "%s%s", VTABLE_NAME_PREFIX, buf1);
|
1997-10-16 09:20:46 +02:00
|
|
|
|
name = get_identifier (buf);
|
|
|
|
|
|
|
|
|
|
/* If this name doesn't clash, then we can use it, otherwise
|
|
|
|
|
we add more to the name until it is unique. */
|
|
|
|
|
|
|
|
|
|
if (! IDENTIFIER_GLOBAL_VALUE (name))
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* Set values for next loop through, if the name isn't unique. */
|
|
|
|
|
|
|
|
|
|
path = BINFO_INHERITANCE_CHAIN (path);
|
|
|
|
|
|
|
|
|
|
/* We better not run out of stuff to make it unique. */
|
|
|
|
|
my_friendly_assert (path != NULL_TREE, 368);
|
|
|
|
|
|
|
|
|
|
basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (path));
|
|
|
|
|
|
1997-12-03 04:37:17 +01:00
|
|
|
|
if (for_type == basetype)
|
|
|
|
|
{
|
|
|
|
|
/* If we run out of basetypes in the path, we have already
|
|
|
|
|
found created a vtable with that name before, we now
|
|
|
|
|
resort to tacking on _%d to distinguish them. */
|
|
|
|
|
int j = 2;
|
|
|
|
|
i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i + 1 + 3;
|
|
|
|
|
buf1 = (char *) alloca (i);
|
|
|
|
|
do {
|
|
|
|
|
sprintf (buf1, "%s%c%s%c%d",
|
|
|
|
|
TYPE_ASSEMBLER_NAME_STRING (basetype), joiner,
|
|
|
|
|
buf2, joiner, j);
|
1999-12-11 20:02:10 +01:00
|
|
|
|
buf = (char *) alloca (strlen (VTABLE_NAME_PREFIX)
|
1997-12-03 04:37:17 +01:00
|
|
|
|
+ strlen (buf1) + 1);
|
1999-12-11 20:02:10 +01:00
|
|
|
|
sprintf (buf, "%s%s", VTABLE_NAME_PREFIX, buf1);
|
1997-12-03 04:37:17 +01:00
|
|
|
|
name = get_identifier (buf);
|
|
|
|
|
|
|
|
|
|
/* If this name doesn't clash, then we can use it,
|
|
|
|
|
otherwise we add something different to the name until
|
|
|
|
|
it is unique. */
|
|
|
|
|
} while (++j <= 999 && IDENTIFIER_GLOBAL_VALUE (name));
|
|
|
|
|
|
|
|
|
|
/* Hey, they really like MI don't they? Increase the 3
|
|
|
|
|
above to 6, and the 999 to 999999. :-) */
|
|
|
|
|
my_friendly_assert (j <= 999, 369);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
1997-10-16 09:20:46 +02:00
|
|
|
|
|
|
|
|
|
i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i;
|
|
|
|
|
new_buf2 = (char *) alloca (i);
|
|
|
|
|
sprintf (new_buf2, "%s%c%s",
|
|
|
|
|
TYPE_ASSEMBLER_NAME_STRING (basetype), joiner, buf2);
|
|
|
|
|
buf2 = new_buf2;
|
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
2000-02-21 00:24:58 +01:00
|
|
|
|
new_decl = build_vtable (for_type, name, TREE_TYPE (orig_decl));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
DECL_ALIGN (new_decl) = DECL_ALIGN (orig_decl);
|
2000-02-21 00:24:58 +01:00
|
|
|
|
BINFO_VTABLE (binfo) = pushdecl_top_level (new_decl);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
#ifdef GATHER_STATISTICS
|
|
|
|
|
n_vtables += 1;
|
|
|
|
|
n_vtable_elems += list_length (BINFO_VIRTUALS (binfo));
|
|
|
|
|
#endif
|
|
|
|
|
|
2000-01-31 05:03:01 +01:00
|
|
|
|
return 1;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
2000-01-31 05:03:01 +01:00
|
|
|
|
/* Create a new vtable for BINFO which is the hierarchy dominated by
|
|
|
|
|
T. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
make_new_vtable (t, binfo)
|
|
|
|
|
tree t;
|
|
|
|
|
tree binfo;
|
|
|
|
|
{
|
|
|
|
|
if (binfo == TYPE_BINFO (t))
|
|
|
|
|
/* In this case, it is *type*'s vtable we are modifying. We start
|
|
|
|
|
with the approximation that it's vtable is that of the
|
|
|
|
|
immediate base class. */
|
|
|
|
|
return build_primary_vtable (TYPE_BINFO (DECL_CONTEXT (TYPE_VFIELD (t))),
|
|
|
|
|
t);
|
|
|
|
|
else
|
|
|
|
|
/* This is our very own copy of `basetype' to play with. Later,
|
|
|
|
|
we will fill in all the virtual functions that override the
|
|
|
|
|
virtual functions in these base classes which are not defined
|
|
|
|
|
by the current type. */
|
|
|
|
|
return build_secondary_vtable (binfo, t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Make *VIRTUALS, an entry on the BINFO_VIRTUALS list for BINFO
|
|
|
|
|
(which is in the hierarchy dominated by T) list FNDECL as its
|
2000-01-31 22:00:01 +01:00
|
|
|
|
BV_FN. DELTA is the required adjustment from the `this' pointer
|
|
|
|
|
where the vtable entry appears to the `this' required when the
|
|
|
|
|
function is actually called. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
static void
|
2000-01-31 22:00:01 +01:00
|
|
|
|
modify_vtable_entry (t, binfo, fndecl, delta, virtuals)
|
2000-01-29 04:59:09 +01:00
|
|
|
|
tree t;
|
|
|
|
|
tree binfo;
|
|
|
|
|
tree fndecl;
|
2000-01-31 22:00:01 +01:00
|
|
|
|
tree delta;
|
2000-01-31 05:03:01 +01:00
|
|
|
|
tree *virtuals;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
2000-01-29 04:59:09 +01:00
|
|
|
|
tree vcall_index;
|
2000-01-31 05:03:01 +01:00
|
|
|
|
tree v;
|
2000-01-29 04:59:09 +01:00
|
|
|
|
|
2000-01-31 05:03:01 +01:00
|
|
|
|
v = *virtuals;
|
2000-01-29 04:59:09 +01:00
|
|
|
|
vcall_index = integer_zero_node;
|
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
if (fndecl != BV_FN (v)
|
|
|
|
|
|| !tree_int_cst_equal (delta, BV_DELTA (v))
|
|
|
|
|
|| !tree_int_cst_equal (vcall_index, BV_VCALL_INDEX (v)))
|
2000-01-29 04:59:09 +01:00
|
|
|
|
{
|
|
|
|
|
tree base_fndecl;
|
|
|
|
|
|
2000-01-31 05:03:01 +01:00
|
|
|
|
/* We need a new vtable for BINFO. */
|
|
|
|
|
if (make_new_vtable (t, binfo))
|
|
|
|
|
{
|
|
|
|
|
/* If we really did make a new vtable, we also made a copy
|
|
|
|
|
of the BINFO_VIRTUALS list. Now, we have to find the
|
|
|
|
|
corresponding entry in that list. */
|
|
|
|
|
*virtuals = BINFO_VIRTUALS (binfo);
|
2000-01-31 22:00:01 +01:00
|
|
|
|
while (BV_FN (*virtuals) != BV_FN (v))
|
2000-01-31 05:03:01 +01:00
|
|
|
|
*virtuals = TREE_CHAIN (*virtuals);
|
|
|
|
|
v = *virtuals;
|
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
base_fndecl = BV_FN (v);
|
|
|
|
|
BV_DELTA (v) = delta;
|
|
|
|
|
BV_VCALL_INDEX (v) = vcall_index;
|
|
|
|
|
BV_FN (v) = fndecl;
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
2000-01-29 04:59:09 +01:00
|
|
|
|
/* Now assign virtual dispatch information, if unset. We can
|
|
|
|
|
dispatch this, through any overridden base function. */
|
|
|
|
|
if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)
|
|
|
|
|
{
|
|
|
|
|
DECL_VINDEX (fndecl) = DECL_VINDEX (base_fndecl);
|
|
|
|
|
DECL_VIRTUAL_CONTEXT (fndecl) = DECL_VIRTUAL_CONTEXT (base_fndecl);
|
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-17 05:08:01 +01:00
|
|
|
|
/* Call this function whenever its known that a vtable for T is going
|
|
|
|
|
to be needed. It's safe to call it more than once. *HAS_VIRTUAL_P
|
|
|
|
|
is initialized to the number of slots that are reserved at the
|
|
|
|
|
beginning of the vtable for RTTI information. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
start_vtable (t, has_virtual_p)
|
|
|
|
|
tree t;
|
|
|
|
|
int *has_virtual_p;
|
|
|
|
|
{
|
|
|
|
|
if (*has_virtual_p == 0 && ! CLASSTYPE_COM_INTERFACE (t))
|
|
|
|
|
{
|
2000-01-17 21:18:43 +01:00
|
|
|
|
/* If we are using thunks, use two slots at the front, one
|
|
|
|
|
for the offset pointer, one for the tdesc pointer.
|
|
|
|
|
For ARM-style vtables, use the same slot for both. */
|
2000-01-17 05:08:01 +01:00
|
|
|
|
if (flag_vtable_thunks)
|
|
|
|
|
*has_virtual_p = 2;
|
|
|
|
|
else
|
|
|
|
|
*has_virtual_p = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1994-04-22 01:30:18 +02:00
|
|
|
|
/* Add a virtual function to all the appropriate vtables for the class
|
|
|
|
|
T. DECL_VINDEX(X) should be error_mark_node, if we want to
|
|
|
|
|
allocate a new slot in our table. If it is error_mark_node, we
|
|
|
|
|
know that no other function from another vtable is overridden by X.
|
|
|
|
|
HAS_VIRTUAL keeps track of how many virtuals there are in our main
|
2000-01-17 21:18:43 +01:00
|
|
|
|
vtable for the type, and we build upon the NEW_VIRTUALS list
|
1994-04-22 01:30:18 +02:00
|
|
|
|
and return it. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1997-11-27 10:45:25 +01:00
|
|
|
|
static void
|
2000-01-17 21:18:43 +01:00
|
|
|
|
add_virtual_function (new_virtuals_p, overridden_virtuals_p,
|
|
|
|
|
has_virtual, fndecl, t)
|
|
|
|
|
tree *new_virtuals_p;
|
|
|
|
|
tree *overridden_virtuals_p;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
int *has_virtual;
|
1994-04-22 01:30:18 +02:00
|
|
|
|
tree fndecl;
|
1996-07-11 03:13:25 +02:00
|
|
|
|
tree t; /* Structure type. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
2000-01-29 04:59:09 +01:00
|
|
|
|
tree new_virtual;
|
|
|
|
|
|
2000-01-17 21:18:43 +01:00
|
|
|
|
/* If this function doesn't override anything from a base class, we
|
|
|
|
|
can just assign it a new DECL_VINDEX now. Otherwise, if it does
|
|
|
|
|
override something, we keep it around and assign its DECL_VINDEX
|
|
|
|
|
later, in modify_all_vtables. */
|
|
|
|
|
if (TREE_CODE (DECL_VINDEX (fndecl)) == INTEGER_CST)
|
|
|
|
|
/* We've already dealt with this function. */
|
2000-01-29 04:59:09 +01:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
new_virtual = build_tree_list (integer_zero_node, fndecl);
|
2000-01-31 22:00:01 +01:00
|
|
|
|
BV_VCALL_INDEX (new_virtual) = integer_zero_node;
|
2000-01-29 04:59:09 +01:00
|
|
|
|
|
|
|
|
|
if (DECL_VINDEX (fndecl) == error_mark_node)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
2000-01-17 21:18:43 +01:00
|
|
|
|
/* FNDECL is a new virtual function; it doesn't override any
|
|
|
|
|
virtual function in a base class. */
|
|
|
|
|
|
1996-04-13 01:55:07 +02:00
|
|
|
|
/* We remember that this was the base sub-object for rtti. */
|
|
|
|
|
CLASSTYPE_RTTI (t) = t;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
2000-01-17 05:08:01 +01:00
|
|
|
|
start_vtable (t, has_virtual);
|
1995-10-12 03:33:51 +01:00
|
|
|
|
|
2000-01-17 23:54:23 +01:00
|
|
|
|
/* Now assign virtual dispatch information. */
|
|
|
|
|
DECL_VINDEX (fndecl) = build_shared_int_cst ((*has_virtual)++);
|
|
|
|
|
DECL_VIRTUAL_CONTEXT (fndecl) = t;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
2000-01-17 21:18:43 +01:00
|
|
|
|
/* Save the state we've computed on the NEW_VIRTUALS list. */
|
2000-01-29 04:59:09 +01:00
|
|
|
|
TREE_CHAIN (new_virtual) = *new_virtuals_p;
|
|
|
|
|
*new_virtuals_p = new_virtual;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* FNDECL overrides a function from a base class. */
|
|
|
|
|
TREE_CHAIN (new_virtual) = *overridden_virtuals_p;
|
|
|
|
|
*overridden_virtuals_p = new_virtual;
|
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern struct obstack *current_obstack;
|
|
|
|
|
|
1998-10-16 14:08:01 +02:00
|
|
|
|
/* Add method METHOD to class TYPE.
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1998-10-16 14:08:01 +02:00
|
|
|
|
If non-NULL, FIELDS is the entry in the METHOD_VEC vector entry of
|
|
|
|
|
the class type where the method should be added. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
void
|
|
|
|
|
add_method (type, fields, method)
|
|
|
|
|
tree type, *fields, method;
|
|
|
|
|
{
|
2000-02-18 07:00:36 +01:00
|
|
|
|
/* Setting the DECL_CONTEXT here is probably redundant. */
|
1998-10-06 16:20:30 +02:00
|
|
|
|
DECL_CONTEXT (method) = type;
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (fields && *fields)
|
1998-10-06 16:20:30 +02:00
|
|
|
|
*fields = build_overload (method, *fields);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int len;
|
1999-02-21 17:38:23 +01:00
|
|
|
|
int slot;
|
1998-10-06 16:20:30 +02:00
|
|
|
|
tree method_vec;
|
|
|
|
|
|
|
|
|
|
if (!CLASSTYPE_METHOD_VEC (type))
|
|
|
|
|
/* Make a new method vector. We start with 8 entries. We must
|
|
|
|
|
allocate at least two (for constructors and destructors), and
|
|
|
|
|
we're going to end up with an assignment operator at some
|
|
|
|
|
point as well.
|
|
|
|
|
|
|
|
|
|
We could use a TREE_LIST for now, and convert it to a
|
|
|
|
|
TREE_VEC in finish_struct, but we would probably waste more
|
|
|
|
|
memory making the links in the list than we would by
|
|
|
|
|
over-allocating the size of the vector here. Furthermore,
|
|
|
|
|
we would complicate all the code that expects this to be a
|
1999-09-07 18:07:42 +02:00
|
|
|
|
vector. */
|
|
|
|
|
CLASSTYPE_METHOD_VEC (type) = make_tree_vec (8);
|
1998-10-06 16:20:30 +02:00
|
|
|
|
|
|
|
|
|
method_vec = CLASSTYPE_METHOD_VEC (type);
|
|
|
|
|
len = TREE_VEC_LENGTH (method_vec);
|
|
|
|
|
|
|
|
|
|
if (DECL_NAME (method) == constructor_name (type))
|
1999-02-21 17:38:23 +01:00
|
|
|
|
/* A new constructor or destructor. Constructors go in
|
|
|
|
|
slot 0; destructors go in slot 1. */
|
|
|
|
|
slot = DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method)) ? 1 : 0;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
1998-10-06 16:20:30 +02:00
|
|
|
|
/* See if we already have an entry with this name. */
|
1999-02-21 17:38:23 +01:00
|
|
|
|
for (slot = 2; slot < len; ++slot)
|
|
|
|
|
if (!TREE_VEC_ELT (method_vec, slot)
|
|
|
|
|
|| (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec,
|
|
|
|
|
slot)))
|
1998-10-06 16:20:30 +02:00
|
|
|
|
== DECL_NAME (method)))
|
|
|
|
|
break;
|
|
|
|
|
|
1999-02-21 17:38:23 +01:00
|
|
|
|
if (slot == len)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1998-10-06 16:20:30 +02:00
|
|
|
|
/* We need a bigger method vector. */
|
1999-09-07 18:07:42 +02:00
|
|
|
|
tree new_vec = make_tree_vec (2 * len);
|
1998-10-17 22:33:45 +02:00
|
|
|
|
bcopy ((PTR) &TREE_VEC_ELT (method_vec, 0),
|
|
|
|
|
(PTR) &TREE_VEC_ELT (new_vec, 0),
|
1998-10-06 16:20:30 +02:00
|
|
|
|
len * sizeof (tree));
|
|
|
|
|
len = 2 * len;
|
|
|
|
|
method_vec = CLASSTYPE_METHOD_VEC (type) = new_vec;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
1998-10-06 16:20:30 +02:00
|
|
|
|
|
1999-02-21 17:38:23 +01:00
|
|
|
|
if (DECL_CONV_FN_P (method) && !TREE_VEC_ELT (method_vec, slot))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1998-10-06 16:20:30 +02:00
|
|
|
|
/* Type conversion operators have to come before
|
|
|
|
|
ordinary methods; add_conversions depends on this to
|
|
|
|
|
speed up looking for conversion operators. So, if
|
|
|
|
|
necessary, we slide some of the vector elements up.
|
|
|
|
|
In theory, this makes this algorithm O(N^2) but we
|
|
|
|
|
don't expect many conversion operators. */
|
1999-02-21 17:38:23 +01:00
|
|
|
|
for (slot = 2; slot < len; ++slot)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1999-02-21 17:38:23 +01:00
|
|
|
|
tree fn = TREE_VEC_ELT (method_vec, slot);
|
|
|
|
|
|
1998-10-06 16:20:30 +02:00
|
|
|
|
if (!fn)
|
|
|
|
|
/* There are no more entries in the vector, so we
|
|
|
|
|
can insert the new conversion operator here. */
|
|
|
|
|
break;
|
1999-02-21 17:38:23 +01:00
|
|
|
|
|
|
|
|
|
if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
|
|
|
|
|
/* We can insert the new function right at the
|
|
|
|
|
SLOTth position. */
|
1998-10-06 16:20:30 +02:00
|
|
|
|
break;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
1999-02-21 17:38:23 +01:00
|
|
|
|
|
|
|
|
|
if (!TREE_VEC_ELT (method_vec, slot))
|
1998-10-06 16:20:30 +02:00
|
|
|
|
/* There is nothing in the Ith slot, so we can avoid
|
|
|
|
|
moving anything. */
|
|
|
|
|
;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
else
|
1998-10-06 16:20:30 +02:00
|
|
|
|
{
|
|
|
|
|
/* We know the last slot in the vector is empty
|
1999-02-21 17:38:23 +01:00
|
|
|
|
because we know that at this point there's room
|
|
|
|
|
for a new function. */
|
|
|
|
|
bcopy ((PTR) &TREE_VEC_ELT (method_vec, slot),
|
|
|
|
|
(PTR) &TREE_VEC_ELT (method_vec, slot + 1),
|
|
|
|
|
(len - slot - 1) * sizeof (tree));
|
|
|
|
|
TREE_VEC_ELT (method_vec, slot) = NULL_TREE;
|
1998-10-06 16:20:30 +02:00
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
1998-10-06 16:20:30 +02:00
|
|
|
|
}
|
|
|
|
|
|
1999-02-21 17:38:23 +01:00
|
|
|
|
if (template_class_depth (type))
|
|
|
|
|
/* TYPE is a template class. Don't issue any errors now; wait
|
|
|
|
|
until instantiation time to complain. */
|
|
|
|
|
;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tree fns;
|
|
|
|
|
|
|
|
|
|
/* Check to see if we've already got this method. */
|
|
|
|
|
for (fns = TREE_VEC_ELT (method_vec, slot);
|
|
|
|
|
fns;
|
|
|
|
|
fns = OVL_NEXT (fns))
|
|
|
|
|
{
|
|
|
|
|
tree fn = OVL_CURRENT (fns);
|
|
|
|
|
|
|
|
|
|
if (TREE_CODE (fn) != TREE_CODE (method))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (TREE_CODE (method) != TEMPLATE_DECL)
|
|
|
|
|
{
|
|
|
|
|
/* [over.load] Member function declarations with the
|
|
|
|
|
same name and the same parameter types cannot be
|
|
|
|
|
overloaded if any of them is a static member
|
|
|
|
|
function declaration. */
|
|
|
|
|
if (DECL_STATIC_FUNCTION_P (fn)
|
|
|
|
|
!= DECL_STATIC_FUNCTION_P (method))
|
|
|
|
|
{
|
|
|
|
|
tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn));
|
|
|
|
|
tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (method));
|
|
|
|
|
|
|
|
|
|
if (! DECL_STATIC_FUNCTION_P (fn))
|
|
|
|
|
parms1 = TREE_CHAIN (parms1);
|
|
|
|
|
else
|
|
|
|
|
parms2 = TREE_CHAIN (parms2);
|
|
|
|
|
|
|
|
|
|
if (compparms (parms1, parms2))
|
|
|
|
|
cp_error ("`%#D' and `%#D' cannot be overloaded",
|
|
|
|
|
fn, method);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Since this is an ordinary function in a
|
|
|
|
|
non-template class, it's mangled name can be used
|
|
|
|
|
as a unique identifier. This technique is only
|
|
|
|
|
an optimization; we would get the same results if
|
|
|
|
|
we just used decls_match here. */
|
|
|
|
|
if (DECL_ASSEMBLER_NAME (fn)
|
|
|
|
|
!= DECL_ASSEMBLER_NAME (method))
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else if (!decls_match (fn, method))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* There has already been a declaration of this method
|
|
|
|
|
or member template. */
|
|
|
|
|
cp_error_at ("`%D' has already been declared in `%T'",
|
|
|
|
|
method, type);
|
|
|
|
|
|
|
|
|
|
/* We don't call duplicate_decls here to merge the
|
|
|
|
|
declarations because that will confuse things if the
|
tinfo.h (__class_type_info): Fix illegal declaration.
1999-04-02 Mark Mitchell <mark@codesourcery.com>
* tinfo.h (__class_type_info): Fix illegal declaration.
* cp-tree.def (TEMPLATE_ID_EXPR): Update comment.
* cp-tree.h (INHERITED_VALUE_BINDING_P): New macro.
(IDENTIFIER_CLASS_VALUE): Improve documentation.
(is_properly_derived_from): Declare.
(invalidate_class_lookup_cache): Likewise.
(maybe_maybe_note_name_used_in_class): Likewise.
(note_name_declared_in_class): Likewise.
(push_using_decl): Remove duplicate declaration.
(id_in_current_class): Remove declaration.
(push_class_binding): Change prototype.
(clear_identitifer_class_values): Declare.
* call.c (is_properly_derived_from): Make it global.
(build_new_function_call): Be careful about updating candidates.
(build_new_method_call): Handle COMPONENT_REFs. Don't crash when
asked to make illegal calls.
* class.c: Include splay-tree.h.
(class_stack_node): Add names_used slot.
(check_member_decl_is_same_in_complete_scope): Remove.
(add_method): Fix comment. Push the declaration into class
scope.
(finish_struct_1): When popping the class, pop the bindings too.
Remove check for data member/function member conflict.
(finish_struct): Remove calls to
check_member_decl_is_same_in_complete_scope. Change calls to
popclass.
(pushclass): Clear names_used in the class stack entry.
Use invalidate_class_lookup_cache to remove cached entries, rather
than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE
before entering a new class. Remove dead code. Don't mess with
current_function_decl when pushing declarations.
(invalidate_class_lookup_cache): New function, split out from ...
(popclass): Here. Clean up names_used on our way out.
(instantiate_type): Adjust.
(build_self_reference): Don't push the declaration here.
(maybe_note_name_used_in_class): New function.
(note_name_declared_in_class): Likewise.
* decl.c (add_binding): Change prototype.
(find_class_binding_level): New function.
(innermost_nonclass_level): Likewise.
(current_binding_level): Update documentation.
(inner_binding_level): Remove. Replace with current_binding_level
throughout.
(push_binding_level): Remove special handling of
class_binding_level.
(pop_binding_level): Likewise. Use find_class_binding_level.
(suspend_binding_level): Likewise.
(global_bindings_p): Use innermost_nonclass_level.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(pseudo_global_level_p): Likewise.
(push_binding): Clear INHERITED_VALUE_BINDING_P.
(add_binding): Check for illegal multiple declarations. Return a
value indicating whether or not the new binding was legal.
(push_local_binding): Skip over class binding levels. Check
return value from add_binding.
(push_class_binding): Set INHERITED_VALUE_BINDING_P. Call
note_name_declared_in_class.
(pushlevel_class): Remove "fake out the rest of the compiler"
code.
(poplevel_class): Reset IDENTIFIER_CLASS_VALUEs.
(clear_identifier_class_values): New function.
(pop_from_top_level): Use it.
(pop_everything): Tweak.
(maybe_process_template_type_declaration): Don't push the
declaration for the template here.
(pushtag): Don't push tag declarations into class scope here.
(pushdecl): Apply DeMorgan's law for readability.
(pushdecl_class_level): Remove special-case code for
TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions.
(push_class_level_bindng): Deal with inherited bindings.
(lookup_name_real): Remove special-case code for
TYPE_BEING_DEFINED, and some implicit typename magic.
(grokdeclarator): Handle COMPONENT_REF for a template function.
(build_enumerator): Don't call pushdecl_class_level here.
(id_in_current_class): Remove.
* decl2.c (grokfield): Don't call pushdecl_class_level or
check_template_shadow.
* errfn.c (cp_file_of): Don't declare.
(cp_line_of): Likewise.
* error.c (dump_decl): Handle an OVERLOAD.
(cp_file_of): Likewise.
(cp_line_of): Likewise.
* init.c (build_member_call): Handle a COMPONENT_REF.
* lex.c (do_identifier): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* method.c (hack_identifier): Build COMPONENT_REFs for references
to member templates as well as member functions. Remove dead
code.
* parse.y (left_curly): Remove.
(nonnested_type): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* parse.c: Regenerated.
(nested_name_specifier_1): Likewise.
* pt.c (check_explicit_specialization): Adjust, for robustness.
(check_template_shadow): Handle OVERLOADs.
(build_template_decl): Set DECL_CONSTRUCTOR_P on the
TEMPLATE_DECL, if appropriate.
* search.c (envelope_add_decl): Remove.
(dfs_pushdecls): Likewise.
(dfs_compress_decls): Likewise.
(dfs_push_decls): New function.
(dfs_push_type_decls): Likewise.
(setup_class_bindings): Likewise.
(template_self_reference_p): Likewise.
(lookup_field_r): Use it.
(looup_member): Remove old comment. Deal with ambiguity.
(push_class_decls): Use dfs_push_decls and dfs_push_type_decls,
and remove envelope processing.
* semantics.c (begin_class_definition): Let pushclass push
declarations for base classes.
(finish_member_declaration): Push declarations into class scope.
* typeck.c (build_component_ref): Just put an OVERLOAD into the
COMPONENT_REF, not a TREE_LIST of an OVERLOAD.
(build_x_function_call): Deal with OVERLOAD. Handle template-ids.
* Makefile.in (class.o): Depend on splay-tree.h.
From-SVN: r26133
1999-04-02 17:36:57 +02:00
|
|
|
|
methods have inline definitions. In particular, we
|
1999-02-21 17:38:23 +01:00
|
|
|
|
will crash while processing the definitions. */
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Actually insert the new method. */
|
|
|
|
|
TREE_VEC_ELT (method_vec, slot)
|
|
|
|
|
= build_overload (method, TREE_VEC_ELT (method_vec, slot));
|
tinfo.h (__class_type_info): Fix illegal declaration.
1999-04-02 Mark Mitchell <mark@codesourcery.com>
* tinfo.h (__class_type_info): Fix illegal declaration.
* cp-tree.def (TEMPLATE_ID_EXPR): Update comment.
* cp-tree.h (INHERITED_VALUE_BINDING_P): New macro.
(IDENTIFIER_CLASS_VALUE): Improve documentation.
(is_properly_derived_from): Declare.
(invalidate_class_lookup_cache): Likewise.
(maybe_maybe_note_name_used_in_class): Likewise.
(note_name_declared_in_class): Likewise.
(push_using_decl): Remove duplicate declaration.
(id_in_current_class): Remove declaration.
(push_class_binding): Change prototype.
(clear_identitifer_class_values): Declare.
* call.c (is_properly_derived_from): Make it global.
(build_new_function_call): Be careful about updating candidates.
(build_new_method_call): Handle COMPONENT_REFs. Don't crash when
asked to make illegal calls.
* class.c: Include splay-tree.h.
(class_stack_node): Add names_used slot.
(check_member_decl_is_same_in_complete_scope): Remove.
(add_method): Fix comment. Push the declaration into class
scope.
(finish_struct_1): When popping the class, pop the bindings too.
Remove check for data member/function member conflict.
(finish_struct): Remove calls to
check_member_decl_is_same_in_complete_scope. Change calls to
popclass.
(pushclass): Clear names_used in the class stack entry.
Use invalidate_class_lookup_cache to remove cached entries, rather
than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE
before entering a new class. Remove dead code. Don't mess with
current_function_decl when pushing declarations.
(invalidate_class_lookup_cache): New function, split out from ...
(popclass): Here. Clean up names_used on our way out.
(instantiate_type): Adjust.
(build_self_reference): Don't push the declaration here.
(maybe_note_name_used_in_class): New function.
(note_name_declared_in_class): Likewise.
* decl.c (add_binding): Change prototype.
(find_class_binding_level): New function.
(innermost_nonclass_level): Likewise.
(current_binding_level): Update documentation.
(inner_binding_level): Remove. Replace with current_binding_level
throughout.
(push_binding_level): Remove special handling of
class_binding_level.
(pop_binding_level): Likewise. Use find_class_binding_level.
(suspend_binding_level): Likewise.
(global_bindings_p): Use innermost_nonclass_level.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(pseudo_global_level_p): Likewise.
(push_binding): Clear INHERITED_VALUE_BINDING_P.
(add_binding): Check for illegal multiple declarations. Return a
value indicating whether or not the new binding was legal.
(push_local_binding): Skip over class binding levels. Check
return value from add_binding.
(push_class_binding): Set INHERITED_VALUE_BINDING_P. Call
note_name_declared_in_class.
(pushlevel_class): Remove "fake out the rest of the compiler"
code.
(poplevel_class): Reset IDENTIFIER_CLASS_VALUEs.
(clear_identifier_class_values): New function.
(pop_from_top_level): Use it.
(pop_everything): Tweak.
(maybe_process_template_type_declaration): Don't push the
declaration for the template here.
(pushtag): Don't push tag declarations into class scope here.
(pushdecl): Apply DeMorgan's law for readability.
(pushdecl_class_level): Remove special-case code for
TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions.
(push_class_level_bindng): Deal with inherited bindings.
(lookup_name_real): Remove special-case code for
TYPE_BEING_DEFINED, and some implicit typename magic.
(grokdeclarator): Handle COMPONENT_REF for a template function.
(build_enumerator): Don't call pushdecl_class_level here.
(id_in_current_class): Remove.
* decl2.c (grokfield): Don't call pushdecl_class_level or
check_template_shadow.
* errfn.c (cp_file_of): Don't declare.
(cp_line_of): Likewise.
* error.c (dump_decl): Handle an OVERLOAD.
(cp_file_of): Likewise.
(cp_line_of): Likewise.
* init.c (build_member_call): Handle a COMPONENT_REF.
* lex.c (do_identifier): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* method.c (hack_identifier): Build COMPONENT_REFs for references
to member templates as well as member functions. Remove dead
code.
* parse.y (left_curly): Remove.
(nonnested_type): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* parse.c: Regenerated.
(nested_name_specifier_1): Likewise.
* pt.c (check_explicit_specialization): Adjust, for robustness.
(check_template_shadow): Handle OVERLOADs.
(build_template_decl): Set DECL_CONSTRUCTOR_P on the
TEMPLATE_DECL, if appropriate.
* search.c (envelope_add_decl): Remove.
(dfs_pushdecls): Likewise.
(dfs_compress_decls): Likewise.
(dfs_push_decls): New function.
(dfs_push_type_decls): Likewise.
(setup_class_bindings): Likewise.
(template_self_reference_p): Likewise.
(lookup_field_r): Use it.
(looup_member): Remove old comment. Deal with ambiguity.
(push_class_decls): Use dfs_push_decls and dfs_push_type_decls,
and remove envelope processing.
* semantics.c (begin_class_definition): Let pushclass push
declarations for base classes.
(finish_member_declaration): Push declarations into class scope.
* typeck.c (build_component_ref): Just put an OVERLOAD into the
COMPONENT_REF, not a TREE_LIST of an OVERLOAD.
(build_x_function_call): Deal with OVERLOAD. Handle template-ids.
* Makefile.in (class.o): Depend on splay-tree.h.
From-SVN: r26133
1999-04-02 17:36:57 +02:00
|
|
|
|
|
|
|
|
|
/* Add the new binding. */
|
|
|
|
|
if (!DECL_CONSTRUCTOR_P (method)
|
|
|
|
|
&& !DECL_DESTRUCTOR_P (method))
|
|
|
|
|
push_class_level_binding (DECL_NAME (method),
|
|
|
|
|
TREE_VEC_ELT (method_vec, slot));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Subroutines of finish_struct. */
|
|
|
|
|
|
|
|
|
|
/* Look through the list of fields for this struct, deleting
|
|
|
|
|
duplicates as we go. This must be recursive to handle
|
|
|
|
|
anonymous unions.
|
|
|
|
|
|
|
|
|
|
FIELD is the field which may not appear anywhere in FIELDS.
|
|
|
|
|
FIELD_PTR, if non-null, is the starting point at which
|
|
|
|
|
chained deletions may take place.
|
|
|
|
|
The value returned is the first acceptable entry found
|
|
|
|
|
in FIELDS.
|
|
|
|
|
|
|
|
|
|
Note that anonymous fields which are not of UNION_TYPE are
|
|
|
|
|
not duplicates, they are just anonymous fields. This happens
|
|
|
|
|
when we have unnamed bitfields, for example. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
static tree
|
1994-08-18 22:50:43 +02:00
|
|
|
|
delete_duplicate_fields_1 (field, fields)
|
|
|
|
|
tree field, fields;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
|
|
|
|
tree x;
|
1994-08-18 22:50:43 +02:00
|
|
|
|
tree prev = 0;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (DECL_NAME (field) == 0)
|
|
|
|
|
{
|
1999-05-19 12:44:22 +02:00
|
|
|
|
if (! ANON_AGGR_TYPE_P (TREE_TYPE (field)))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
return fields;
|
|
|
|
|
|
|
|
|
|
for (x = TYPE_FIELDS (TREE_TYPE (field)); x; x = TREE_CHAIN (x))
|
1994-08-18 22:50:43 +02:00
|
|
|
|
fields = delete_duplicate_fields_1 (x, fields);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
return fields;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (x = fields; x; prev = x, x = TREE_CHAIN (x))
|
|
|
|
|
{
|
|
|
|
|
if (DECL_NAME (x) == 0)
|
|
|
|
|
{
|
1999-05-19 12:44:22 +02:00
|
|
|
|
if (! ANON_AGGR_TYPE_P (TREE_TYPE (x)))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
continue;
|
|
|
|
|
TYPE_FIELDS (TREE_TYPE (x))
|
1994-08-18 22:50:43 +02:00
|
|
|
|
= delete_duplicate_fields_1 (field, TYPE_FIELDS (TREE_TYPE (x)));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (TYPE_FIELDS (TREE_TYPE (x)) == 0)
|
|
|
|
|
{
|
|
|
|
|
if (prev == 0)
|
|
|
|
|
fields = TREE_CHAIN (fields);
|
|
|
|
|
else
|
|
|
|
|
TREE_CHAIN (prev) = TREE_CHAIN (x);
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-12-16 04:10:12 +01:00
|
|
|
|
else if (TREE_CODE (field) == USING_DECL)
|
|
|
|
|
/* A using declaration may is allowed to appear more than
|
|
|
|
|
once. We'll prune these from the field list later, and
|
|
|
|
|
handle_using_decl will complain about invalid multiple
|
|
|
|
|
uses. */
|
|
|
|
|
;
|
|
|
|
|
else if (DECL_NAME (field) == DECL_NAME (x))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1999-12-16 04:10:12 +01:00
|
|
|
|
if (TREE_CODE (field) == CONST_DECL
|
|
|
|
|
&& TREE_CODE (x) == CONST_DECL)
|
|
|
|
|
cp_error_at ("duplicate enum value `%D'", x);
|
|
|
|
|
else if (TREE_CODE (field) == CONST_DECL
|
|
|
|
|
|| TREE_CODE (x) == CONST_DECL)
|
|
|
|
|
cp_error_at ("duplicate field `%D' (as enum and non-enum)",
|
|
|
|
|
x);
|
|
|
|
|
else if (DECL_DECLARES_TYPE_P (field)
|
|
|
|
|
&& DECL_DECLARES_TYPE_P (x))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1999-12-16 04:10:12 +01:00
|
|
|
|
if (same_type_p (TREE_TYPE (field), TREE_TYPE (x)))
|
|
|
|
|
continue;
|
|
|
|
|
cp_error_at ("duplicate nested type `%D'", x);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
1999-12-16 04:10:12 +01:00
|
|
|
|
else if (DECL_DECLARES_TYPE_P (field)
|
|
|
|
|
|| DECL_DECLARES_TYPE_P (x))
|
|
|
|
|
{
|
|
|
|
|
/* Hide tag decls. */
|
|
|
|
|
if ((TREE_CODE (field) == TYPE_DECL
|
|
|
|
|
&& DECL_ARTIFICIAL (field))
|
|
|
|
|
|| (TREE_CODE (x) == TYPE_DECL
|
|
|
|
|
&& DECL_ARTIFICIAL (x)))
|
|
|
|
|
continue;
|
|
|
|
|
cp_error_at ("duplicate field `%D' (as type and non-type)",
|
|
|
|
|
x);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
cp_error_at ("duplicate member `%D'", x);
|
|
|
|
|
if (prev == 0)
|
|
|
|
|
fields = TREE_CHAIN (fields);
|
|
|
|
|
else
|
|
|
|
|
TREE_CHAIN (prev) = TREE_CHAIN (x);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return fields;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
delete_duplicate_fields (fields)
|
|
|
|
|
tree fields;
|
|
|
|
|
{
|
|
|
|
|
tree x;
|
|
|
|
|
for (x = fields; x && TREE_CHAIN (x); x = TREE_CHAIN (x))
|
1994-08-18 22:50:43 +02:00
|
|
|
|
TREE_CHAIN (x) = delete_duplicate_fields_1 (x, TREE_CHAIN (x));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
1998-06-14 01:48:07 +02:00
|
|
|
|
/* Change the access of FDECL to ACCESS in T. The access to FDECL is
|
|
|
|
|
along the path given by BINFO. Return 1 if change was legit,
|
|
|
|
|
otherwise return 0. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
static int
|
1998-06-14 01:48:07 +02:00
|
|
|
|
alter_access (t, binfo, fdecl, access)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
tree t;
|
1998-06-14 01:48:07 +02:00
|
|
|
|
tree binfo;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
tree fdecl;
|
1996-01-17 19:57:55 +01:00
|
|
|
|
tree access;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
|
|
|
|
tree elem = purpose_member (t, DECL_ACCESS (fdecl));
|
1998-03-25 17:14:49 +01:00
|
|
|
|
if (elem)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1998-03-25 17:14:49 +01:00
|
|
|
|
if (TREE_VALUE (elem) != access)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1998-03-25 17:14:49 +01:00
|
|
|
|
if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_error_at ("conflicting access specifications for method `%D', ignored", TREE_TYPE (fdecl));
|
1998-03-25 17:14:49 +01:00
|
|
|
|
else
|
1998-09-07 16:25:35 +02:00
|
|
|
|
error ("conflicting access specifications for field `%s', ignored",
|
1998-03-25 17:14:49 +01:00
|
|
|
|
IDENTIFIER_POINTER (DECL_NAME (fdecl)));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
1998-03-29 00:49:35 +01:00
|
|
|
|
{
|
|
|
|
|
/* They're changing the access to the same thing they changed
|
|
|
|
|
it to before. That's OK. */
|
|
|
|
|
;
|
|
|
|
|
}
|
1994-11-29 01:59:16 +01:00
|
|
|
|
}
|
1998-03-25 17:14:49 +01:00
|
|
|
|
else
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1998-06-14 01:48:07 +02:00
|
|
|
|
enforce_access (binfo, fdecl);
|
1996-01-17 19:57:55 +01:00
|
|
|
|
DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
1999-12-16 04:10:12 +01:00
|
|
|
|
/* Process the USING_DECL, which is a member of T. */
|
1998-06-14 01:48:07 +02:00
|
|
|
|
|
1999-03-03 12:24:45 +01:00
|
|
|
|
static void
|
1999-12-16 04:10:12 +01:00
|
|
|
|
handle_using_decl (using_decl, t)
|
1998-06-14 01:48:07 +02:00
|
|
|
|
tree using_decl;
|
|
|
|
|
tree t;
|
|
|
|
|
{
|
|
|
|
|
tree ctype = DECL_INITIAL (using_decl);
|
|
|
|
|
tree name = DECL_NAME (using_decl);
|
|
|
|
|
tree access
|
|
|
|
|
= TREE_PRIVATE (using_decl) ? access_private_node
|
|
|
|
|
: TREE_PROTECTED (using_decl) ? access_protected_node
|
|
|
|
|
: access_public_node;
|
|
|
|
|
tree fdecl, binfo;
|
|
|
|
|
tree flist = NULL_TREE;
|
1999-12-16 04:10:12 +01:00
|
|
|
|
tree fields = TYPE_FIELDS (t);
|
|
|
|
|
tree method_vec = CLASSTYPE_METHOD_VEC (t);
|
1998-06-14 01:48:07 +02:00
|
|
|
|
tree tmp;
|
|
|
|
|
int i;
|
|
|
|
|
int n_methods;
|
|
|
|
|
|
|
|
|
|
binfo = binfo_or_else (ctype, t);
|
|
|
|
|
if (! binfo)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (name == constructor_name (ctype)
|
|
|
|
|
|| name == constructor_name_full (ctype))
|
1998-12-03 17:58:03 +01:00
|
|
|
|
{
|
|
|
|
|
cp_error_at ("using-declaration for constructor", using_decl);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
1998-06-14 01:48:07 +02:00
|
|
|
|
fdecl = lookup_member (binfo, name, 0, 0);
|
|
|
|
|
|
|
|
|
|
if (!fdecl)
|
|
|
|
|
{
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_error_at ("no members matching `%D' in `%#T'", using_decl, ctype);
|
1998-06-14 01:48:07 +02:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Functions are represented as TREE_LIST, with the purpose
|
|
|
|
|
being the type and the value the functions. Other members
|
|
|
|
|
come as themselves. */
|
|
|
|
|
if (TREE_CODE (fdecl) == TREE_LIST)
|
|
|
|
|
/* Ignore base type this came from. */
|
|
|
|
|
fdecl = TREE_VALUE (fdecl);
|
|
|
|
|
|
|
|
|
|
if (TREE_CODE (fdecl) == OVERLOAD)
|
|
|
|
|
{
|
|
|
|
|
/* We later iterate over all functions. */
|
|
|
|
|
flist = fdecl;
|
|
|
|
|
fdecl = OVL_FUNCTION (flist);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
name = DECL_NAME (fdecl);
|
|
|
|
|
n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
|
1998-10-06 16:20:30 +02:00
|
|
|
|
for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); i++)
|
1998-06-14 01:48:07 +02:00
|
|
|
|
if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)))
|
|
|
|
|
== name)
|
|
|
|
|
{
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
|
|
|
|
|
cp_error_at (" because of local method `%#D' with same name",
|
1998-06-14 01:48:07 +02:00
|
|
|
|
OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
|
|
|
|
|
return;
|
|
|
|
|
}
|
1998-07-16 19:48:39 +02:00
|
|
|
|
|
|
|
|
|
if (! DECL_LANG_SPECIFIC (fdecl))
|
|
|
|
|
/* We don't currently handle DECL_ACCESS for TYPE_DECLs; just return. */
|
|
|
|
|
return;
|
1998-06-14 01:48:07 +02:00
|
|
|
|
|
|
|
|
|
for (tmp = fields; tmp; tmp = TREE_CHAIN (tmp))
|
|
|
|
|
if (DECL_NAME (tmp) == name)
|
|
|
|
|
{
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
|
|
|
|
|
cp_error_at (" because of local field `%#D' with same name", tmp);
|
1998-06-14 01:48:07 +02:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Make type T see field decl FDECL with access ACCESS.*/
|
|
|
|
|
if (flist)
|
|
|
|
|
{
|
|
|
|
|
while (flist)
|
|
|
|
|
{
|
|
|
|
|
if (alter_access (t, binfo, OVL_FUNCTION (flist),
|
|
|
|
|
access) == 0)
|
|
|
|
|
return;
|
|
|
|
|
flist = OVL_CHAIN (flist);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
alter_access (t, binfo, fdecl, access);
|
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
/* Run through the base clases of T, updating
|
|
|
|
|
CANT_HAVE_DEFAULT_CTOR_P, CANT_HAVE_CONST_CTOR_P, and
|
|
|
|
|
NO_CONST_ASN_REF_P. Also set flag bits in T based on properties of
|
|
|
|
|
the bases. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
static void
|
|
|
|
|
check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
|
|
|
|
|
no_const_asn_ref_p)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
tree t;
|
1999-12-16 23:18:22 +01:00
|
|
|
|
int *cant_have_default_ctor_p;
|
|
|
|
|
int *cant_have_const_ctor_p;
|
|
|
|
|
int *no_const_asn_ref_p;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1999-12-16 23:18:22 +01:00
|
|
|
|
int n_baseclasses;
|
|
|
|
|
int i;
|
1999-12-29 09:28:50 +01:00
|
|
|
|
int seen_nearly_empty_base_p;
|
1999-12-16 23:18:22 +01:00
|
|
|
|
tree binfos;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
binfos = TYPE_BINFO_BASETYPES (t);
|
|
|
|
|
n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
|
1999-12-29 09:28:50 +01:00
|
|
|
|
seen_nearly_empty_base_p = 0;
|
1999-12-16 23:18:22 +01:00
|
|
|
|
|
|
|
|
|
/* An aggregate cannot have baseclasses. */
|
|
|
|
|
CLASSTYPE_NON_AGGREGATE (t) |= (n_baseclasses != 0);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < n_baseclasses; ++i)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1999-12-16 23:18:22 +01:00
|
|
|
|
tree base_binfo;
|
|
|
|
|
tree basetype;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
/* Figure out what base we're looking at. */
|
|
|
|
|
base_binfo = TREE_VEC_ELT (binfos, i);
|
|
|
|
|
basetype = TREE_TYPE (base_binfo);
|
1998-04-03 05:41:20 +02:00
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
/* If the type of basetype is incomplete, then we already
|
|
|
|
|
complained about that fact (and we should have fixed it up as
|
|
|
|
|
well). */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (TYPE_SIZE (basetype) == 0)
|
|
|
|
|
{
|
|
|
|
|
int j;
|
|
|
|
|
/* The base type is of incomplete type. It is
|
|
|
|
|
probably best to pretend that it does not
|
|
|
|
|
exist. */
|
|
|
|
|
if (i == n_baseclasses-1)
|
|
|
|
|
TREE_VEC_ELT (binfos, i) = NULL_TREE;
|
|
|
|
|
TREE_VEC_LENGTH (binfos) -= 1;
|
|
|
|
|
n_baseclasses -= 1;
|
|
|
|
|
for (j = i; j+1 < n_baseclasses; j++)
|
|
|
|
|
TREE_VEC_ELT (binfos, j) = TREE_VEC_ELT (binfos, j+1);
|
1999-12-16 23:18:22 +01:00
|
|
|
|
continue;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
1999-12-21 01:19:01 +01:00
|
|
|
|
/* Effective C++ rule 14. We only need to check TYPE_POLYMORPHIC_P
|
1999-12-16 23:18:22 +01:00
|
|
|
|
here because the case of virtual functions but non-virtual
|
|
|
|
|
dtor is handled in finish_struct_1. */
|
1999-12-21 01:19:01 +01:00
|
|
|
|
if (warn_ecpp && ! TYPE_POLYMORPHIC_P (basetype)
|
1999-12-16 23:18:22 +01:00
|
|
|
|
&& TYPE_HAS_DESTRUCTOR (basetype))
|
|
|
|
|
cp_warning ("base class `%#T' has a non-virtual destructor",
|
|
|
|
|
basetype);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
/* If the base class doesn't have copy constructors or
|
|
|
|
|
assignment operators that take const references, then the
|
|
|
|
|
derived class cannot have such a member automatically
|
|
|
|
|
generated. */
|
|
|
|
|
if (! TYPE_HAS_CONST_INIT_REF (basetype))
|
|
|
|
|
*cant_have_const_ctor_p = 1;
|
|
|
|
|
if (TYPE_HAS_ASSIGN_REF (basetype)
|
|
|
|
|
&& !TYPE_HAS_CONST_ASSIGN_REF (basetype))
|
|
|
|
|
*no_const_asn_ref_p = 1;
|
|
|
|
|
/* Similarly, if the base class doesn't have a default
|
|
|
|
|
constructor, then the derived class won't have an
|
|
|
|
|
automatically generated default constructor. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (TYPE_HAS_CONSTRUCTOR (basetype)
|
|
|
|
|
&& ! TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype))
|
|
|
|
|
{
|
1999-12-16 23:18:22 +01:00
|
|
|
|
*cant_have_default_ctor_p = 1;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (! TYPE_HAS_CONSTRUCTOR (t))
|
|
|
|
|
{
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_pedwarn ("base `%T' with only non-default constructor",
|
1994-02-24 02:02:37 +01:00
|
|
|
|
basetype);
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_pedwarn ("in class without a constructor");
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-12-29 09:28:50 +01:00
|
|
|
|
/* If the base class is not empty or nearly empty, then this
|
|
|
|
|
class cannot be nearly empty. */
|
|
|
|
|
if (!CLASSTYPE_NEARLY_EMPTY_P (basetype) && !is_empty_class (basetype))
|
|
|
|
|
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
|
|
|
|
|
/* And if there is more than one nearly empty base, then the
|
|
|
|
|
derived class is not nearly empty either. */
|
|
|
|
|
else if (CLASSTYPE_NEARLY_EMPTY_P (basetype)
|
|
|
|
|
&& seen_nearly_empty_base_p)
|
|
|
|
|
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
|
|
|
|
|
/* If this is the first nearly empty base class, then remember
|
|
|
|
|
that we saw it. */
|
|
|
|
|
else if (CLASSTYPE_NEARLY_EMPTY_P (basetype))
|
|
|
|
|
seen_nearly_empty_base_p = 1;
|
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
/* A lot of properties from the bases also apply to the derived
|
|
|
|
|
class. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype);
|
|
|
|
|
TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (basetype);
|
1999-12-16 23:18:22 +01:00
|
|
|
|
TYPE_HAS_COMPLEX_ASSIGN_REF (t)
|
|
|
|
|
|= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype);
|
1995-04-24 19:27:46 +02:00
|
|
|
|
TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
TYPE_OVERLOADS_CALL_EXPR (t) |= TYPE_OVERLOADS_CALL_EXPR (basetype);
|
|
|
|
|
TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype);
|
|
|
|
|
TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype);
|
1999-12-21 01:19:01 +01:00
|
|
|
|
TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
/* Derived classes can implicitly become COMified if their bases
|
|
|
|
|
are COM. */
|
1999-04-13 02:39:32 +02:00
|
|
|
|
if (CLASSTYPE_COM_INTERFACE (basetype))
|
1999-12-16 23:18:22 +01:00
|
|
|
|
CLASSTYPE_COM_INTERFACE (t) = 1;
|
|
|
|
|
else if (i == 0 && CLASSTYPE_COM_INTERFACE (t))
|
1999-04-13 02:39:32 +02:00
|
|
|
|
{
|
1999-12-14 08:00:22 +01:00
|
|
|
|
cp_error
|
|
|
|
|
("COM interface type `%T' with non-COM leftmost base class `%T'",
|
|
|
|
|
t, basetype);
|
1999-04-13 02:39:32 +02:00
|
|
|
|
CLASSTYPE_COM_INTERFACE (t) = 0;
|
|
|
|
|
}
|
1999-12-16 23:18:22 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-01 04:04:27 +01:00
|
|
|
|
/* Make the Ith baseclass of T its primary base. */
|
1999-12-16 23:18:22 +01:00
|
|
|
|
|
2000-01-01 04:04:27 +01:00
|
|
|
|
static void
|
|
|
|
|
set_primary_base (t, i, has_virtual_p)
|
|
|
|
|
tree t;
|
|
|
|
|
int i;
|
|
|
|
|
int *has_virtual_p;
|
|
|
|
|
{
|
|
|
|
|
tree basetype;
|
|
|
|
|
|
|
|
|
|
CLASSTYPE_VFIELD_PARENT (t) = i;
|
|
|
|
|
basetype = BINFO_TYPE (CLASSTYPE_PRIMARY_BINFO (t));
|
|
|
|
|
TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype);
|
|
|
|
|
TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype);
|
|
|
|
|
TYPE_VFIELD (t) = TYPE_VFIELD (basetype);
|
|
|
|
|
CLASSTYPE_RTTI (t) = CLASSTYPE_RTTI (basetype);
|
|
|
|
|
*has_virtual_p = CLASSTYPE_VSIZE (basetype);
|
|
|
|
|
}
|
1999-12-16 23:18:22 +01:00
|
|
|
|
|
2000-01-01 04:04:27 +01:00
|
|
|
|
/* Determine the primary class for T. */
|
1999-12-16 23:18:22 +01:00
|
|
|
|
|
2000-01-01 04:04:27 +01:00
|
|
|
|
static void
|
2000-01-03 05:05:43 +01:00
|
|
|
|
determine_primary_base (t, has_virtual_p)
|
1999-12-16 23:18:22 +01:00
|
|
|
|
tree t;
|
2000-01-03 05:05:43 +01:00
|
|
|
|
int *has_virtual_p;
|
1999-12-16 23:18:22 +01:00
|
|
|
|
{
|
|
|
|
|
int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
|
2000-01-03 05:05:43 +01:00
|
|
|
|
|
2000-01-03 07:56:21 +01:00
|
|
|
|
/* If there are no baseclasses, there is certainly no primary base. */
|
|
|
|
|
if (n_baseclasses == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
2000-01-03 05:05:43 +01:00
|
|
|
|
*has_virtual_p = 0;
|
1999-12-16 23:18:22 +01:00
|
|
|
|
|
|
|
|
|
for (i = 0; i < n_baseclasses; i++)
|
|
|
|
|
{
|
2000-01-01 04:04:27 +01:00
|
|
|
|
tree base_binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), i);
|
1999-12-16 23:18:22 +01:00
|
|
|
|
tree basetype = BINFO_TYPE (base_binfo);
|
1999-04-13 02:39:32 +02:00
|
|
|
|
|
2000-01-17 05:08:01 +01:00
|
|
|
|
if (TYPE_CONTAINS_VPTR_P (basetype))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
2000-01-01 04:04:27 +01:00
|
|
|
|
/* Even a virtual baseclass can contain our RTTI
|
|
|
|
|
information. But, we prefer a non-virtual polymorphic
|
|
|
|
|
baseclass. */
|
|
|
|
|
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
|
|
|
|
|
CLASSTYPE_RTTI (t) = CLASSTYPE_RTTI (basetype);
|
1996-04-13 01:55:07 +02:00
|
|
|
|
|
2000-01-03 07:56:21 +01:00
|
|
|
|
/* A virtual baseclass can't be the primary base under the
|
|
|
|
|
old ABI. And under the new ABI we still prefer a
|
|
|
|
|
non-virtual base. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (TREE_VIA_VIRTUAL (base_binfo))
|
|
|
|
|
continue;
|
|
|
|
|
|
2000-01-01 04:04:27 +01:00
|
|
|
|
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
2000-01-03 05:05:43 +01:00
|
|
|
|
set_primary_base (t, i, has_virtual_p);
|
2000-01-01 04:04:27 +01:00
|
|
|
|
CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2000-01-01 04:04:27 +01:00
|
|
|
|
tree vfields;
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
/* Only add unique vfields, and flatten them out as we go. */
|
2000-01-01 04:04:27 +01:00
|
|
|
|
for (vfields = CLASSTYPE_VFIELDS (basetype);
|
|
|
|
|
vfields;
|
|
|
|
|
vfields = TREE_CHAIN (vfields))
|
|
|
|
|
if (VF_BINFO_VALUE (vfields) == NULL_TREE
|
|
|
|
|
|| ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields)))
|
|
|
|
|
CLASSTYPE_VFIELDS (t)
|
|
|
|
|
= tree_cons (base_binfo,
|
|
|
|
|
VF_BASETYPE_VALUE (vfields),
|
|
|
|
|
CLASSTYPE_VFIELDS (t));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
2000-01-03 05:05:43 +01:00
|
|
|
|
if (*has_virtual_p == 0)
|
|
|
|
|
set_primary_base (t, i, has_virtual_p);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-01 04:04:27 +01:00
|
|
|
|
if (!TYPE_VFIELD (t))
|
|
|
|
|
CLASSTYPE_VFIELD_PARENT (t) = -1;
|
2000-01-03 07:56:21 +01:00
|
|
|
|
|
2000-01-12 21:56:15 +01:00
|
|
|
|
/* The new ABI allows for the use of a "nearly-empty" virtual base
|
|
|
|
|
class as the primary base class if no non-virtual polymorphic
|
|
|
|
|
base can be found. */
|
|
|
|
|
if (flag_new_abi && !CLASSTYPE_HAS_PRIMARY_BASE_P (t))
|
|
|
|
|
for (i = 0; i < n_baseclasses; ++i)
|
|
|
|
|
{
|
|
|
|
|
tree base_binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), i);
|
|
|
|
|
tree basetype = BINFO_TYPE (base_binfo);
|
|
|
|
|
|
|
|
|
|
if (TREE_VIA_VIRTUAL (base_binfo)
|
|
|
|
|
&& CLASSTYPE_NEARLY_EMPTY_P (basetype))
|
|
|
|
|
{
|
|
|
|
|
set_primary_base (t, i, has_virtual_p);
|
|
|
|
|
CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Mark the primary base classes at this point. */
|
2000-01-03 07:56:21 +01:00
|
|
|
|
mark_primary_bases (t);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
2000-01-03 05:05:43 +01:00
|
|
|
|
/* Set memoizing fields and bits of T (and its variants) for later
|
|
|
|
|
use. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
static void
|
2000-01-03 05:05:43 +01:00
|
|
|
|
finish_struct_bits (t)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
tree t;
|
|
|
|
|
{
|
|
|
|
|
int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
|
|
|
|
|
|
|
|
|
|
/* Fix up variants (if any). */
|
|
|
|
|
tree variants = TYPE_NEXT_VARIANT (t);
|
|
|
|
|
while (variants)
|
|
|
|
|
{
|
|
|
|
|
/* These fields are in the _TYPE part of the node, not in
|
|
|
|
|
the TYPE_LANG_SPECIFIC component, so they are not shared. */
|
|
|
|
|
TYPE_HAS_CONSTRUCTOR (variants) = TYPE_HAS_CONSTRUCTOR (t);
|
|
|
|
|
TYPE_HAS_DESTRUCTOR (variants) = TYPE_HAS_DESTRUCTOR (t);
|
|
|
|
|
TYPE_NEEDS_CONSTRUCTING (variants) = TYPE_NEEDS_CONSTRUCTING (t);
|
|
|
|
|
TYPE_NEEDS_DESTRUCTOR (variants) = TYPE_NEEDS_DESTRUCTOR (t);
|
|
|
|
|
|
1999-12-21 01:19:01 +01:00
|
|
|
|
TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (variants)
|
|
|
|
|
= TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (t);
|
|
|
|
|
TYPE_POLYMORPHIC_P (variants) = TYPE_POLYMORPHIC_P (t);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
TYPE_USES_VIRTUAL_BASECLASSES (variants) = TYPE_USES_VIRTUAL_BASECLASSES (t);
|
|
|
|
|
/* Copy whatever these are holding today. */
|
|
|
|
|
TYPE_MIN_VALUE (variants) = TYPE_MIN_VALUE (t);
|
|
|
|
|
TYPE_MAX_VALUE (variants) = TYPE_MAX_VALUE (t);
|
1996-02-28 23:01:56 +01:00
|
|
|
|
TYPE_FIELDS (variants) = TYPE_FIELDS (t);
|
1996-07-11 03:13:25 +02:00
|
|
|
|
TYPE_SIZE (variants) = TYPE_SIZE (t);
|
1998-08-17 19:23:38 +02:00
|
|
|
|
TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
variants = TYPE_NEXT_VARIANT (variants);
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-03 05:05:43 +01:00
|
|
|
|
if (n_baseclasses && TYPE_POLYMORPHIC_P (t))
|
1999-12-29 07:39:42 +01:00
|
|
|
|
/* For a class w/o baseclasses, `finish_struct' has set
|
|
|
|
|
CLASS_TYPE_ABSTRACT_VIRTUALS correctly (by
|
|
|
|
|
definition). Similarly for a class whose base classes do not
|
|
|
|
|
have vtables. When neither of these is true, we might have
|
|
|
|
|
removed abstract virtuals (by providing a definition), added
|
|
|
|
|
some (by declaring new ones), or redeclared ones from a base
|
|
|
|
|
class. We need to recalculate what's really an abstract virtual
|
|
|
|
|
at this point (by looking in the vtables). */
|
|
|
|
|
get_pure_virtuals (t);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
if (n_baseclasses)
|
|
|
|
|
{
|
|
|
|
|
/* Notice whether this class has type conversion functions defined. */
|
|
|
|
|
tree binfo = TYPE_BINFO (t);
|
|
|
|
|
tree binfos = BINFO_BASETYPES (binfo);
|
|
|
|
|
tree basetype;
|
|
|
|
|
|
|
|
|
|
for (i = n_baseclasses-1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
|
|
|
|
|
|
cp-tree.h: Lose CLASSTYPE_VBASE_SIZE, some unused stuff.
* cp-tree.h: Lose CLASSTYPE_VBASE_SIZE, some unused stuff.
* decl.c, decl2.c, pt.c, ptree.c, lex.c: Likewise.
* class.c (duplicate_tag_error): Likewise.
(finish_struct_1): Set CLASSTYPE_SIZE, CLASSTYPE_MODE, CLASSTYPE_ALIGN.
* tree.c (layout_vbasetypes): Update from layout_record, remove
var_size support, use CLASSTYPE_SIZE instead of CLASSTYPE_VBASE_SIZE.
(layout_basetypes): Likewise.
From-SVN: r18965
1998-04-02 19:05:40 +02:00
|
|
|
|
TYPE_HAS_CONVERSION (t) |= TYPE_HAS_CONVERSION (basetype);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1995-04-24 19:27:46 +02:00
|
|
|
|
/* If this type has a copy constructor, force its mode to be BLKmode, and
|
|
|
|
|
force its TREE_ADDRESSABLE bit to be nonzero. This will cause it to
|
|
|
|
|
be passed by invisible reference and prevent it from being returned in
|
1995-12-19 07:51:14 +01:00
|
|
|
|
a register.
|
|
|
|
|
|
|
|
|
|
Also do this if the class has BLKmode but can still be returned in
|
|
|
|
|
registers, since function_cannot_inline_p won't let us inline
|
|
|
|
|
functions returning such a type. This affects the HP-PA. */
|
|
|
|
|
if (! TYPE_HAS_TRIVIAL_INIT_REF (t)
|
|
|
|
|
|| (TYPE_MODE (t) == BLKmode && ! aggregate_value_p (t)
|
|
|
|
|
&& CLASSTYPE_NON_AGGREGATE (t)))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1995-04-24 19:27:46 +02:00
|
|
|
|
tree variants;
|
1996-12-18 03:46:25 +01:00
|
|
|
|
DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode;
|
1995-04-24 19:27:46 +02:00
|
|
|
|
for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
|
|
|
|
TYPE_MODE (variants) = BLKmode;
|
|
|
|
|
TREE_ADDRESSABLE (variants) = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-09-15 13:43:54 +02:00
|
|
|
|
/* Issue warnings about T having private constructors, but no friends,
|
|
|
|
|
and so forth.
|
1998-09-14 13:09:07 +02:00
|
|
|
|
|
1998-09-15 13:43:54 +02:00
|
|
|
|
HAS_NONPRIVATE_METHOD is nonzero if T has any non-private methods or
|
|
|
|
|
static members. HAS_NONPRIVATE_STATIC_FN is nonzero if T has any
|
|
|
|
|
non-private static member functions. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
maybe_warn_about_overly_private_class (t)
|
|
|
|
|
tree t;
|
1998-09-14 13:09:07 +02:00
|
|
|
|
{
|
1998-09-20 14:30:50 +02:00
|
|
|
|
int has_member_fn = 0;
|
|
|
|
|
int has_nonprivate_method = 0;
|
|
|
|
|
tree fn;
|
|
|
|
|
|
|
|
|
|
if (!warn_ctor_dtor_privacy
|
1998-09-15 13:43:54 +02:00
|
|
|
|
/* If the class has friends, those entities might create and
|
|
|
|
|
access instances, so we should not warn. */
|
1998-09-20 14:30:50 +02:00
|
|
|
|
|| (CLASSTYPE_FRIEND_CLASSES (t)
|
|
|
|
|
|| DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))
|
1998-09-15 13:43:54 +02:00
|
|
|
|
/* We will have warned when the template was declared; there's
|
|
|
|
|
no need to warn on every instantiation. */
|
1998-09-20 14:30:50 +02:00
|
|
|
|
|| CLASSTYPE_TEMPLATE_INSTANTIATION (t))
|
|
|
|
|
/* There's no reason to even consider warning about this
|
|
|
|
|
class. */
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* We only issue one warning, if more than one applies, because
|
|
|
|
|
otherwise, on code like:
|
|
|
|
|
|
|
|
|
|
class A {
|
|
|
|
|
// Oops - forgot `public:'
|
|
|
|
|
A();
|
|
|
|
|
A(const A&);
|
|
|
|
|
~A();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
we warn several times about essentially the same problem. */
|
|
|
|
|
|
|
|
|
|
/* Check to see if all (non-constructor, non-destructor) member
|
|
|
|
|
functions are private. (Since there are no friends or
|
|
|
|
|
non-private statics, we can't ever call any of the private member
|
|
|
|
|
functions.) */
|
|
|
|
|
for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
|
|
|
|
|
/* We're not interested in compiler-generated methods; they don't
|
|
|
|
|
provide any way to call private members. */
|
|
|
|
|
if (!DECL_ARTIFICIAL (fn))
|
|
|
|
|
{
|
|
|
|
|
if (!TREE_PRIVATE (fn))
|
1998-09-15 13:43:54 +02:00
|
|
|
|
{
|
1998-09-20 14:30:50 +02:00
|
|
|
|
if (DECL_STATIC_FUNCTION_P (fn))
|
|
|
|
|
/* A non-private static member function is just like a
|
|
|
|
|
friend; it can create and invoke private member
|
|
|
|
|
functions, and be accessed without a class
|
|
|
|
|
instance. */
|
|
|
|
|
return;
|
1998-09-15 13:43:54 +02:00
|
|
|
|
|
1998-09-20 14:30:50 +02:00
|
|
|
|
has_nonprivate_method = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
1998-10-15 13:36:46 +02:00
|
|
|
|
else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))
|
1998-09-20 14:30:50 +02:00
|
|
|
|
has_member_fn = 1;
|
|
|
|
|
}
|
1998-09-14 13:09:07 +02:00
|
|
|
|
|
1998-09-20 14:30:50 +02:00
|
|
|
|
if (!has_nonprivate_method && has_member_fn)
|
|
|
|
|
{
|
1998-10-15 13:36:46 +02:00
|
|
|
|
/* There are no non-private methods, and there's at least one
|
|
|
|
|
private member function that isn't a constructor or
|
|
|
|
|
destructor. (If all the private members are
|
|
|
|
|
constructors/destructors we want to use the code below that
|
|
|
|
|
issues error messages specifically referring to
|
|
|
|
|
constructors/destructors.) */
|
1998-09-20 14:30:50 +02:00
|
|
|
|
int i;
|
|
|
|
|
tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
|
|
|
|
|
for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++)
|
|
|
|
|
if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i))
|
|
|
|
|
|| TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i)))
|
|
|
|
|
{
|
|
|
|
|
has_nonprivate_method = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!has_nonprivate_method)
|
1998-09-15 13:43:54 +02:00
|
|
|
|
{
|
1998-09-20 14:30:50 +02:00
|
|
|
|
cp_warning ("all member functions in class `%T' are private", t);
|
|
|
|
|
return;
|
1998-09-15 13:43:54 +02:00
|
|
|
|
}
|
1998-09-20 14:30:50 +02:00
|
|
|
|
}
|
1998-09-14 13:09:07 +02:00
|
|
|
|
|
1998-09-20 14:30:50 +02:00
|
|
|
|
/* Even if some of the member functions are non-private, the class
|
|
|
|
|
won't be useful for much if all the constructors or destructors
|
|
|
|
|
are private: such an object can never be created or destroyed. */
|
|
|
|
|
if (TYPE_HAS_DESTRUCTOR (t))
|
|
|
|
|
{
|
|
|
|
|
tree dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1);
|
1998-09-15 13:43:54 +02:00
|
|
|
|
|
1998-09-20 14:30:50 +02:00
|
|
|
|
if (TREE_PRIVATE (dtor))
|
|
|
|
|
{
|
|
|
|
|
cp_warning ("`%#T' only defines a private destructor and has no friends",
|
|
|
|
|
t);
|
|
|
|
|
return;
|
1998-09-15 13:43:54 +02:00
|
|
|
|
}
|
1998-09-20 14:30:50 +02:00
|
|
|
|
}
|
1998-09-15 13:43:54 +02:00
|
|
|
|
|
1998-09-20 14:30:50 +02:00
|
|
|
|
if (TYPE_HAS_CONSTRUCTOR (t))
|
|
|
|
|
{
|
|
|
|
|
int nonprivate_ctor = 0;
|
1998-09-15 13:43:54 +02:00
|
|
|
|
|
1998-09-20 14:30:50 +02:00
|
|
|
|
/* If a non-template class does not define a copy
|
|
|
|
|
constructor, one is defined for it, enabling it to avoid
|
|
|
|
|
this warning. For a template class, this does not
|
|
|
|
|
happen, and so we would normally get a warning on:
|
1998-09-15 13:43:54 +02:00
|
|
|
|
|
1998-09-20 14:30:50 +02:00
|
|
|
|
template <class T> class C { private: C(); };
|
1998-09-15 13:43:54 +02:00
|
|
|
|
|
1998-09-20 14:30:50 +02:00
|
|
|
|
To avoid this asymmetry, we check TYPE_HAS_INIT_REF. All
|
|
|
|
|
complete non-template or fully instantiated classes have this
|
|
|
|
|
flag set. */
|
|
|
|
|
if (!TYPE_HAS_INIT_REF (t))
|
|
|
|
|
nonprivate_ctor = 1;
|
|
|
|
|
else
|
|
|
|
|
for (fn = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
|
|
|
|
|
fn;
|
|
|
|
|
fn = OVL_NEXT (fn))
|
|
|
|
|
{
|
|
|
|
|
tree ctor = OVL_CURRENT (fn);
|
|
|
|
|
/* Ideally, we wouldn't count copy constructors (or, in
|
|
|
|
|
fact, any constructor that takes an argument of the
|
|
|
|
|
class type as a parameter) because such things cannot
|
|
|
|
|
be used to construct an instance of the class unless
|
|
|
|
|
you already have one. But, for now at least, we're
|
|
|
|
|
more generous. */
|
|
|
|
|
if (! TREE_PRIVATE (ctor))
|
1998-09-15 13:43:54 +02:00
|
|
|
|
{
|
1998-09-20 14:30:50 +02:00
|
|
|
|
nonprivate_ctor = 1;
|
|
|
|
|
break;
|
1998-09-15 13:43:54 +02:00
|
|
|
|
}
|
1998-09-20 14:30:50 +02:00
|
|
|
|
}
|
1998-09-14 13:09:07 +02:00
|
|
|
|
|
1998-09-20 14:30:50 +02:00
|
|
|
|
if (nonprivate_ctor == 0)
|
|
|
|
|
{
|
|
|
|
|
cp_warning ("`%#T' only defines private constructors and has no friends",
|
|
|
|
|
t);
|
|
|
|
|
return;
|
1998-09-15 13:43:54 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
1998-09-14 13:09:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
1999-07-09 18:15:04 +02:00
|
|
|
|
/* Function to help qsort sort FIELD_DECLs by name order. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
field_decl_cmp (x, y)
|
|
|
|
|
const tree *x, *y;
|
|
|
|
|
{
|
|
|
|
|
if (DECL_NAME (*x) == DECL_NAME (*y))
|
2000-01-07 00:54:34 +01:00
|
|
|
|
/* A nontype is "greater" than a type. */
|
|
|
|
|
return DECL_DECLARES_TYPE_P (*y) - DECL_DECLARES_TYPE_P (*x);
|
1999-07-09 18:15:04 +02:00
|
|
|
|
if (DECL_NAME (*x) == NULL_TREE)
|
|
|
|
|
return -1;
|
|
|
|
|
if (DECL_NAME (*y) == NULL_TREE)
|
|
|
|
|
return 1;
|
|
|
|
|
if (DECL_NAME (*x) < DECL_NAME (*y))
|
|
|
|
|
return -1;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Comparison function to compare two TYPE_METHOD_VEC entries by name. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
method_name_cmp (m1, m2)
|
|
|
|
|
const tree *m1, *m2;
|
|
|
|
|
{
|
|
|
|
|
if (*m1 == NULL_TREE && *m2 == NULL_TREE)
|
|
|
|
|
return 0;
|
|
|
|
|
if (*m1 == NULL_TREE)
|
|
|
|
|
return -1;
|
|
|
|
|
if (*m2 == NULL_TREE)
|
|
|
|
|
return 1;
|
|
|
|
|
if (DECL_NAME (OVL_CURRENT (*m1)) < DECL_NAME (OVL_CURRENT (*m2)))
|
|
|
|
|
return -1;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
1998-09-15 13:43:54 +02:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
/* Warn about duplicate methods in fn_fields. Also compact method
|
|
|
|
|
lists so that lookup can be made faster.
|
|
|
|
|
|
|
|
|
|
Data Structure: List of method lists. The outer list is a
|
|
|
|
|
TREE_LIST, whose TREE_PURPOSE field is the field name and the
|
1995-01-24 09:19:58 +01:00
|
|
|
|
TREE_VALUE is the DECL_CHAIN of the FUNCTION_DECLs. TREE_CHAIN
|
|
|
|
|
links the entire list of methods for TYPE_METHODS. Friends are
|
|
|
|
|
chained in the same way as member functions (? TREE_CHAIN or
|
|
|
|
|
DECL_CHAIN), but they live in the TREE_TYPE field of the outer
|
|
|
|
|
list. That allows them to be quickly deleted, and requires no
|
|
|
|
|
extra storage.
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
If there are any constructors/destructors, they are moved to the
|
|
|
|
|
front of the list. This makes pushclass more efficient.
|
|
|
|
|
|
1999-07-09 18:15:04 +02:00
|
|
|
|
@@ The above comment is obsolete. It mostly describes what add_method
|
|
|
|
|
@@ and add_implicitly_declared_members do.
|
|
|
|
|
|
|
|
|
|
Sort methods that are not special (i.e., constructors, destructors, and
|
|
|
|
|
type conversion operators) so that we can find them faster in search. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1998-09-15 13:43:54 +02:00
|
|
|
|
static void
|
|
|
|
|
finish_struct_methods (t)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
tree t;
|
|
|
|
|
{
|
1998-09-15 13:43:54 +02:00
|
|
|
|
tree fn_fields;
|
1999-12-16 04:10:12 +01:00
|
|
|
|
tree method_vec;
|
1996-03-21 20:46:11 +01:00
|
|
|
|
tree ctor_name = constructor_name (t);
|
1999-12-16 04:10:12 +01:00
|
|
|
|
int slot, len;
|
|
|
|
|
|
|
|
|
|
if (!TYPE_METHODS (t))
|
|
|
|
|
{
|
|
|
|
|
/* Clear these for safety; perhaps some parsing error could set
|
|
|
|
|
these incorrectly. */
|
|
|
|
|
TYPE_HAS_CONSTRUCTOR (t) = 0;
|
|
|
|
|
TYPE_HAS_DESTRUCTOR (t) = 0;
|
|
|
|
|
CLASSTYPE_METHOD_VEC (t) = NULL_TREE;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
method_vec = CLASSTYPE_METHOD_VEC (t);
|
1999-12-16 23:18:22 +01:00
|
|
|
|
my_friendly_assert (method_vec != NULL_TREE, 19991215);
|
1999-12-16 04:10:12 +01:00
|
|
|
|
len = TREE_VEC_LENGTH (method_vec);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1996-03-21 20:46:11 +01:00
|
|
|
|
/* First fill in entry 0 with the constructors, entry 1 with destructors,
|
|
|
|
|
and the next few with type conversion operators (if any). */
|
1998-09-15 13:43:54 +02:00
|
|
|
|
for (fn_fields = TYPE_METHODS (t); fn_fields;
|
|
|
|
|
fn_fields = TREE_CHAIN (fn_fields))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
|
|
|
|
tree fn_name = DECL_NAME (fn_fields);
|
|
|
|
|
|
|
|
|
|
/* Clear out this flag.
|
|
|
|
|
|
|
|
|
|
@@ Doug may figure out how to break
|
|
|
|
|
@@ this with nested classes and friends. */
|
|
|
|
|
DECL_IN_AGGR_P (fn_fields) = 0;
|
|
|
|
|
|
|
|
|
|
/* Note here that a copy ctor is private, so we don't dare generate
|
|
|
|
|
a default copy constructor for a class that has a member
|
|
|
|
|
of this type without making sure they have access to it. */
|
1996-03-21 20:46:11 +01:00
|
|
|
|
if (fn_name == ctor_name)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
|
|
|
|
tree parmtypes = FUNCTION_ARG_CHAIN (fn_fields);
|
|
|
|
|
tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node;
|
|
|
|
|
|
|
|
|
|
if (TREE_CODE (parmtype) == REFERENCE_TYPE
|
|
|
|
|
&& TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == t)
|
|
|
|
|
{
|
|
|
|
|
if (TREE_CHAIN (parmtypes) == NULL_TREE
|
|
|
|
|
|| TREE_CHAIN (parmtypes) == void_list_node
|
|
|
|
|
|| TREE_PURPOSE (TREE_CHAIN (parmtypes)))
|
|
|
|
|
{
|
|
|
|
|
if (TREE_PROTECTED (fn_fields))
|
|
|
|
|
TYPE_HAS_NONPUBLIC_CTOR (t) = 1;
|
|
|
|
|
else if (TREE_PRIVATE (fn_fields))
|
|
|
|
|
TYPE_HAS_NONPUBLIC_CTOR (t) = 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-10-06 16:20:30 +02:00
|
|
|
|
}
|
|
|
|
|
else if (fn_name == ansi_opname[(int) MODIFY_EXPR])
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
|
|
|
|
tree parmtype = TREE_VALUE (FUNCTION_ARG_CHAIN (fn_fields));
|
|
|
|
|
|
1994-08-05 22:25:20 +02:00
|
|
|
|
if (copy_assignment_arg_p (parmtype, DECL_VIRTUAL_P (fn_fields)))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
|
|
|
|
if (TREE_PROTECTED (fn_fields))
|
|
|
|
|
TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 1;
|
|
|
|
|
else if (TREE_PRIVATE (fn_fields))
|
|
|
|
|
TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-09-15 13:43:54 +02:00
|
|
|
|
if (TYPE_HAS_DESTRUCTOR (t) && !TREE_VEC_ELT (method_vec, 1))
|
|
|
|
|
/* We thought there was a destructor, but there wasn't. Some
|
|
|
|
|
parse errors cause this anomalous situation. */
|
|
|
|
|
TYPE_HAS_DESTRUCTOR (t) = 0;
|
|
|
|
|
|
|
|
|
|
/* Issue warnings about private constructors and such. If there are
|
|
|
|
|
no methods, then some public defaults are generated. */
|
1999-07-09 18:15:04 +02:00
|
|
|
|
maybe_warn_about_overly_private_class (t);
|
|
|
|
|
|
|
|
|
|
/* Now sort the methods. */
|
|
|
|
|
while (len > 2 && TREE_VEC_ELT (method_vec, len-1) == NULL_TREE)
|
|
|
|
|
len--;
|
|
|
|
|
TREE_VEC_LENGTH (method_vec) = len;
|
|
|
|
|
|
|
|
|
|
/* The type conversion ops have to live at the front of the vec, so we
|
|
|
|
|
can't sort them. */
|
|
|
|
|
for (slot = 2; slot < len; ++slot)
|
|
|
|
|
{
|
|
|
|
|
tree fn = TREE_VEC_ELT (method_vec, slot);
|
|
|
|
|
|
|
|
|
|
if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (len - slot > 1)
|
|
|
|
|
qsort (&TREE_VEC_ELT (method_vec, slot), len-slot, sizeof (tree),
|
|
|
|
|
(int (*)(const void *, const void *))method_name_cmp);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
1996-07-11 03:13:25 +02:00
|
|
|
|
/* Emit error when a duplicate definition of a type is seen. Patch up. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
duplicate_tag_error (t)
|
|
|
|
|
tree t;
|
|
|
|
|
{
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_error ("redefinition of `%#T'", t);
|
|
|
|
|
cp_error_at ("previous definition here", t);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
/* Pretend we haven't defined this type. */
|
|
|
|
|
|
|
|
|
|
/* All of the component_decl's were TREE_CHAINed together in the parser.
|
|
|
|
|
finish_struct_methods walks these chains and assembles all methods with
|
|
|
|
|
the same base name into DECL_CHAINs. Now we don't need the parser chains
|
1996-07-11 03:13:25 +02:00
|
|
|
|
anymore, so we unravel them. */
|
|
|
|
|
|
|
|
|
|
/* This used to be in finish_struct, but it turns out that the
|
|
|
|
|
TREE_CHAIN is used by dbxout_type_methods and perhaps some other
|
|
|
|
|
things... */
|
1996-03-21 20:46:11 +01:00
|
|
|
|
if (CLASSTYPE_METHOD_VEC (t))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1996-03-21 20:46:11 +01:00
|
|
|
|
tree method_vec = CLASSTYPE_METHOD_VEC (t);
|
|
|
|
|
int i, len = TREE_VEC_LENGTH (method_vec);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
|
{
|
1996-03-21 20:46:11 +01:00
|
|
|
|
tree unchain = TREE_VEC_ELT (method_vec, i);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
while (unchain != NULL_TREE)
|
|
|
|
|
{
|
1998-05-08 04:06:26 +02:00
|
|
|
|
TREE_CHAIN (OVL_CURRENT (unchain)) = NULL_TREE;
|
|
|
|
|
unchain = OVL_NEXT (unchain);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (TYPE_LANG_SPECIFIC (t))
|
|
|
|
|
{
|
|
|
|
|
tree binfo = TYPE_BINFO (t);
|
|
|
|
|
int interface_only = CLASSTYPE_INTERFACE_ONLY (t);
|
|
|
|
|
int interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (t);
|
1999-08-03 16:45:20 +02:00
|
|
|
|
tree template_info = CLASSTYPE_TEMPLATE_INFO (t);
|
|
|
|
|
int use_template = CLASSTYPE_USE_TEMPLATE (t);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1994-10-12 17:44:14 +01:00
|
|
|
|
bzero ((char *) TYPE_LANG_SPECIFIC (t), sizeof (struct lang_type));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
BINFO_BASETYPES(binfo) = NULL_TREE;
|
|
|
|
|
|
|
|
|
|
TYPE_BINFO (t) = binfo;
|
|
|
|
|
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
|
|
|
|
|
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
|
|
|
|
|
TYPE_REDEFINED (t) = 1;
|
1999-08-03 16:45:20 +02:00
|
|
|
|
CLASSTYPE_TEMPLATE_INFO (t) = template_info;
|
|
|
|
|
CLASSTYPE_USE_TEMPLATE (t) = use_template;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
TYPE_SIZE (t) = NULL_TREE;
|
|
|
|
|
TYPE_MODE (t) = VOIDmode;
|
|
|
|
|
TYPE_FIELDS (t) = NULL_TREE;
|
|
|
|
|
TYPE_METHODS (t) = NULL_TREE;
|
|
|
|
|
TYPE_VFIELD (t) = NULL_TREE;
|
|
|
|
|
TYPE_CONTEXT (t) = NULL_TREE;
|
1999-07-09 13:05:23 +02:00
|
|
|
|
TYPE_NONCOPIED_PARTS (t) = NULL_TREE;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
2000-02-21 05:19:12 +01:00
|
|
|
|
/* Make the BINFO's vtablehave N entries, including RTTI entries,
|
|
|
|
|
vbase and vcall offsets, etc. Set its type and call the backend
|
|
|
|
|
to lay it out. */
|
2000-01-26 00:26:21 +01:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
layout_vtable_decl (binfo, n)
|
|
|
|
|
tree binfo;
|
|
|
|
|
int n;
|
|
|
|
|
{
|
|
|
|
|
tree itype;
|
|
|
|
|
tree atype;
|
|
|
|
|
|
|
|
|
|
itype = size_int (n);
|
|
|
|
|
atype = build_cplus_array_type (vtable_entry_type,
|
|
|
|
|
build_index_type (itype));
|
|
|
|
|
layout_type (atype);
|
|
|
|
|
|
|
|
|
|
/* We may have to grow the vtable. */
|
|
|
|
|
if (!same_type_p (TREE_TYPE (BINFO_VTABLE (binfo)), atype))
|
|
|
|
|
{
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
tree vtable = BINFO_VTABLE (binfo);
|
|
|
|
|
|
|
|
|
|
TREE_TYPE (vtable) = atype;
|
|
|
|
|
DECL_SIZE (vtable) = DECL_SIZE_UNIT (vtable) = 0;
|
|
|
|
|
layout_decl (vtable, 0);
|
|
|
|
|
|
2000-01-26 00:26:21 +01:00
|
|
|
|
/* At one time the vtable info was grabbed 2 words at a time. This
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
fails on Sparc unless you have 8-byte alignment. */
|
|
|
|
|
DECL_ALIGN (vtable) = MAX (TYPE_ALIGN (double_type_node),
|
|
|
|
|
DECL_ALIGN (vtable));
|
2000-01-26 00:26:21 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns the number of virtual function table entries (excluding
|
|
|
|
|
RTTI information, vbase and vcall offests, etc.) in the vtable for
|
|
|
|
|
BINFO. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
num_vfun_entries (binfo)
|
|
|
|
|
tree binfo;
|
|
|
|
|
{
|
|
|
|
|
return list_length (skip_rtti_stuff (binfo,
|
|
|
|
|
BINFO_TYPE (binfo),
|
|
|
|
|
NULL));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Called from num_extra_vtbl_entries via dfs_walk. */
|
|
|
|
|
|
|
|
|
|
static tree
|
|
|
|
|
dfs_count_virtuals (binfo, data)
|
|
|
|
|
tree binfo;
|
|
|
|
|
void *data;
|
|
|
|
|
{
|
|
|
|
|
/* Non-primary bases are not interesting; all of the virtual
|
|
|
|
|
function table entries have been overridden. */
|
|
|
|
|
if (!BINFO_PRIMARY_MARKED_P (binfo))
|
|
|
|
|
((vcall_offset_data *) data)->offsets += num_vfun_entries (binfo);
|
|
|
|
|
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-16 17:59:44 +01:00
|
|
|
|
/* Returns the number of extra entries (at negative indices) required
|
|
|
|
|
for BINFO's vtable. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
num_extra_vtbl_entries (binfo)
|
|
|
|
|
tree binfo;
|
|
|
|
|
{
|
|
|
|
|
tree type;
|
|
|
|
|
int entries;
|
|
|
|
|
|
|
|
|
|
type = BINFO_TYPE (binfo);
|
|
|
|
|
entries = 0;
|
|
|
|
|
|
|
|
|
|
/* There is an entry for the offset to each virtual base. */
|
2000-01-26 00:26:21 +01:00
|
|
|
|
if (vbase_offsets_in_vtable_p ())
|
|
|
|
|
entries += list_length (CLASSTYPE_VBASECLASSES (type));
|
2000-01-16 17:59:44 +01:00
|
|
|
|
|
2000-01-26 00:26:21 +01:00
|
|
|
|
/* If this is a virtual base, there are entries for each virtual
|
|
|
|
|
function defined in this class or its bases. */
|
|
|
|
|
if (vcall_offsets_in_vtable_p () && TREE_VIA_VIRTUAL (binfo))
|
|
|
|
|
{
|
|
|
|
|
vcall_offset_data vod;
|
|
|
|
|
|
|
|
|
|
vod.vbase = binfo;
|
|
|
|
|
vod.offsets = 0;
|
|
|
|
|
dfs_walk (binfo,
|
|
|
|
|
dfs_count_virtuals,
|
|
|
|
|
dfs_vcall_offset_queue_p,
|
|
|
|
|
&vod);
|
|
|
|
|
entries += vod.offsets;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return entries ? size_int (entries) : size_zero_node;
|
2000-01-16 17:59:44 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns the offset (in bytes) from the beginning of BINFO's vtable
|
|
|
|
|
where the vptr should actually point. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
size_extra_vtbl_entries (binfo)
|
|
|
|
|
tree binfo;
|
|
|
|
|
{
|
|
|
|
|
tree offset;
|
|
|
|
|
|
|
|
|
|
offset = size_binop (EXACT_DIV_EXPR,
|
|
|
|
|
TYPE_SIZE (vtable_entry_type),
|
|
|
|
|
size_int (BITS_PER_UNIT));
|
|
|
|
|
offset = size_binop (MULT_EXPR, offset, num_extra_vtbl_entries (binfo));
|
|
|
|
|
return fold (offset);
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-17 05:08:01 +01:00
|
|
|
|
/* Construct the initializer for BINFOs virtual function table. BINFO
|
2000-02-21 05:19:12 +01:00
|
|
|
|
is part of the hierarchy dominated by T. The value returned is a
|
|
|
|
|
TREE_LIST suitable for wrapping in a CONSTRUCTOR to use as the
|
|
|
|
|
DECL_INITIAL for a vtable. */
|
1999-07-27 20:15:21 +02:00
|
|
|
|
|
|
|
|
|
static tree
|
2000-01-17 05:08:01 +01:00
|
|
|
|
build_vtbl_initializer (binfo, t)
|
1999-07-27 20:15:21 +02:00
|
|
|
|
tree binfo;
|
2000-01-17 05:08:01 +01:00
|
|
|
|
tree t;
|
1999-07-27 20:15:21 +02:00
|
|
|
|
{
|
|
|
|
|
tree v = BINFO_VIRTUALS (binfo);
|
|
|
|
|
tree inits = NULL_TREE;
|
2000-01-16 17:59:44 +01:00
|
|
|
|
tree type = BINFO_TYPE (binfo);
|
|
|
|
|
|
2000-01-26 00:26:21 +01:00
|
|
|
|
/* Add entries to the vtable that indicate how to adjust the this
|
|
|
|
|
pointer when calling a virtual function in this class. */
|
|
|
|
|
inits = build_vcall_offset_vtbl_entries (binfo, t);
|
|
|
|
|
|
2000-01-16 18:38:06 +01:00
|
|
|
|
/* Add entries to the vtable for offsets to our virtual bases. */
|
2000-01-26 00:26:21 +01:00
|
|
|
|
inits = chainon (build_vbase_offset_vtbl_entries (binfo, t),
|
|
|
|
|
inits);
|
1999-07-27 20:15:21 +02:00
|
|
|
|
|
|
|
|
|
/* Process the RTTI stuff at the head of the list. If we're not
|
|
|
|
|
using vtable thunks, then the RTTI entry is just an ordinary
|
|
|
|
|
function, and we can process it just like the other virtual
|
|
|
|
|
function entries. */
|
2000-01-16 17:59:44 +01:00
|
|
|
|
if (!CLASSTYPE_COM_INTERFACE (type) && flag_vtable_thunks)
|
1999-07-27 20:15:21 +02:00
|
|
|
|
{
|
|
|
|
|
tree offset;
|
|
|
|
|
tree init;
|
|
|
|
|
|
|
|
|
|
/* The first entry is an offset. */
|
|
|
|
|
offset = TREE_PURPOSE (v);
|
|
|
|
|
my_friendly_assert (TREE_CODE (offset) == INTEGER_CST,
|
|
|
|
|
19990727);
|
|
|
|
|
|
|
|
|
|
/* Convert the offset to look like a function pointer, so that
|
|
|
|
|
we can put it in the vtable. */
|
|
|
|
|
init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);
|
|
|
|
|
TREE_CONSTANT (init) = 1;
|
|
|
|
|
inits = tree_cons (NULL_TREE, init, inits);
|
|
|
|
|
|
|
|
|
|
v = TREE_CHAIN (v);
|
2000-01-28 14:30:13 +01:00
|
|
|
|
|
|
|
|
|
if (new_abi_rtti_p ())
|
|
|
|
|
{
|
|
|
|
|
tree decl = TREE_VALUE (v);
|
|
|
|
|
|
|
|
|
|
if (decl)
|
|
|
|
|
decl = build_unary_op (ADDR_EXPR, decl, 0);
|
|
|
|
|
else
|
|
|
|
|
decl = integer_zero_node;
|
|
|
|
|
decl = build1 (NOP_EXPR, vfunc_ptr_type_node, decl);
|
|
|
|
|
TREE_CONSTANT (decl) = 1;
|
2000-01-29 16:47:14 +01:00
|
|
|
|
decl = build_vtable_entry (integer_zero_node, integer_zero_node,
|
|
|
|
|
decl);
|
2000-01-28 14:30:13 +01:00
|
|
|
|
inits = tree_cons (NULL_TREE, decl, inits);
|
|
|
|
|
|
|
|
|
|
v = TREE_CHAIN (v);
|
|
|
|
|
}
|
|
|
|
|
/* In the old abi the second entry (the tdesc pointer) is
|
|
|
|
|
just an ordinary function, so it can be dealt with like the
|
|
|
|
|
virtual functions. */
|
1999-07-27 20:15:21 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Go through all the ordinary virtual functions, building up
|
|
|
|
|
initializers. */
|
|
|
|
|
while (v)
|
|
|
|
|
{
|
|
|
|
|
tree delta;
|
2000-01-29 04:59:09 +01:00
|
|
|
|
tree vcall_index;
|
1999-07-27 20:15:21 +02:00
|
|
|
|
tree fn;
|
2000-02-20 03:46:56 +01:00
|
|
|
|
tree pfn;
|
1999-07-27 20:15:21 +02:00
|
|
|
|
tree init;
|
|
|
|
|
|
|
|
|
|
/* Pull the offset for `this', and the function to call, out of
|
|
|
|
|
the list. */
|
2000-01-31 22:00:01 +01:00
|
|
|
|
delta = BV_DELTA (v);
|
|
|
|
|
vcall_index = BV_VCALL_INDEX (v);
|
|
|
|
|
fn = BV_FN (v);
|
1999-07-27 20:15:21 +02:00
|
|
|
|
my_friendly_assert (TREE_CODE (delta) == INTEGER_CST, 19990727);
|
|
|
|
|
my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 19990727);
|
|
|
|
|
|
|
|
|
|
/* You can't call an abstract virtual function; it's abstract.
|
|
|
|
|
So, we replace these functions with __pure_virtual. */
|
1999-12-29 07:39:42 +01:00
|
|
|
|
if (DECL_PURE_VIRTUAL_P (fn))
|
1999-07-27 20:15:21 +02:00
|
|
|
|
fn = abort_fndecl;
|
|
|
|
|
|
2000-02-20 03:46:56 +01:00
|
|
|
|
/* Take the address of the function, considering it to be of an
|
|
|
|
|
appropriate generic type. */
|
|
|
|
|
pfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn);
|
|
|
|
|
/* The address of a function can't change. */
|
|
|
|
|
TREE_CONSTANT (pfn) = 1;
|
|
|
|
|
/* Enter it in the vtable. */
|
|
|
|
|
init = build_vtable_entry (delta, vcall_index, pfn);
|
1999-07-27 20:15:21 +02:00
|
|
|
|
/* And add it to the chain of initializers. */
|
|
|
|
|
inits = tree_cons (NULL_TREE, init, inits);
|
|
|
|
|
|
|
|
|
|
/* Keep going. */
|
|
|
|
|
v = TREE_CHAIN (v);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The initializers were built up in reverse order; straighten them
|
|
|
|
|
out now. */
|
2000-02-21 05:19:12 +01:00
|
|
|
|
return nreverse (inits);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Initialize the vtable for BINFO with the INITS. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
initialize_vtable (binfo, inits)
|
|
|
|
|
tree binfo;
|
|
|
|
|
tree inits;
|
|
|
|
|
{
|
|
|
|
|
tree context;
|
|
|
|
|
tree decl;
|
|
|
|
|
|
|
|
|
|
layout_vtable_decl (binfo, list_length (inits));
|
|
|
|
|
decl = BINFO_VTABLE (binfo);
|
|
|
|
|
context = DECL_CONTEXT (decl);
|
|
|
|
|
DECL_CONTEXT (decl) = 0;
|
|
|
|
|
DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, inits);
|
|
|
|
|
cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
|
|
|
|
|
DECL_CONTEXT (decl) = context;
|
1999-07-27 20:15:21 +02:00
|
|
|
|
}
|
|
|
|
|
|
2000-01-11 03:28:01 +01:00
|
|
|
|
/* Called from finish_vtbls via dfs_walk. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
2000-01-11 03:28:01 +01:00
|
|
|
|
static tree
|
|
|
|
|
dfs_finish_vtbls (binfo, data)
|
1996-04-13 01:55:07 +02:00
|
|
|
|
tree binfo;
|
2000-01-17 05:08:01 +01:00
|
|
|
|
void *data;
|
2000-02-21 05:19:12 +01:00
|
|
|
|
{
|
|
|
|
|
if (!BINFO_PRIMARY_MARKED_P (binfo)
|
|
|
|
|
&& CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
|
|
|
|
|
&& BINFO_NEW_VTABLE_MARKED (binfo))
|
|
|
|
|
initialize_vtable (binfo,
|
|
|
|
|
build_vtbl_initializer (binfo, (tree) data));
|
|
|
|
|
|
|
|
|
|
CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
|
|
|
|
|
SET_BINFO_MARKED (binfo);
|
|
|
|
|
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Called from finish_vtbls via dfs_walk when using the new ABI.
|
|
|
|
|
Accumulates the vtable initializers for all of the vtables into
|
|
|
|
|
TREE_VALUE (DATA). */
|
|
|
|
|
|
|
|
|
|
static tree
|
|
|
|
|
dfs_accumulate_vtbl_inits (binfo, data)
|
|
|
|
|
tree binfo;
|
|
|
|
|
void *data;
|
1994-04-22 01:30:18 +02:00
|
|
|
|
{
|
2000-01-11 03:28:01 +01:00
|
|
|
|
if (!BINFO_PRIMARY_MARKED_P (binfo)
|
|
|
|
|
&& CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
|
|
|
|
|
&& BINFO_NEW_VTABLE_MARKED (binfo))
|
1994-04-22 01:30:18 +02:00
|
|
|
|
{
|
2000-02-21 05:19:12 +01:00
|
|
|
|
tree l;
|
|
|
|
|
tree t;
|
|
|
|
|
|
|
|
|
|
l = (tree) data;
|
|
|
|
|
t = TREE_PURPOSE (l);
|
|
|
|
|
|
|
|
|
|
/* If this is a secondary vtable, record its location. */
|
|
|
|
|
if (binfo != TYPE_BINFO (t))
|
|
|
|
|
{
|
|
|
|
|
tree vtbl;
|
|
|
|
|
|
|
|
|
|
vtbl = TYPE_BINFO_VTABLE (t);
|
|
|
|
|
vtbl = build1 (ADDR_EXPR,
|
|
|
|
|
build_pointer_type (TREE_TYPE (vtbl)),
|
|
|
|
|
vtbl);
|
|
|
|
|
BINFO_VTABLE (binfo)
|
|
|
|
|
= build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl,
|
|
|
|
|
size_binop (MULT_EXPR,
|
|
|
|
|
TYPE_SIZE_UNIT (TREE_TYPE (vtbl)),
|
|
|
|
|
size_int (list_length (TREE_VALUE (l)))));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Add the initializers for this vtable to the initailizers for
|
|
|
|
|
the other vtables we've already got. */
|
|
|
|
|
TREE_VALUE (l)
|
|
|
|
|
= chainon (TREE_VALUE (l),
|
|
|
|
|
build_vtbl_initializer (binfo, t));
|
1994-04-22 01:30:18 +02:00
|
|
|
|
}
|
|
|
|
|
|
2000-01-11 03:28:01 +01:00
|
|
|
|
CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
|
|
|
|
|
SET_BINFO_MARKED (binfo);
|
|
|
|
|
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Create all the necessary vtables for T and its base classes. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
finish_vtbls (t)
|
|
|
|
|
tree t;
|
|
|
|
|
{
|
2000-02-21 05:19:12 +01:00
|
|
|
|
if (merge_primary_and_secondary_vtables_p ())
|
|
|
|
|
{
|
|
|
|
|
tree list;
|
|
|
|
|
|
|
|
|
|
/* Under the new ABI, we lay out the primary and secondary
|
|
|
|
|
vtables in one contiguous vtable. The primary vtable is
|
|
|
|
|
first, followed by the secondary vtables as encountered in a
|
|
|
|
|
pre-order depth-first left-to-right traversal. */
|
|
|
|
|
list = build_tree_list (t, NULL_TREE);
|
|
|
|
|
dfs_walk_real (TYPE_BINFO (t),
|
|
|
|
|
dfs_accumulate_vtbl_inits,
|
|
|
|
|
NULL,
|
|
|
|
|
dfs_unmarked_real_bases_queue_p,
|
|
|
|
|
list);
|
|
|
|
|
if (TYPE_BINFO_VTABLE (t))
|
|
|
|
|
initialize_vtable (TYPE_BINFO (t), TREE_VALUE (list));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
dfs_walk (TYPE_BINFO (t), dfs_finish_vtbls,
|
|
|
|
|
dfs_unmarked_real_bases_queue_p, t);
|
|
|
|
|
|
2000-01-11 03:28:01 +01:00
|
|
|
|
dfs_walk (TYPE_BINFO (t), dfs_unmark,
|
|
|
|
|
dfs_marked_real_bases_queue_p, t);
|
1994-04-22 01:30:18 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* True if we should override the given BASE_FNDECL with the given
|
|
|
|
|
FNDECL. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1994-04-22 01:30:18 +02:00
|
|
|
|
static int
|
|
|
|
|
overrides (fndecl, base_fndecl)
|
|
|
|
|
tree fndecl, base_fndecl;
|
|
|
|
|
{
|
1996-07-11 03:13:25 +02:00
|
|
|
|
/* Destructors have special names. */
|
1997-05-06 22:14:14 +02:00
|
|
|
|
if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl))
|
|
|
|
|
&& DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
|
1994-04-22 01:30:18 +02:00
|
|
|
|
return 1;
|
1997-05-06 22:14:14 +02:00
|
|
|
|
if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl))
|
|
|
|
|
|| DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
|
1994-04-22 01:30:18 +02:00
|
|
|
|
return 0;
|
|
|
|
|
if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl))
|
|
|
|
|
{
|
1996-02-28 23:01:56 +01:00
|
|
|
|
tree types, base_types;
|
1994-04-22 01:30:18 +02:00
|
|
|
|
#if 0
|
|
|
|
|
retypes = TREE_TYPE (TREE_TYPE (fndecl));
|
|
|
|
|
base_retypes = TREE_TYPE (TREE_TYPE (base_fndecl));
|
|
|
|
|
#endif
|
|
|
|
|
types = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
|
|
|
|
base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl));
|
cplus-dem.c (work_stuff): Replace const_type and volatile_type with type_quals.
* cplus-dem.c (work_stuff): Replace const_type and volatile_type
with type_quals.
(TYPE_UNQUALIFIED): New macro.
(TYPE_QUAL_CONST): Likewise.
(TYPE_QUAL_VOLATILE): Likewise.
(TYPE_QUAL_RESTRICT): Likewise.
(code_for_qualifier): New function.
(qualifier_string): Likewise.
(demangle_qualifier): Likewise.
(internal_cplus_demangle): Use them.
(demangle_signature): Likewise.
(demangle_template_value_parm): Likewise.
(do_type): Likewise.
(demangle_fund_type)): Likewise.
* Makefile.in (hash.h): Run gperf when necessary.
* cp-tree.h (CP_TYPE_READONLY): Remove.
(CP_TYPE_VOLATILE): Likewise.
(CP_TYPE_QUALS): New macro.
(CP_TYPE_CONST_P): Likewise.
(CP_TYPE_VOLATILE_P): Likewise.
(CP_TYPE_RESTRICT_P): Likewise.
(CP_TYPE_CONST_NON_VOLATILE_P): Likewise.
(cp_build_type_variant): Rename to ...
(cp_build_qualified_type): New function.
(c_apply_type_quals_to_decl): Declare.
(SIGNATURE_POINTER_NAME_FORMAT): Modify to allow `restrict'.
(SIGNATURE_REFERENCE_NAME_FORMAT): Likewise.
(cp_type_qual_from_rid): New function.
(compparms): Remove unused parameter. All callers changed.
(cp_type_quals): New function.
(at_least_as_qualified_p): Likewise.
(more_qualified_p): Likewise.
* call.c (standard_conversion): Replace calls to
cp_build_type_variant with cp_build_qualified_type. Use
CP_TYPE_QUALS to get qualifiers and at_least_as_qualified_p to
compare them. Use CP_TYPE_* macros to check qualifiers.
(reference_binding): Likewise.
(implicit_conversion): Likewise.
(add_builtin_candidates): Likewise.
(build_over_call): Likewise.
* class.c (overrides): Compare all qualifiers, not just `const',
on method declarations.
* cvt.c (convert_to_reference): More CP_TYPE_QUALS conversion, etc.
(convert_pointer_to_real): Likewise.
(type_promotes_to): Likewise.
* decl.c (check_for_uninitialized_const_var): New function.
(init_decl_processing): More CP_TYPE_QUALS conversion, etc.
(cp_finish_decl): Use check_for_uninitialized_const_var.
(grokdeclarator): More CP_TYPE_QUALS conversion, etc. Update to
handle `restrict'.
(grok_ctor_properties): Likewise.
(grok_op_properties): Likewise.
(start_function): Likewise.
(rever_static_member_fn): Likewise.
* decl2.c (grok_method_quals): Likewise.
(grokfield): Likewise.
* error.c (dump_readonly_or_volatile): Rename to ...
(dump_qualifiers): New function. Handle `restrict'.
(dump_type_real): Use it.
(dump_aggr_type): Likewise.
(dump_type_prefix): Likewise.
(dump_type_suffix): Likewise.
(dump_function_decl): Likewise.
(cv_as_string): Likewise.
* gxx.gperf: Add __restrict and __restrict__.
* gxxint.texi: Document `u' as used for `__restrict', and a few
other previously undocumented codes.
* hash.h: Regenerated.
* init.c (expand_aggr_init): More CP_TYPE_QUALS conversion, etc.
(build_member_call): Likewise.
(build_new_1): Likewise.
* lex.c (init_parse): Add entry for RID_RESTRICT.
(cons_up_default_function): More CP_TYPE_QUALS conversion, etc.
(cp_type_qual_from_rid): Define.
* lex.h (enum rid): Add RID_RESTRICT.
* method.c (process_modifiers): Deal with `restrict'.
* parse.y (primary): More CP_TYPE_QUALS conversion, etc.
* parse.c: Regenerated.
* pt.c (convert_nontype_argument): More CP_TYPE_QUALS conversion, etc.
(tsubst_aggr_type): Likewise.
(tsubst): Likewise.
(check_cv_quals_for_unify): Likewise.
(unify): Likewise.
* rtti.c (init_rtti_processing): Likewise.
(build_headof): Likewise.
(get_tinfo_var): Likewise.
(buidl_dynamic_cast_1): Likewise. Fix `volatile' handling.
(expand_class_desc): Likewise.
(expand_attr_desc): Likewise.
(synthesize_tinfo_fn): Likewise.
* search.c (covariant_return_p): Likewise. Fix `volatile' handling.
(get_matching_virtual): Likewise.
(expand_upcast_fixups): Likewise.
* sig.c (build_signature_pointer_or_reference_name): Take
type_quals, not constp and volatilep.
(build_signature_pointer_or_reference_type): Likewise.
(match_method_types): More CP_TYPE_QUALS conversion, etc.
(build_signature_pointer_constructor): Likewise.
(build_signature_method_call): Likewise.
* tree.c (build_cplus_array_type): Likewise.
(cp_build_type_variant): Rename to ...
(cp_build_qualified_type): New function. Deal with `__restrict'.
(canonical_type_variant): More CP_TYPE_QUALS conversion, etc.
(build_exception_variant): Likewise.
(mapcar): Likewise.
* typeck.c (qualif_type): Likewise.
(common_type): Likewise.
(comptypes): Likewise.
(comp_cv_target_types): Likewise.
(at_least_as_qualified_p): Define.
(more_qualified_p): Likewise.
(comp_cv_qualification): More CP_TYPE_QUALS conversion, etc.
(compparms): Likewise.
(inline_conversion): Likewise.
(string_conv_p): Likewise.
(build_component_ref): Likewise.
(build_indirect_ref): Likewise.
(build_array_ref): Likewise.
(build_unary_op): Likewise.
(build_conditional_expr): Likewise.
(build_static_cast): Likewise.
(build_c_cast): Likewise.
(build_modify_expr): Likewise.
(convert_For_assignment): Likewise.
(comp_ptr_ttypes_real): Likewise.
(cp_type_quals): New function.
From-SVN: r23258
1998-10-23 16:53:28 +02:00
|
|
|
|
if ((TYPE_QUALS (TREE_TYPE (TREE_VALUE (base_types)))
|
|
|
|
|
== TYPE_QUALS (TREE_TYPE (TREE_VALUE (types))))
|
|
|
|
|
&& compparms (TREE_CHAIN (base_types), TREE_CHAIN (types)))
|
1994-04-22 01:30:18 +02:00
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
typedef struct find_final_overrider_data_s {
|
|
|
|
|
/* The function for which we are trying to find a final overrider. */
|
|
|
|
|
tree fn;
|
|
|
|
|
/* The base class in which the function was declared. */
|
|
|
|
|
tree declaring_base;
|
|
|
|
|
/* The most derived class in the hierarchy. */
|
|
|
|
|
tree most_derived_type;
|
|
|
|
|
/* The final overriding function. */
|
|
|
|
|
tree overriding_fn;
|
|
|
|
|
/* The BINFO for the class in which the final overriding function
|
|
|
|
|
appears. */
|
|
|
|
|
tree overriding_base;
|
|
|
|
|
} find_final_overrider_data;
|
|
|
|
|
|
|
|
|
|
/* Called from find_final_overrider via dfs_walk. */
|
2000-01-12 21:56:15 +01:00
|
|
|
|
|
1994-08-05 22:25:20 +02:00
|
|
|
|
static tree
|
2000-01-31 22:00:01 +01:00
|
|
|
|
dfs_find_final_overrider (binfo, data)
|
|
|
|
|
tree binfo;
|
|
|
|
|
void *data;
|
1994-08-05 22:25:20 +02:00
|
|
|
|
{
|
2000-01-31 22:00:01 +01:00
|
|
|
|
find_final_overrider_data *ffod = (find_final_overrider_data *) data;
|
1994-08-05 22:25:20 +02:00
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
if (same_type_p (BINFO_TYPE (binfo),
|
|
|
|
|
BINFO_TYPE (ffod->declaring_base))
|
|
|
|
|
&& tree_int_cst_equal (BINFO_OFFSET (binfo),
|
|
|
|
|
BINFO_OFFSET (ffod->declaring_base)))
|
1994-08-05 22:25:20 +02:00
|
|
|
|
{
|
2000-01-31 22:00:01 +01:00
|
|
|
|
tree path;
|
|
|
|
|
tree method;
|
|
|
|
|
|
|
|
|
|
/* We've found a path to the declaring base. Walk down the path
|
|
|
|
|
looking for an overrider for FN. */
|
|
|
|
|
for (path = reverse_path (binfo);
|
|
|
|
|
path;
|
|
|
|
|
path = TREE_CHAIN (path))
|
|
|
|
|
{
|
|
|
|
|
for (method = TYPE_METHODS (BINFO_TYPE (TREE_VALUE (path)));
|
|
|
|
|
method;
|
|
|
|
|
method = TREE_CHAIN (method))
|
|
|
|
|
if (DECL_VIRTUAL_P (method) && overrides (method, ffod->fn))
|
|
|
|
|
break;
|
1994-08-05 22:25:20 +02:00
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
if (method)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If we found an overrider, record the overriding function, and
|
|
|
|
|
the base from which it came. */
|
|
|
|
|
if (path)
|
1994-08-05 22:25:20 +02:00
|
|
|
|
{
|
2000-01-31 22:00:01 +01:00
|
|
|
|
if (ffod->overriding_fn && ffod->overriding_fn != method)
|
1994-08-05 22:25:20 +02:00
|
|
|
|
{
|
2000-01-31 22:00:01 +01:00
|
|
|
|
/* We've found a different overrider along a different
|
|
|
|
|
path. That can be OK if the new one overrides the
|
|
|
|
|
old one. Consider:
|
|
|
|
|
|
|
|
|
|
struct S { virtual void f(); };
|
|
|
|
|
struct T : public virtual S { virtual void f(); };
|
|
|
|
|
struct U : public virtual S, public virtual T {};
|
|
|
|
|
|
|
|
|
|
Here `T::f' is the final overrider for `S::f'. */
|
|
|
|
|
if (strictly_overrides (method, ffod->overriding_fn))
|
|
|
|
|
{
|
|
|
|
|
ffod->overriding_fn = method;
|
|
|
|
|
ffod->overriding_base = TREE_VALUE (path);
|
|
|
|
|
}
|
|
|
|
|
else if (!strictly_overrides (ffod->overriding_fn, method))
|
|
|
|
|
{
|
|
|
|
|
cp_error ("no unique final overrider for `%D' in `%T'",
|
|
|
|
|
ffod->most_derived_type,
|
|
|
|
|
ffod->fn);
|
|
|
|
|
cp_error ("candidates are: `%#D'", ffod->overriding_fn);
|
|
|
|
|
cp_error (" `%#D'", method);
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (ffod->overriding_base
|
|
|
|
|
&& (!tree_int_cst_equal
|
|
|
|
|
(BINFO_OFFSET (TREE_VALUE (path)),
|
|
|
|
|
BINFO_OFFSET (ffod->overriding_base))))
|
|
|
|
|
{
|
|
|
|
|
/* We've found two instances of the same base that
|
|
|
|
|
provide overriders. */
|
|
|
|
|
cp_error ("no unique final overrider for `%D' since there two instances of `%T' in `%T'",
|
|
|
|
|
ffod->fn,
|
|
|
|
|
BINFO_TYPE (ffod->overriding_base),
|
|
|
|
|
ffod->most_derived_type);
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ffod->overriding_fn = method;
|
|
|
|
|
ffod->overriding_base = TREE_VALUE (path);
|
1994-08-05 22:25:20 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-01-12 21:56:15 +01:00
|
|
|
|
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
/* Returns a TREE_LIST whose TREE_PURPOSE is the final overrider for
|
|
|
|
|
FN and whose TREE_VALUE is the binfo for the base where the
|
|
|
|
|
overriding occurs. BINFO (in the hierarchy dominated by T) is the
|
|
|
|
|
base object in which FN is declared. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1994-08-05 22:25:20 +02:00
|
|
|
|
static tree
|
2000-01-31 22:00:01 +01:00
|
|
|
|
find_final_overrider (t, binfo, fn)
|
|
|
|
|
tree t;
|
|
|
|
|
tree binfo;
|
|
|
|
|
tree fn;
|
1994-08-05 22:25:20 +02:00
|
|
|
|
{
|
2000-01-31 22:00:01 +01:00
|
|
|
|
find_final_overrider_data ffod;
|
1994-08-05 22:25:20 +02:00
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
/* Getting this right is a little tricky. This is legal:
|
1994-08-05 22:25:20 +02:00
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
struct S { virtual void f (); };
|
|
|
|
|
struct T { virtual void f (); };
|
|
|
|
|
struct U : public S, public T { };
|
1994-08-05 22:25:20 +02:00
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
even though calling `f' in `U' is ambiguous. But,
|
1994-08-05 22:25:20 +02:00
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
struct R { virtual void f(); };
|
|
|
|
|
struct S : virtual public R { virtual void f (); };
|
|
|
|
|
struct T : virtual public R { virtual void f (); };
|
|
|
|
|
struct U : public S, public T { };
|
2000-01-12 21:56:15 +01:00
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
is not -- there's no way to decide whether to put `S::f' or
|
|
|
|
|
`T::f' in the vtable for `R'.
|
|
|
|
|
|
|
|
|
|
The solution is to look at all paths to BINFO. If we find
|
|
|
|
|
different overriders along any two, then there is a problem. */
|
|
|
|
|
ffod.fn = fn;
|
|
|
|
|
ffod.declaring_base = binfo;
|
|
|
|
|
ffod.most_derived_type = t;
|
|
|
|
|
ffod.overriding_fn = NULL_TREE;
|
|
|
|
|
ffod.overriding_base = NULL_TREE;
|
|
|
|
|
|
|
|
|
|
if (dfs_walk (TYPE_BINFO (t),
|
|
|
|
|
dfs_find_final_overrider,
|
|
|
|
|
NULL,
|
|
|
|
|
&ffod))
|
|
|
|
|
return error_mark_node;
|
2000-01-12 21:56:15 +01:00
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
return build_tree_list (ffod.overriding_fn, ffod.overriding_base);
|
1994-08-05 22:25:20 +02:00
|
|
|
|
}
|
|
|
|
|
|
2000-01-02 05:04:05 +01:00
|
|
|
|
/* Return the BINFO_VIRTUALS list for BINFO, without the RTTI stuff at
|
|
|
|
|
the front. If non-NULL, N is set to the number of entries
|
|
|
|
|
skipped. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
2000-01-02 05:04:05 +01:00
|
|
|
|
tree
|
|
|
|
|
skip_rtti_stuff (binfo, t, n)
|
|
|
|
|
tree binfo;
|
|
|
|
|
tree t;
|
|
|
|
|
unsigned HOST_WIDE_INT *n;
|
1995-10-12 03:33:51 +01:00
|
|
|
|
{
|
2000-01-02 05:04:05 +01:00
|
|
|
|
tree virtuals;
|
1995-10-12 03:33:51 +01:00
|
|
|
|
|
1999-04-13 02:39:32 +02:00
|
|
|
|
if (CLASSTYPE_COM_INTERFACE (t))
|
|
|
|
|
return 0;
|
|
|
|
|
|
2000-01-02 05:04:05 +01:00
|
|
|
|
if (n)
|
|
|
|
|
*n = 0;
|
|
|
|
|
virtuals = BINFO_VIRTUALS (binfo);
|
|
|
|
|
if (virtuals)
|
1995-10-12 03:33:51 +01:00
|
|
|
|
{
|
|
|
|
|
/* We always reserve a slot for the offset/tdesc entry. */
|
2000-01-02 05:04:05 +01:00
|
|
|
|
if (n)
|
|
|
|
|
++*n;
|
|
|
|
|
virtuals = TREE_CHAIN (virtuals);
|
1995-10-12 03:33:51 +01:00
|
|
|
|
}
|
2000-01-02 05:04:05 +01:00
|
|
|
|
if (flag_vtable_thunks && virtuals)
|
1995-10-12 03:33:51 +01:00
|
|
|
|
{
|
|
|
|
|
/* The second slot is reserved for the tdesc pointer when thunks
|
|
|
|
|
are used. */
|
2000-01-02 05:04:05 +01:00
|
|
|
|
if (n)
|
|
|
|
|
++*n;
|
|
|
|
|
virtuals = TREE_CHAIN (virtuals);
|
1995-10-12 03:33:51 +01:00
|
|
|
|
}
|
2000-01-02 05:04:05 +01:00
|
|
|
|
|
|
|
|
|
return virtuals;
|
1995-10-12 03:33:51 +01:00
|
|
|
|
}
|
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
/* Called via dfs_walk. Returns BINFO if BINFO has the same type as
|
|
|
|
|
DATA (which is really an _TYPE node). */
|
1999-07-27 20:15:21 +02:00
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
static tree
|
|
|
|
|
dfs_find_base (binfo, data)
|
|
|
|
|
tree binfo;
|
|
|
|
|
void *data;
|
|
|
|
|
{
|
|
|
|
|
return (same_type_p (BINFO_TYPE (binfo), (tree) data)
|
|
|
|
|
? binfo : NULL_TREE);
|
1994-04-22 01:30:18 +02:00
|
|
|
|
}
|
|
|
|
|
|
2000-01-03 07:56:21 +01:00
|
|
|
|
/* Called from modify_all_vtables via dfs_walk. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
2000-01-03 07:56:21 +01:00
|
|
|
|
static tree
|
|
|
|
|
dfs_modify_vtables (binfo, data)
|
|
|
|
|
tree binfo;
|
|
|
|
|
void *data;
|
|
|
|
|
{
|
|
|
|
|
if (/* There's no need to modify the vtable for a primary base;
|
|
|
|
|
we're not going to use that vtable anyhow. */
|
|
|
|
|
!BINFO_PRIMARY_MARKED_P (binfo)
|
|
|
|
|
/* Similarly, a base without a vtable needs no modification. */
|
|
|
|
|
&& CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
|
1994-04-22 01:30:18 +02:00
|
|
|
|
{
|
2000-01-31 22:00:01 +01:00
|
|
|
|
tree t;
|
|
|
|
|
tree virtuals;
|
|
|
|
|
tree old_virtuals;
|
|
|
|
|
|
|
|
|
|
t = (tree) data;
|
|
|
|
|
|
2000-02-10 09:24:15 +01:00
|
|
|
|
/* If we're supporting RTTI then we always need a new vtable to
|
|
|
|
|
point to the RTTI information. Under the new ABI we may need
|
|
|
|
|
a new vtable to contain vcall and vbase offsets. */
|
2000-01-31 22:00:01 +01:00
|
|
|
|
if (flag_rtti || flag_new_abi)
|
|
|
|
|
make_new_vtable (t, binfo);
|
|
|
|
|
|
|
|
|
|
/* Now, go through each of the virtual functions in the virtual
|
|
|
|
|
function table for BINFO. Find the final overrider, and
|
|
|
|
|
update the BINFO_VIRTUALS list appropriately. */
|
|
|
|
|
for (virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), NULL),
|
|
|
|
|
old_virtuals = skip_rtti_stuff (TYPE_BINFO (BINFO_TYPE (binfo)),
|
|
|
|
|
BINFO_TYPE (binfo),
|
|
|
|
|
NULL);
|
|
|
|
|
virtuals;
|
|
|
|
|
virtuals = TREE_CHAIN (virtuals),
|
|
|
|
|
old_virtuals = TREE_CHAIN (old_virtuals))
|
|
|
|
|
{
|
|
|
|
|
tree b;
|
|
|
|
|
tree fn;
|
|
|
|
|
tree overrider;
|
|
|
|
|
tree vindex;
|
|
|
|
|
tree delta;
|
2000-02-10 09:24:15 +01:00
|
|
|
|
int i;
|
2000-01-31 22:00:01 +01:00
|
|
|
|
|
|
|
|
|
/* Find the function which originally caused this vtable
|
|
|
|
|
entry to be present. */
|
|
|
|
|
fn = BV_FN (old_virtuals);
|
|
|
|
|
vindex = DECL_VINDEX (fn);
|
|
|
|
|
b = dfs_walk (binfo, dfs_find_base, NULL, DECL_VIRTUAL_CONTEXT (fn));
|
|
|
|
|
fn = skip_rtti_stuff (TYPE_BINFO (BINFO_TYPE (b)),
|
|
|
|
|
BINFO_TYPE (b),
|
2000-02-10 09:24:15 +01:00
|
|
|
|
&i);
|
|
|
|
|
while (i < TREE_INT_CST_LOW (vindex))
|
|
|
|
|
{
|
|
|
|
|
fn = TREE_CHAIN (fn);
|
|
|
|
|
++i;
|
|
|
|
|
}
|
2000-01-31 22:00:01 +01:00
|
|
|
|
fn = BV_FN (fn);
|
|
|
|
|
|
|
|
|
|
/* Handle the case of a virtual function defined in BINFO
|
|
|
|
|
itself. */
|
|
|
|
|
overrider = find_final_overrider (t, b, fn);
|
|
|
|
|
if (overrider == error_mark_node)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* The `this' pointer needs to be adjusted from pointing to
|
|
|
|
|
BINFO to pointing at the base where the final overrider
|
|
|
|
|
appears. */
|
|
|
|
|
delta = size_binop (PLUS_EXPR,
|
|
|
|
|
get_derived_offset (binfo,
|
|
|
|
|
DECL_VIRTUAL_CONTEXT (fn)),
|
|
|
|
|
BINFO_OFFSET (binfo));
|
|
|
|
|
delta = ssize_binop (MINUS_EXPR,
|
|
|
|
|
BINFO_OFFSET (TREE_VALUE (overrider)),
|
|
|
|
|
delta);
|
|
|
|
|
|
|
|
|
|
modify_vtable_entry (t,
|
|
|
|
|
binfo,
|
|
|
|
|
TREE_PURPOSE (overrider),
|
|
|
|
|
delta,
|
|
|
|
|
&virtuals);
|
|
|
|
|
}
|
1994-04-22 01:30:18 +02:00
|
|
|
|
}
|
2000-01-03 07:56:21 +01:00
|
|
|
|
|
|
|
|
|
SET_BINFO_MARKED (binfo);
|
|
|
|
|
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-17 23:54:23 +01:00
|
|
|
|
/* Update all of the primary and secondary vtables for T. Create new
|
|
|
|
|
vtables as required, and initialize their RTTI information. Each
|
|
|
|
|
of the functions in OVERRIDDEN_VIRTUALS overrides a virtual
|
|
|
|
|
function from a base class; find and modify the appropriate entries
|
|
|
|
|
to point to the overriding functions. Returns a list, in
|
|
|
|
|
declaration order, of the functions that are overridden in this
|
|
|
|
|
class, but do not appear in the primary base class vtable, and
|
|
|
|
|
which should therefore be appended to the end of the vtable for T. */
|
|
|
|
|
|
|
|
|
|
static tree
|
|
|
|
|
modify_all_vtables (t, has_virtual_p, overridden_virtuals)
|
2000-01-03 07:56:21 +01:00
|
|
|
|
tree t;
|
2000-01-17 23:54:23 +01:00
|
|
|
|
int *has_virtual_p;
|
|
|
|
|
tree overridden_virtuals;
|
2000-01-03 07:56:21 +01:00
|
|
|
|
{
|
2000-01-17 23:54:23 +01:00
|
|
|
|
tree binfo;
|
2000-01-03 07:56:21 +01:00
|
|
|
|
|
2000-01-17 23:54:23 +01:00
|
|
|
|
binfo = TYPE_BINFO (t);
|
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
/* Update all of the vtables. */
|
|
|
|
|
dfs_walk (binfo,
|
|
|
|
|
dfs_modify_vtables,
|
|
|
|
|
dfs_unmarked_real_bases_queue_p,
|
|
|
|
|
t);
|
|
|
|
|
dfs_walk (binfo, dfs_unmark, dfs_marked_real_bases_queue_p, t);
|
2000-01-17 23:54:23 +01:00
|
|
|
|
|
|
|
|
|
/* If we should include overriding functions for secondary vtables
|
|
|
|
|
in our primary vtable, add them now. */
|
|
|
|
|
if (all_overridden_vfuns_in_vtables_p ())
|
|
|
|
|
{
|
|
|
|
|
tree *fnsp = &overridden_virtuals;
|
|
|
|
|
|
|
|
|
|
while (*fnsp)
|
|
|
|
|
{
|
|
|
|
|
tree fn = TREE_VALUE (*fnsp);
|
|
|
|
|
|
|
|
|
|
if (BINFO_VIRTUALS (binfo)
|
|
|
|
|
&& !value_member (fn, BINFO_VIRTUALS (binfo)))
|
|
|
|
|
{
|
|
|
|
|
/* We know we need a vtable for this class now. */
|
|
|
|
|
start_vtable (t, has_virtual_p);
|
|
|
|
|
/* Set the vtable index. */
|
|
|
|
|
DECL_VINDEX (fn)
|
|
|
|
|
= build_shared_int_cst ((*has_virtual_p)++);
|
|
|
|
|
/* We don't need to convert to a base class when calling
|
|
|
|
|
this function. */
|
|
|
|
|
DECL_VIRTUAL_CONTEXT (fn) = t;
|
2000-02-20 03:46:56 +01:00
|
|
|
|
|
2000-01-17 23:54:23 +01:00
|
|
|
|
/* We don't need to adjust the `this' pointer when
|
|
|
|
|
calling this function. */
|
2000-01-31 22:00:01 +01:00
|
|
|
|
BV_DELTA (*fnsp) = integer_zero_node;
|
|
|
|
|
BV_VCALL_INDEX (*fnsp) = integer_zero_node;
|
2000-01-17 23:54:23 +01:00
|
|
|
|
|
|
|
|
|
/* This is an overridden function not already in our
|
|
|
|
|
vtable. Keep it. */
|
|
|
|
|
fnsp = &TREE_CHAIN (*fnsp);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
/* We've already got an entry for this function. Skip
|
|
|
|
|
it. */
|
|
|
|
|
*fnsp = TREE_CHAIN (*fnsp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
overridden_virtuals = NULL_TREE;
|
|
|
|
|
|
|
|
|
|
return overridden_virtuals;
|
1994-04-22 01:30:18 +02:00
|
|
|
|
}
|
|
|
|
|
|
1994-04-29 00:48:45 +02:00
|
|
|
|
/* Here, we already know that they match in every respect.
|
|
|
|
|
All we have to check is where they had their declarations. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1994-04-29 00:48:45 +02:00
|
|
|
|
static int
|
|
|
|
|
strictly_overrides (fndecl1, fndecl2)
|
|
|
|
|
tree fndecl1, fndecl2;
|
|
|
|
|
{
|
Make DECL_CONTEXT mean the class in which a member function was declared, even for a virtual function.
Make DECL_CONTEXT mean the class in which a member function was
declared, even for a virtual function.
* cp-tree.h (DECL_CLASS_CONTEXT): Adjust.
(DECL_FRIEND_CONTEXT): New macro.
(DECL_REAL_CONTEXT): Remove.
(SET_DECL_FRIEND_CONTEXT): Likewise.
(DECL_VIRTUAL_CONTEXT): Adjust.
(DECL_CLASS_SCOPE_P): Use TYPE_P.
(add_friends): Remove.
(hack_decl_function_context): Likewise.
* call.c (build_new_function_call): Replace DECL_REAL_CONTEXT with
CP_DECL_CONTEXT.
(build_over_call): Fix indentation. Use DECL_CONTEXT
instead of DECL_CLASS_CONTEXT.
* class.c (dfs_build_vcall_offset_vtbl_entries): Likewise.
(add_method): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT.
(strictly_overrides): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
(build_vtbl_or_vbase_field): Don't set DECL_CLASS_CONTEXT.
(build_base_field): Likewise.
(finish_struct_1): Likewise.
(build_self_reference): Likewise.
* decl.c (push_class_binding): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(pushtag): Use decl_function_context, not
hack_decl_function_context.
(decls_match): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
(duplicate_decls): Use DECL_VIRTUAL_CONTEXT.
(pushdecl): Remove bogus code.
(start_decl): Use DECL_CONTEXT rather than DECL_CLASS_CONTEXT.
(cp_finish_decl): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
(grokfndecl): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
Use decl_function_context, nothack_decl_function_context.
(grokvardecl): Don't set DECL_CLASS_CONTEXT.
(grokdeclarator): Likewise. Use decl_function_context, not
hack_decl_function_context.
(copy_args_p): Document. Don't use DECL_CLASS_CONTEXT.
(start_function): Use DECL_FRIEND_CONTEXT, not
DECL_CLASS_CONTEXT. Use decl_function_context, not
hack_decl_function_context.
(finish_function): Use decl_function_context, not
hack_decl_function_context.
(maybe_retrofit_in_chrg): Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
(grokclassfn): Set DECL_VIRTUAL_CONTEXT, not DECL_CONTEXT.
(finish_static_data_member_decl): Don't set DECL_CLASS_CONTEXT.
(grokfield): Likewise.
(finish_builtin_type): Likewise.
(finish_vtable_vardec): Use decl_function_context, not
hack_decl_function_context.
(import_export_decl): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
(start_static_initialization_or_destruction): Likewise.
(finish_static_initialization_or_destruction): Likewise.
(mark_used): Adjust logic for deciding when to synthesize methods.
* dump.c (dequeue_and_dump): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
* error.c (dump_function_decl): Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
* friend.c (is_friend): Likewise.
(add_friends): Remove.
(do_friend): Use SET_DECL_FRIEND_CONTEXT.
* lex.c (begin_definition_of_inclass_inline): Use
decl_function_context, not hack_decl_function_context.
(process_next_inline): Likewise.
(do_identifier): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
* method.c (set_mangled_name_for_decl): Use DECL_CONTEXT, not
DECL_CLASSS_CONTEXT.
(hack_identifier): Likewise.
(synthesize_method): Use decl_function_context, not
hack_decl_function_context.
* pt.c (template_class_depth_real): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(is_member_template): Use decl_function_context, not
hack_decl_function_context. Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
(build_template_decl): Set DECL_VIRTUAL_CONTEXT, not
DECL_CLASS_CONTEXT.
(check_default_tmpl_args): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(push_template_decl_real): Likewise.
(instantiate_class_template): Don't call add_friends.
(tsubst_default_argument): Use DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(tsubst_decl): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT.
Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
(set_meangled_name_for_template_decl): Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
* repo.c (repo_inline_used): Likewise.
* search.c (current_scope): Adjust for new _CONTEXT macros.
(context_for_name_lookup): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(friend_accessible_p): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
(lookup_fnfields_here):Likewise.
(check_final_overrider): Likewise.
(init_vbase_pointers): Likewise.
(virtual_context): Likewise.
* semantics.c (finish_member_declaration): Just set DECL_CONTEXT.
(expand_body): Use decl_function_context, not
hack_decl_function_context.
* tree.c (hack_decl_function_context): Remove.
* typeck.c (build_x_function_call): Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
* typeck2.c (error_not_base_type): Likewise.
From-SVN: r32018
2000-02-17 00:54:23 +01:00
|
|
|
|
int distance = get_base_distance (DECL_CONTEXT (fndecl2),
|
|
|
|
|
DECL_CONTEXT (fndecl1),
|
1994-04-29 00:48:45 +02:00
|
|
|
|
0, (tree *)0);
|
|
|
|
|
if (distance == -2 || distance > 0)
|
|
|
|
|
return 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-01 20:32:00 +01:00
|
|
|
|
/* Get the base virtual function declarations in T that are either
|
|
|
|
|
overridden or hidden by FNDECL as a list. We set TREE_PURPOSE with
|
|
|
|
|
the overrider/hider. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1997-08-27 10:03:41 +02:00
|
|
|
|
static tree
|
1996-02-01 20:32:00 +01:00
|
|
|
|
get_basefndecls (fndecl, t)
|
|
|
|
|
tree fndecl, t;
|
|
|
|
|
{
|
|
|
|
|
tree methods = TYPE_METHODS (t);
|
|
|
|
|
tree base_fndecls = NULL_TREE;
|
|
|
|
|
tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
|
|
|
|
|
int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
|
|
|
|
|
|
|
|
|
|
while (methods)
|
|
|
|
|
{
|
|
|
|
|
if (TREE_CODE (methods) == FUNCTION_DECL
|
|
|
|
|
&& DECL_VINDEX (methods) != NULL_TREE
|
|
|
|
|
&& DECL_NAME (fndecl) == DECL_NAME (methods))
|
1999-12-16 04:10:12 +01:00
|
|
|
|
base_fndecls = tree_cons (fndecl, methods, base_fndecls);
|
1996-02-01 20:32:00 +01:00
|
|
|
|
|
|
|
|
|
methods = TREE_CHAIN (methods);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (base_fndecls)
|
|
|
|
|
return base_fndecls;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < n_baseclasses; i++)
|
|
|
|
|
{
|
|
|
|
|
tree base_binfo = TREE_VEC_ELT (binfos, i);
|
|
|
|
|
tree basetype = BINFO_TYPE (base_binfo);
|
|
|
|
|
|
|
|
|
|
base_fndecls = chainon (get_basefndecls (fndecl, basetype),
|
|
|
|
|
base_fndecls);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return base_fndecls;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Mark the functions that have been hidden with their overriders.
|
|
|
|
|
Since we start out with all functions already marked with a hider,
|
1999-08-03 00:59:03 +02:00
|
|
|
|
no need to mark functions that are just hidden.
|
|
|
|
|
|
|
|
|
|
Subroutine of warn_hidden. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1997-04-02 05:58:33 +02:00
|
|
|
|
static void
|
1996-02-01 20:32:00 +01:00
|
|
|
|
mark_overriders (fndecl, base_fndecls)
|
|
|
|
|
tree fndecl, base_fndecls;
|
|
|
|
|
{
|
1999-08-03 00:59:03 +02:00
|
|
|
|
for (; base_fndecls; base_fndecls = TREE_CHAIN (base_fndecls))
|
1996-02-01 20:32:00 +01:00
|
|
|
|
{
|
1999-08-03 00:59:03 +02:00
|
|
|
|
if (overrides (fndecl, TREE_VALUE (base_fndecls)))
|
1996-02-01 20:32:00 +01:00
|
|
|
|
TREE_PURPOSE (base_fndecls) = fndecl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-09 23:43:25 +01:00
|
|
|
|
/* If this declaration supersedes the declaration of
|
|
|
|
|
a method declared virtual in the base class, then
|
|
|
|
|
mark this field as being virtual as well. */
|
|
|
|
|
|
1997-04-02 05:58:33 +02:00
|
|
|
|
static void
|
1996-02-20 21:35:10 +01:00
|
|
|
|
check_for_override (decl, ctype)
|
1996-02-09 23:43:25 +01:00
|
|
|
|
tree decl, ctype;
|
|
|
|
|
{
|
|
|
|
|
tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype));
|
|
|
|
|
int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
|
|
|
|
|
int virtualp = DECL_VIRTUAL_P (decl);
|
1999-02-26 13:00:10 +01:00
|
|
|
|
int found_overriden_fn = 0;
|
1996-02-09 23:43:25 +01:00
|
|
|
|
|
|
|
|
|
for (i = 0; i < n_baselinks; i++)
|
|
|
|
|
{
|
|
|
|
|
tree base_binfo = TREE_VEC_ELT (binfos, i);
|
1999-12-21 01:19:01 +01:00
|
|
|
|
if (TYPE_POLYMORPHIC_P (BINFO_TYPE (base_binfo)))
|
1996-02-09 23:43:25 +01:00
|
|
|
|
{
|
|
|
|
|
tree tmp = get_matching_virtual
|
|
|
|
|
(base_binfo, decl,
|
|
|
|
|
DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)));
|
1999-02-26 13:00:10 +01:00
|
|
|
|
|
|
|
|
|
if (tmp && !found_overriden_fn)
|
1996-02-09 23:43:25 +01:00
|
|
|
|
{
|
|
|
|
|
/* If this function overrides some virtual in some base
|
|
|
|
|
class, then the function itself is also necessarily
|
|
|
|
|
virtual, even if the user didn't explicitly say so. */
|
|
|
|
|
DECL_VIRTUAL_P (decl) = 1;
|
|
|
|
|
|
|
|
|
|
/* The TMP we really want is the one from the deepest
|
|
|
|
|
baseclass on this path, taking care not to
|
|
|
|
|
duplicate if we have already found it (via another
|
|
|
|
|
path to its virtual baseclass. */
|
|
|
|
|
if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
|
|
|
|
|
{
|
1999-08-04 11:07:51 +02:00
|
|
|
|
cp_error_at ("`static %#D' cannot be declared", decl);
|
|
|
|
|
cp_error_at (" since `virtual %#D' declared in base class",
|
1996-02-09 23:43:25 +01:00
|
|
|
|
tmp);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
virtualp = 1;
|
|
|
|
|
|
2000-01-17 21:18:43 +01:00
|
|
|
|
/* Set DECL_VINDEX to a value that is neither an
|
|
|
|
|
INTEGER_CST nor the error_mark_node so that
|
|
|
|
|
add_virtual_function will realize this is an
|
|
|
|
|
overridden function. */
|
|
|
|
|
DECL_VINDEX (decl)
|
|
|
|
|
= tree_cons (tmp, NULL_TREE, DECL_VINDEX (decl));
|
1999-02-26 13:00:10 +01:00
|
|
|
|
|
|
|
|
|
/* We now know that DECL overrides something,
|
|
|
|
|
which is all that is important. But, we must
|
|
|
|
|
continue to iterate through all the base-classes
|
|
|
|
|
in order to allow get_matching_virtual to check for
|
|
|
|
|
various illegal overrides. */
|
|
|
|
|
found_overriden_fn = 1;
|
1996-02-09 23:43:25 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (virtualp)
|
|
|
|
|
{
|
|
|
|
|
if (DECL_VINDEX (decl) == NULL_TREE)
|
|
|
|
|
DECL_VINDEX (decl) = error_mark_node;
|
|
|
|
|
IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1996-03-21 20:46:11 +01:00
|
|
|
|
/* Warn about hidden virtual functions that are not overridden in t.
|
|
|
|
|
We know that constructors and destructors don't apply. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1996-02-01 20:32:00 +01:00
|
|
|
|
void
|
|
|
|
|
warn_hidden (t)
|
|
|
|
|
tree t;
|
|
|
|
|
{
|
|
|
|
|
tree method_vec = CLASSTYPE_METHOD_VEC (t);
|
|
|
|
|
int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* We go through each separately named virtual function. */
|
1998-10-06 16:20:30 +02:00
|
|
|
|
for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); ++i)
|
1996-02-01 20:32:00 +01:00
|
|
|
|
{
|
1998-07-12 03:30:11 +02:00
|
|
|
|
tree fns = TREE_VEC_ELT (method_vec, i);
|
2000-01-04 17:29:41 +01:00
|
|
|
|
tree fndecl = NULL_TREE;
|
1996-02-01 20:32:00 +01:00
|
|
|
|
|
|
|
|
|
tree base_fndecls = NULL_TREE;
|
|
|
|
|
tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
|
|
|
|
|
int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
|
|
|
|
|
|
1999-08-03 00:59:03 +02:00
|
|
|
|
/* First see if we have any virtual functions in this batch. */
|
|
|
|
|
for (; fns; fns = OVL_NEXT (fns))
|
|
|
|
|
{
|
|
|
|
|
fndecl = OVL_CURRENT (fns);
|
|
|
|
|
if (DECL_VINDEX (fndecl))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fns == NULL_TREE)
|
1996-02-01 20:32:00 +01:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* First we get a list of all possible functions that might be
|
|
|
|
|
hidden from each base class. */
|
|
|
|
|
for (i = 0; i < n_baseclasses; i++)
|
|
|
|
|
{
|
|
|
|
|
tree base_binfo = TREE_VEC_ELT (binfos, i);
|
|
|
|
|
tree basetype = BINFO_TYPE (base_binfo);
|
|
|
|
|
|
|
|
|
|
base_fndecls = chainon (get_basefndecls (fndecl, basetype),
|
|
|
|
|
base_fndecls);
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-12 03:30:11 +02:00
|
|
|
|
fns = OVL_NEXT (fns);
|
1996-02-01 20:32:00 +01:00
|
|
|
|
|
|
|
|
|
/* ...then mark up all the base functions with overriders, preferring
|
|
|
|
|
overriders to hiders. */
|
|
|
|
|
if (base_fndecls)
|
1999-08-03 00:59:03 +02:00
|
|
|
|
for (; fns; fns = OVL_NEXT (fns))
|
1996-02-01 20:32:00 +01:00
|
|
|
|
{
|
1999-08-03 00:59:03 +02:00
|
|
|
|
fndecl = OVL_CURRENT (fns);
|
|
|
|
|
if (DECL_VINDEX (fndecl))
|
|
|
|
|
mark_overriders (fndecl, base_fndecls);
|
1996-02-01 20:32:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now give a warning for all base functions without overriders,
|
|
|
|
|
as they are hidden. */
|
1999-08-03 00:59:03 +02:00
|
|
|
|
for (; base_fndecls; base_fndecls = TREE_CHAIN (base_fndecls))
|
1996-02-01 20:32:00 +01:00
|
|
|
|
{
|
1999-08-03 00:59:03 +02:00
|
|
|
|
if (! overrides (TREE_PURPOSE (base_fndecls),
|
|
|
|
|
TREE_VALUE (base_fndecls)))
|
1996-02-01 20:32:00 +01:00
|
|
|
|
{
|
|
|
|
|
/* Here we know it is a hider, and no overrider exists. */
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls));
|
|
|
|
|
cp_warning_at (" by `%D'", TREE_PURPOSE (base_fndecls));
|
1996-02-01 20:32:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check for things that are invalid. There are probably plenty of other
|
|
|
|
|
things we should check for also. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1996-02-01 20:32:00 +01:00
|
|
|
|
static void
|
|
|
|
|
finish_struct_anon (t)
|
|
|
|
|
tree t;
|
|
|
|
|
{
|
|
|
|
|
tree field;
|
1999-07-09 18:15:04 +02:00
|
|
|
|
|
1996-02-01 20:32:00 +01:00
|
|
|
|
for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
|
|
|
|
|
{
|
|
|
|
|
if (TREE_STATIC (field))
|
|
|
|
|
continue;
|
|
|
|
|
if (TREE_CODE (field) != FIELD_DECL)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (DECL_NAME (field) == NULL_TREE
|
1999-05-19 12:44:22 +02:00
|
|
|
|
&& ANON_AGGR_TYPE_P (TREE_TYPE (field)))
|
1996-02-01 20:32:00 +01:00
|
|
|
|
{
|
1999-07-09 18:15:04 +02:00
|
|
|
|
tree elt = TYPE_FIELDS (TREE_TYPE (field));
|
|
|
|
|
for (; elt; elt = TREE_CHAIN (elt))
|
1996-02-01 20:32:00 +01:00
|
|
|
|
{
|
1999-07-09 18:15:04 +02:00
|
|
|
|
if (DECL_ARTIFICIAL (elt))
|
1996-02-01 20:32:00 +01:00
|
|
|
|
continue;
|
|
|
|
|
|
1999-07-09 18:15:04 +02:00
|
|
|
|
if (DECL_NAME (elt) == constructor_name (t))
|
1998-11-18 03:21:54 +01:00
|
|
|
|
cp_pedwarn_at ("ANSI C++ forbids member `%D' with same name as enclosing class",
|
1999-07-09 18:15:04 +02:00
|
|
|
|
elt);
|
1998-11-18 03:21:54 +01:00
|
|
|
|
|
1999-07-09 18:15:04 +02:00
|
|
|
|
if (TREE_CODE (elt) != FIELD_DECL)
|
1998-11-18 03:21:54 +01:00
|
|
|
|
{
|
|
|
|
|
cp_pedwarn_at ("`%#D' invalid; an anonymous union can only have non-static data members",
|
1999-07-09 18:15:04 +02:00
|
|
|
|
elt);
|
1998-11-18 03:21:54 +01:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
1999-07-09 18:15:04 +02:00
|
|
|
|
if (TREE_PRIVATE (elt))
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_pedwarn_at ("private member `%#D' in anonymous union",
|
1999-07-09 18:15:04 +02:00
|
|
|
|
elt);
|
|
|
|
|
else if (TREE_PROTECTED (elt))
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_pedwarn_at ("protected member `%#D' in anonymous union",
|
1999-07-09 18:15:04 +02:00
|
|
|
|
elt);
|
1996-03-21 20:46:11 +01:00
|
|
|
|
|
1999-07-09 18:15:04 +02:00
|
|
|
|
TREE_PRIVATE (elt) = TREE_PRIVATE (field);
|
|
|
|
|
TREE_PROTECTED (elt) = TREE_PROTECTED (field);
|
1996-02-01 20:32:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
extern int interface_only, interface_unknown;
|
|
|
|
|
|
1998-10-06 16:20:30 +02:00
|
|
|
|
/* Create default constructors, assignment operators, and so forth for
|
|
|
|
|
the type indicated by T, if they are needed.
|
|
|
|
|
CANT_HAVE_DEFAULT_CTOR, CANT_HAVE_CONST_CTOR, and
|
|
|
|
|
CANT_HAVE_ASSIGNMENT are nonzero if, for whatever reason, the class
|
|
|
|
|
cannot have a default constructor, copy constructor taking a const
|
|
|
|
|
reference argument, or an assignment operator, respectively. If a
|
|
|
|
|
virtual destructor is created, its DECL is returned; otherwise the
|
|
|
|
|
return value is NULL_TREE. */
|
|
|
|
|
|
|
|
|
|
static tree
|
|
|
|
|
add_implicitly_declared_members (t, cant_have_default_ctor,
|
|
|
|
|
cant_have_const_cctor,
|
|
|
|
|
cant_have_assignment)
|
|
|
|
|
tree t;
|
|
|
|
|
int cant_have_default_ctor;
|
|
|
|
|
int cant_have_const_cctor;
|
|
|
|
|
int cant_have_assignment;
|
|
|
|
|
{
|
|
|
|
|
tree default_fn;
|
|
|
|
|
tree implicit_fns = NULL_TREE;
|
|
|
|
|
tree name = TYPE_IDENTIFIER (t);
|
|
|
|
|
tree virtual_dtor = NULL_TREE;
|
|
|
|
|
tree *f;
|
|
|
|
|
|
|
|
|
|
/* Destructor. */
|
extend.texi (C++ Signatures): Remove node.
* extend.texi (C++ Signatures): Remove node.
* invoke.texi: Remove discussion of -fhandle-signatures,
signature, sigof, __signature__, and __sigof__.
* Make-lang.in (CXX_SRCS): Remove sig.c.
* Makefile.in (CXX_OBJS): Remove sig.o.
(sig.o): Remove.
* cp-tree.h (CPTI_OPAQUE_TYPE): Remove.
(CPTI_SIGNATURE_TYPE): Likewise.
(CPTI_SIGTABLE_ENTRY_TYPE): Likewise.
(opaque_type_node): Likewise.
(signature_type_node): Likewise.
(sigtable_entry_type): Likewise.
(flag_handle_signatures): Likewise.
(lang_type): Remove is_signature, is_signature_pointer,
is_signature_reference, has_opaque_typedecls,
sigtables_has_been_generated. Adjust dummy. Remove signature,
signature_pointer_to, signature_reference_to.
(IS_SIGNATURE): Remove.
(SET_SIGNATURE): Remove.
(CLEAR_SIGNATURE): Remove.
(IS_SIGNATURE_POINTER): Remove.
(IS_SIGNATURE_REFERENCE): Remove.
(SIGNATURE_HAS_OPAQUE_TYPEDECLS): Remove.
(SIGTABLE_HAS_BEEN_GENERATED): Remove.
(CLASSTYPE_SIGNATURE): Remove.
(SIGNATURE_TYPE): Remove.
(SIGNATURE_METHOD_VEC): Remove.
(SIGNATURE_POINTER_TO): Remove.
(SIGNATURE_REFERENCE_TO): Remove.
(lang_decl_flags): Remove is_default_implementation. Rename
memfunc_pointer_to to saved_tree.
(IS_DEFAULT_IMPLEMENTATION): Remove.
(DECL_MEMFUNC_POINTER_TO): Remove.
(DECL_MEMFUNC_POINTING_TO): Remove.
(DECL_SAVED_TREE): Adjust definition.
(tag_types): Remove signature_type_node.
(SIGNATURE_FIELD_NAME): Remove.
(SIGNATURE_FIELD_NAME_FORMAT): Likewise.
(SIGNATURE_OPTR_NAME): Likewise.
(SIGNATURE_SPTR_NAME): Likewise.
(SIGNATURE_POINTER_NAME): Likewise.
(SIGNATURE_POINTER_NAME_FORMAT): Likewise.
(SIGNATURE_REFERENCE_NAME): Likewise.
(SIGNATURE_REFERNECE_NAME_FORMAT): Likewise.
(SIGTABLE_PTR_TYPE): Likewise.
(SIGTABLE_NAME_FORMAT): Likewise.
(SIGTABLE_NAME_FORMAT_LONG): Likewise.
(SIGTABLE_TAG_NAME): Likewise.
(SIGTABLE_VB_OFF_NAME): Likewise.
(SIGTABLE_VT_OFF_NAME): Likewise.
(finish_base_specifiers): Change prototype.
(build_signature_pointer_type): Remove.
(build_signature_reference_type): Remove.
(build_signature_pointer_constructor): Remove.
(build_signature_method_call): Remove.
(build_optr_ref): Likewise.
(append_signature_fields): Likewise.
(signature_error): Likewise.
* call.c (build_this): Remove signature support.
(build_over_call): Likewise.
(build_new_method_call): Likewise.
* class.c (add_implicitly_declared_members): Likewise.
(finish_struct_1): Likewise.
(finish_struct): Likewise.
* cvt.c (cp_convert_to_pointer): Likewise.
(convert_to_pointer_force): Likewise.
(ocp_convert): Likewise.
* decl.c (sigtable_decl_p): Remove.
(init_decl_processing): Remove support for signatures.
(cp_finish_decl): Likewise.
(grokdeclarator): Likewise.
(grokparms): Likewise.
(xref_tag): Likewise.
(start_function): Likewise.
(start_method): Likewise.
* decl2.c (finish_sigtable_vardecl): Remove.
(flag_handle_signatures): Remove.
(lang_f_options): Remove handle-signatures.
(grokfield): Remove support for signatures.
(grokbitfield): Likewise.
(finish_file): Likewise.
(reparse_absdcl_as_casts): Likewise.
* error.c (dump_type_real): Likewise.
(dump_function_decl): Likewise.
* friend.c (make_friend_class): Likewise.
* gxx.gperf: Remove __signature__, signature, __sigof__, sigof.
* hash.h: Regenerated.
* init.c (build_new_1): Remove support for signatures.
* lang-options.h: Remove -fhandle-signatures,
-fno-handle-signatures.
* lex.c (init_parse): Remove support for signatures.
(yyprint): Likewise.
* lex.h (rid): Remove RID_SIGNATURE.
* method.c (build_decl_overload_real): Remove support for
signatures.
(hack_identifier): Likewise.
* parse.y (base_class): Likewise.
(base_class.1): Likewise.
(access_specifier): Likewise.
* search.c (lookup_member): Likewise.
* semantics.c (finish_qualified_object_call_expr): Likewise.
(finish_template_type_parm): Likewise.
(begin_class_definition): Likewise.
(finish_base_specifier): Likewise.
* sig.c: Remove.
* tree.c (build_cplus_method_type): Remove support for signatures.
* typeck.c (require_complete_type): Likewise.
(c_sizeof): Likewise.
(c_alignof): Likewise.
(build_object_ref): Likewise.
(build_component_ref): Likewise.
(build_indirect_ref): Likewise.
(build_c_cast): Likewise.
(build_modify_expr): Likewise.
(convert_for_initialization): Likewise.
* typeck2.c (signature_error): Remove.
(store_init_value): Remove support for signatures.
(digest_init): Likewise.
(build_x_arrow): Likewise.
(build_functional_cast): Likewise.
* xref.c (GNU_xref_decl): Likewise.
From-SVN: r28677
1999-08-11 22:22:41 +02:00
|
|
|
|
if (TYPE_NEEDS_DESTRUCTOR (t) && !TYPE_HAS_DESTRUCTOR (t))
|
1998-10-06 16:20:30 +02:00
|
|
|
|
{
|
|
|
|
|
default_fn = cons_up_default_function (t, name, 0);
|
|
|
|
|
check_for_override (default_fn, t);
|
|
|
|
|
|
|
|
|
|
/* If we couldn't make it work, then pretend we didn't need it. */
|
|
|
|
|
if (default_fn == void_type_node)
|
|
|
|
|
TYPE_NEEDS_DESTRUCTOR (t) = 0;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TREE_CHAIN (default_fn) = implicit_fns;
|
|
|
|
|
implicit_fns = default_fn;
|
|
|
|
|
|
|
|
|
|
if (DECL_VINDEX (default_fn))
|
|
|
|
|
virtual_dtor = default_fn;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t);
|
|
|
|
|
|
|
|
|
|
/* Default constructor. */
|
extend.texi (C++ Signatures): Remove node.
* extend.texi (C++ Signatures): Remove node.
* invoke.texi: Remove discussion of -fhandle-signatures,
signature, sigof, __signature__, and __sigof__.
* Make-lang.in (CXX_SRCS): Remove sig.c.
* Makefile.in (CXX_OBJS): Remove sig.o.
(sig.o): Remove.
* cp-tree.h (CPTI_OPAQUE_TYPE): Remove.
(CPTI_SIGNATURE_TYPE): Likewise.
(CPTI_SIGTABLE_ENTRY_TYPE): Likewise.
(opaque_type_node): Likewise.
(signature_type_node): Likewise.
(sigtable_entry_type): Likewise.
(flag_handle_signatures): Likewise.
(lang_type): Remove is_signature, is_signature_pointer,
is_signature_reference, has_opaque_typedecls,
sigtables_has_been_generated. Adjust dummy. Remove signature,
signature_pointer_to, signature_reference_to.
(IS_SIGNATURE): Remove.
(SET_SIGNATURE): Remove.
(CLEAR_SIGNATURE): Remove.
(IS_SIGNATURE_POINTER): Remove.
(IS_SIGNATURE_REFERENCE): Remove.
(SIGNATURE_HAS_OPAQUE_TYPEDECLS): Remove.
(SIGTABLE_HAS_BEEN_GENERATED): Remove.
(CLASSTYPE_SIGNATURE): Remove.
(SIGNATURE_TYPE): Remove.
(SIGNATURE_METHOD_VEC): Remove.
(SIGNATURE_POINTER_TO): Remove.
(SIGNATURE_REFERENCE_TO): Remove.
(lang_decl_flags): Remove is_default_implementation. Rename
memfunc_pointer_to to saved_tree.
(IS_DEFAULT_IMPLEMENTATION): Remove.
(DECL_MEMFUNC_POINTER_TO): Remove.
(DECL_MEMFUNC_POINTING_TO): Remove.
(DECL_SAVED_TREE): Adjust definition.
(tag_types): Remove signature_type_node.
(SIGNATURE_FIELD_NAME): Remove.
(SIGNATURE_FIELD_NAME_FORMAT): Likewise.
(SIGNATURE_OPTR_NAME): Likewise.
(SIGNATURE_SPTR_NAME): Likewise.
(SIGNATURE_POINTER_NAME): Likewise.
(SIGNATURE_POINTER_NAME_FORMAT): Likewise.
(SIGNATURE_REFERENCE_NAME): Likewise.
(SIGNATURE_REFERNECE_NAME_FORMAT): Likewise.
(SIGTABLE_PTR_TYPE): Likewise.
(SIGTABLE_NAME_FORMAT): Likewise.
(SIGTABLE_NAME_FORMAT_LONG): Likewise.
(SIGTABLE_TAG_NAME): Likewise.
(SIGTABLE_VB_OFF_NAME): Likewise.
(SIGTABLE_VT_OFF_NAME): Likewise.
(finish_base_specifiers): Change prototype.
(build_signature_pointer_type): Remove.
(build_signature_reference_type): Remove.
(build_signature_pointer_constructor): Remove.
(build_signature_method_call): Remove.
(build_optr_ref): Likewise.
(append_signature_fields): Likewise.
(signature_error): Likewise.
* call.c (build_this): Remove signature support.
(build_over_call): Likewise.
(build_new_method_call): Likewise.
* class.c (add_implicitly_declared_members): Likewise.
(finish_struct_1): Likewise.
(finish_struct): Likewise.
* cvt.c (cp_convert_to_pointer): Likewise.
(convert_to_pointer_force): Likewise.
(ocp_convert): Likewise.
* decl.c (sigtable_decl_p): Remove.
(init_decl_processing): Remove support for signatures.
(cp_finish_decl): Likewise.
(grokdeclarator): Likewise.
(grokparms): Likewise.
(xref_tag): Likewise.
(start_function): Likewise.
(start_method): Likewise.
* decl2.c (finish_sigtable_vardecl): Remove.
(flag_handle_signatures): Remove.
(lang_f_options): Remove handle-signatures.
(grokfield): Remove support for signatures.
(grokbitfield): Likewise.
(finish_file): Likewise.
(reparse_absdcl_as_casts): Likewise.
* error.c (dump_type_real): Likewise.
(dump_function_decl): Likewise.
* friend.c (make_friend_class): Likewise.
* gxx.gperf: Remove __signature__, signature, __sigof__, sigof.
* hash.h: Regenerated.
* init.c (build_new_1): Remove support for signatures.
* lang-options.h: Remove -fhandle-signatures,
-fno-handle-signatures.
* lex.c (init_parse): Remove support for signatures.
(yyprint): Likewise.
* lex.h (rid): Remove RID_SIGNATURE.
* method.c (build_decl_overload_real): Remove support for
signatures.
(hack_identifier): Likewise.
* parse.y (base_class): Likewise.
(base_class.1): Likewise.
(access_specifier): Likewise.
* search.c (lookup_member): Likewise.
* semantics.c (finish_qualified_object_call_expr): Likewise.
(finish_template_type_parm): Likewise.
(begin_class_definition): Likewise.
(finish_base_specifier): Likewise.
* sig.c: Remove.
* tree.c (build_cplus_method_type): Remove support for signatures.
* typeck.c (require_complete_type): Likewise.
(c_sizeof): Likewise.
(c_alignof): Likewise.
(build_object_ref): Likewise.
(build_component_ref): Likewise.
(build_indirect_ref): Likewise.
(build_c_cast): Likewise.
(build_modify_expr): Likewise.
(convert_for_initialization): Likewise.
* typeck2.c (signature_error): Remove.
(store_init_value): Remove support for signatures.
(digest_init): Likewise.
(build_x_arrow): Likewise.
(build_functional_cast): Likewise.
* xref.c (GNU_xref_decl): Likewise.
From-SVN: r28677
1999-08-11 22:22:41 +02:00
|
|
|
|
if (! TYPE_HAS_CONSTRUCTOR (t) && ! cant_have_default_ctor)
|
1998-10-06 16:20:30 +02:00
|
|
|
|
{
|
|
|
|
|
default_fn = cons_up_default_function (t, name, 2);
|
|
|
|
|
TREE_CHAIN (default_fn) = implicit_fns;
|
|
|
|
|
implicit_fns = default_fn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Copy constructor. */
|
extend.texi (C++ Signatures): Remove node.
* extend.texi (C++ Signatures): Remove node.
* invoke.texi: Remove discussion of -fhandle-signatures,
signature, sigof, __signature__, and __sigof__.
* Make-lang.in (CXX_SRCS): Remove sig.c.
* Makefile.in (CXX_OBJS): Remove sig.o.
(sig.o): Remove.
* cp-tree.h (CPTI_OPAQUE_TYPE): Remove.
(CPTI_SIGNATURE_TYPE): Likewise.
(CPTI_SIGTABLE_ENTRY_TYPE): Likewise.
(opaque_type_node): Likewise.
(signature_type_node): Likewise.
(sigtable_entry_type): Likewise.
(flag_handle_signatures): Likewise.
(lang_type): Remove is_signature, is_signature_pointer,
is_signature_reference, has_opaque_typedecls,
sigtables_has_been_generated. Adjust dummy. Remove signature,
signature_pointer_to, signature_reference_to.
(IS_SIGNATURE): Remove.
(SET_SIGNATURE): Remove.
(CLEAR_SIGNATURE): Remove.
(IS_SIGNATURE_POINTER): Remove.
(IS_SIGNATURE_REFERENCE): Remove.
(SIGNATURE_HAS_OPAQUE_TYPEDECLS): Remove.
(SIGTABLE_HAS_BEEN_GENERATED): Remove.
(CLASSTYPE_SIGNATURE): Remove.
(SIGNATURE_TYPE): Remove.
(SIGNATURE_METHOD_VEC): Remove.
(SIGNATURE_POINTER_TO): Remove.
(SIGNATURE_REFERENCE_TO): Remove.
(lang_decl_flags): Remove is_default_implementation. Rename
memfunc_pointer_to to saved_tree.
(IS_DEFAULT_IMPLEMENTATION): Remove.
(DECL_MEMFUNC_POINTER_TO): Remove.
(DECL_MEMFUNC_POINTING_TO): Remove.
(DECL_SAVED_TREE): Adjust definition.
(tag_types): Remove signature_type_node.
(SIGNATURE_FIELD_NAME): Remove.
(SIGNATURE_FIELD_NAME_FORMAT): Likewise.
(SIGNATURE_OPTR_NAME): Likewise.
(SIGNATURE_SPTR_NAME): Likewise.
(SIGNATURE_POINTER_NAME): Likewise.
(SIGNATURE_POINTER_NAME_FORMAT): Likewise.
(SIGNATURE_REFERENCE_NAME): Likewise.
(SIGNATURE_REFERNECE_NAME_FORMAT): Likewise.
(SIGTABLE_PTR_TYPE): Likewise.
(SIGTABLE_NAME_FORMAT): Likewise.
(SIGTABLE_NAME_FORMAT_LONG): Likewise.
(SIGTABLE_TAG_NAME): Likewise.
(SIGTABLE_VB_OFF_NAME): Likewise.
(SIGTABLE_VT_OFF_NAME): Likewise.
(finish_base_specifiers): Change prototype.
(build_signature_pointer_type): Remove.
(build_signature_reference_type): Remove.
(build_signature_pointer_constructor): Remove.
(build_signature_method_call): Remove.
(build_optr_ref): Likewise.
(append_signature_fields): Likewise.
(signature_error): Likewise.
* call.c (build_this): Remove signature support.
(build_over_call): Likewise.
(build_new_method_call): Likewise.
* class.c (add_implicitly_declared_members): Likewise.
(finish_struct_1): Likewise.
(finish_struct): Likewise.
* cvt.c (cp_convert_to_pointer): Likewise.
(convert_to_pointer_force): Likewise.
(ocp_convert): Likewise.
* decl.c (sigtable_decl_p): Remove.
(init_decl_processing): Remove support for signatures.
(cp_finish_decl): Likewise.
(grokdeclarator): Likewise.
(grokparms): Likewise.
(xref_tag): Likewise.
(start_function): Likewise.
(start_method): Likewise.
* decl2.c (finish_sigtable_vardecl): Remove.
(flag_handle_signatures): Remove.
(lang_f_options): Remove handle-signatures.
(grokfield): Remove support for signatures.
(grokbitfield): Likewise.
(finish_file): Likewise.
(reparse_absdcl_as_casts): Likewise.
* error.c (dump_type_real): Likewise.
(dump_function_decl): Likewise.
* friend.c (make_friend_class): Likewise.
* gxx.gperf: Remove __signature__, signature, __sigof__, sigof.
* hash.h: Regenerated.
* init.c (build_new_1): Remove support for signatures.
* lang-options.h: Remove -fhandle-signatures,
-fno-handle-signatures.
* lex.c (init_parse): Remove support for signatures.
(yyprint): Likewise.
* lex.h (rid): Remove RID_SIGNATURE.
* method.c (build_decl_overload_real): Remove support for
signatures.
(hack_identifier): Likewise.
* parse.y (base_class): Likewise.
(base_class.1): Likewise.
(access_specifier): Likewise.
* search.c (lookup_member): Likewise.
* semantics.c (finish_qualified_object_call_expr): Likewise.
(finish_template_type_parm): Likewise.
(begin_class_definition): Likewise.
(finish_base_specifier): Likewise.
* sig.c: Remove.
* tree.c (build_cplus_method_type): Remove support for signatures.
* typeck.c (require_complete_type): Likewise.
(c_sizeof): Likewise.
(c_alignof): Likewise.
(build_object_ref): Likewise.
(build_component_ref): Likewise.
(build_indirect_ref): Likewise.
(build_c_cast): Likewise.
(build_modify_expr): Likewise.
(convert_for_initialization): Likewise.
* typeck2.c (signature_error): Remove.
(store_init_value): Remove support for signatures.
(digest_init): Likewise.
(build_x_arrow): Likewise.
(build_functional_cast): Likewise.
* xref.c (GNU_xref_decl): Likewise.
From-SVN: r28677
1999-08-11 22:22:41 +02:00
|
|
|
|
if (! TYPE_HAS_INIT_REF (t) && ! TYPE_FOR_JAVA (t))
|
1998-10-06 16:20:30 +02:00
|
|
|
|
{
|
|
|
|
|
/* ARM 12.18: You get either X(X&) or X(const X&), but
|
|
|
|
|
not both. --Chip */
|
|
|
|
|
default_fn = cons_up_default_function (t, name,
|
|
|
|
|
3 + cant_have_const_cctor);
|
|
|
|
|
TREE_CHAIN (default_fn) = implicit_fns;
|
|
|
|
|
implicit_fns = default_fn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Assignment operator. */
|
extend.texi (C++ Signatures): Remove node.
* extend.texi (C++ Signatures): Remove node.
* invoke.texi: Remove discussion of -fhandle-signatures,
signature, sigof, __signature__, and __sigof__.
* Make-lang.in (CXX_SRCS): Remove sig.c.
* Makefile.in (CXX_OBJS): Remove sig.o.
(sig.o): Remove.
* cp-tree.h (CPTI_OPAQUE_TYPE): Remove.
(CPTI_SIGNATURE_TYPE): Likewise.
(CPTI_SIGTABLE_ENTRY_TYPE): Likewise.
(opaque_type_node): Likewise.
(signature_type_node): Likewise.
(sigtable_entry_type): Likewise.
(flag_handle_signatures): Likewise.
(lang_type): Remove is_signature, is_signature_pointer,
is_signature_reference, has_opaque_typedecls,
sigtables_has_been_generated. Adjust dummy. Remove signature,
signature_pointer_to, signature_reference_to.
(IS_SIGNATURE): Remove.
(SET_SIGNATURE): Remove.
(CLEAR_SIGNATURE): Remove.
(IS_SIGNATURE_POINTER): Remove.
(IS_SIGNATURE_REFERENCE): Remove.
(SIGNATURE_HAS_OPAQUE_TYPEDECLS): Remove.
(SIGTABLE_HAS_BEEN_GENERATED): Remove.
(CLASSTYPE_SIGNATURE): Remove.
(SIGNATURE_TYPE): Remove.
(SIGNATURE_METHOD_VEC): Remove.
(SIGNATURE_POINTER_TO): Remove.
(SIGNATURE_REFERENCE_TO): Remove.
(lang_decl_flags): Remove is_default_implementation. Rename
memfunc_pointer_to to saved_tree.
(IS_DEFAULT_IMPLEMENTATION): Remove.
(DECL_MEMFUNC_POINTER_TO): Remove.
(DECL_MEMFUNC_POINTING_TO): Remove.
(DECL_SAVED_TREE): Adjust definition.
(tag_types): Remove signature_type_node.
(SIGNATURE_FIELD_NAME): Remove.
(SIGNATURE_FIELD_NAME_FORMAT): Likewise.
(SIGNATURE_OPTR_NAME): Likewise.
(SIGNATURE_SPTR_NAME): Likewise.
(SIGNATURE_POINTER_NAME): Likewise.
(SIGNATURE_POINTER_NAME_FORMAT): Likewise.
(SIGNATURE_REFERENCE_NAME): Likewise.
(SIGNATURE_REFERNECE_NAME_FORMAT): Likewise.
(SIGTABLE_PTR_TYPE): Likewise.
(SIGTABLE_NAME_FORMAT): Likewise.
(SIGTABLE_NAME_FORMAT_LONG): Likewise.
(SIGTABLE_TAG_NAME): Likewise.
(SIGTABLE_VB_OFF_NAME): Likewise.
(SIGTABLE_VT_OFF_NAME): Likewise.
(finish_base_specifiers): Change prototype.
(build_signature_pointer_type): Remove.
(build_signature_reference_type): Remove.
(build_signature_pointer_constructor): Remove.
(build_signature_method_call): Remove.
(build_optr_ref): Likewise.
(append_signature_fields): Likewise.
(signature_error): Likewise.
* call.c (build_this): Remove signature support.
(build_over_call): Likewise.
(build_new_method_call): Likewise.
* class.c (add_implicitly_declared_members): Likewise.
(finish_struct_1): Likewise.
(finish_struct): Likewise.
* cvt.c (cp_convert_to_pointer): Likewise.
(convert_to_pointer_force): Likewise.
(ocp_convert): Likewise.
* decl.c (sigtable_decl_p): Remove.
(init_decl_processing): Remove support for signatures.
(cp_finish_decl): Likewise.
(grokdeclarator): Likewise.
(grokparms): Likewise.
(xref_tag): Likewise.
(start_function): Likewise.
(start_method): Likewise.
* decl2.c (finish_sigtable_vardecl): Remove.
(flag_handle_signatures): Remove.
(lang_f_options): Remove handle-signatures.
(grokfield): Remove support for signatures.
(grokbitfield): Likewise.
(finish_file): Likewise.
(reparse_absdcl_as_casts): Likewise.
* error.c (dump_type_real): Likewise.
(dump_function_decl): Likewise.
* friend.c (make_friend_class): Likewise.
* gxx.gperf: Remove __signature__, signature, __sigof__, sigof.
* hash.h: Regenerated.
* init.c (build_new_1): Remove support for signatures.
* lang-options.h: Remove -fhandle-signatures,
-fno-handle-signatures.
* lex.c (init_parse): Remove support for signatures.
(yyprint): Likewise.
* lex.h (rid): Remove RID_SIGNATURE.
* method.c (build_decl_overload_real): Remove support for
signatures.
(hack_identifier): Likewise.
* parse.y (base_class): Likewise.
(base_class.1): Likewise.
(access_specifier): Likewise.
* search.c (lookup_member): Likewise.
* semantics.c (finish_qualified_object_call_expr): Likewise.
(finish_template_type_parm): Likewise.
(begin_class_definition): Likewise.
(finish_base_specifier): Likewise.
* sig.c: Remove.
* tree.c (build_cplus_method_type): Remove support for signatures.
* typeck.c (require_complete_type): Likewise.
(c_sizeof): Likewise.
(c_alignof): Likewise.
(build_object_ref): Likewise.
(build_component_ref): Likewise.
(build_indirect_ref): Likewise.
(build_c_cast): Likewise.
(build_modify_expr): Likewise.
(convert_for_initialization): Likewise.
* typeck2.c (signature_error): Remove.
(store_init_value): Remove support for signatures.
(digest_init): Likewise.
(build_x_arrow): Likewise.
(build_functional_cast): Likewise.
* xref.c (GNU_xref_decl): Likewise.
From-SVN: r28677
1999-08-11 22:22:41 +02:00
|
|
|
|
if (! TYPE_HAS_ASSIGN_REF (t) && ! TYPE_FOR_JAVA (t))
|
1998-10-06 16:20:30 +02:00
|
|
|
|
{
|
|
|
|
|
default_fn = cons_up_default_function (t, name,
|
|
|
|
|
5 + cant_have_assignment);
|
|
|
|
|
TREE_CHAIN (default_fn) = implicit_fns;
|
|
|
|
|
implicit_fns = default_fn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now, hook all of the new functions on to TYPE_METHODS,
|
|
|
|
|
and add them to the CLASSTYPE_METHOD_VEC. */
|
|
|
|
|
for (f = &implicit_fns; *f; f = &TREE_CHAIN (*f))
|
|
|
|
|
add_method (t, 0, *f);
|
|
|
|
|
*f = TYPE_METHODS (t);
|
|
|
|
|
TYPE_METHODS (t) = implicit_fns;
|
|
|
|
|
|
|
|
|
|
return virtual_dtor;
|
|
|
|
|
}
|
|
|
|
|
|
1999-07-09 18:15:04 +02:00
|
|
|
|
/* Subroutine of finish_struct_1. Recursively count the number of fields
|
|
|
|
|
in TYPE, including anonymous union members. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
count_fields (fields)
|
|
|
|
|
tree fields;
|
|
|
|
|
{
|
|
|
|
|
tree x;
|
|
|
|
|
int n_fields = 0;
|
|
|
|
|
for (x = fields; x; x = TREE_CHAIN (x))
|
|
|
|
|
{
|
|
|
|
|
if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
|
|
|
|
|
n_fields += count_fields (TYPE_FIELDS (TREE_TYPE (x)));
|
|
|
|
|
else
|
|
|
|
|
n_fields += 1;
|
|
|
|
|
}
|
|
|
|
|
return n_fields;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Subroutine of finish_struct_1. Recursively add all the fields in the
|
|
|
|
|
TREE_LIST FIELDS to the TREE_VEC FIELD_VEC, starting at offset IDX. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
add_fields_to_vec (fields, field_vec, idx)
|
|
|
|
|
tree fields, field_vec;
|
|
|
|
|
int idx;
|
|
|
|
|
{
|
|
|
|
|
tree x;
|
|
|
|
|
for (x = fields; x; x = TREE_CHAIN (x))
|
|
|
|
|
{
|
|
|
|
|
if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
|
|
|
|
|
idx = add_fields_to_vec (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx);
|
|
|
|
|
else
|
|
|
|
|
TREE_VEC_ELT (field_vec, idx++) = x;
|
|
|
|
|
}
|
|
|
|
|
return idx;
|
|
|
|
|
}
|
|
|
|
|
|
1999-11-03 22:34:04 +01:00
|
|
|
|
/* FIELD is a bit-field. We are finishing the processing for its
|
|
|
|
|
enclosing type. Issue any appropriate messages and set appropriate
|
|
|
|
|
flags. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
check_bitfield_decl (field)
|
|
|
|
|
tree field;
|
|
|
|
|
{
|
|
|
|
|
tree type = TREE_TYPE (field);
|
|
|
|
|
|
|
|
|
|
/* Invalid bit-field size done by grokfield. */
|
|
|
|
|
/* Detect invalid bit-field type. Simply checking if TYPE is
|
|
|
|
|
integral is insufficient, as that is the array core of the field
|
|
|
|
|
type. If TREE_TYPE (field) is integral, then TYPE must be the same. */
|
|
|
|
|
if (DECL_INITIAL (field)
|
|
|
|
|
&& ! INTEGRAL_TYPE_P (TREE_TYPE (field)))
|
|
|
|
|
{
|
|
|
|
|
cp_error_at ("bit-field `%#D' with non-integral type", field);
|
|
|
|
|
DECL_INITIAL (field) = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Detect and ignore out of range field width. */
|
|
|
|
|
if (DECL_INITIAL (field))
|
|
|
|
|
{
|
|
|
|
|
tree w = DECL_INITIAL (field);
|
|
|
|
|
register int width = 0;
|
|
|
|
|
|
|
|
|
|
/* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs. */
|
|
|
|
|
STRIP_NOPS (w);
|
|
|
|
|
|
|
|
|
|
/* detect invalid field size. */
|
|
|
|
|
if (TREE_CODE (w) == CONST_DECL)
|
|
|
|
|
w = DECL_INITIAL (w);
|
|
|
|
|
else if (TREE_READONLY_DECL_P (w))
|
|
|
|
|
w = decl_constant_value (w);
|
|
|
|
|
|
|
|
|
|
if (TREE_CODE (w) != INTEGER_CST)
|
|
|
|
|
{
|
|
|
|
|
cp_error_at ("bit-field `%D' width not an integer constant",
|
|
|
|
|
field);
|
|
|
|
|
DECL_INITIAL (field) = NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
else if (width = TREE_INT_CST_LOW (w),
|
|
|
|
|
width < 0)
|
|
|
|
|
{
|
|
|
|
|
DECL_INITIAL (field) = NULL;
|
|
|
|
|
cp_error_at ("negative width in bit-field `%D'", field);
|
|
|
|
|
}
|
|
|
|
|
else if (width == 0 && DECL_NAME (field) != 0)
|
|
|
|
|
{
|
|
|
|
|
DECL_INITIAL (field) = NULL;
|
|
|
|
|
cp_error_at ("zero width for bit-field `%D'", field);
|
|
|
|
|
}
|
|
|
|
|
else if (width
|
|
|
|
|
> TYPE_PRECISION (long_long_unsigned_type_node))
|
|
|
|
|
{
|
|
|
|
|
/* The backend will dump if you try to use something too
|
|
|
|
|
big; avoid that. */
|
|
|
|
|
DECL_INITIAL (field) = NULL;
|
|
|
|
|
sorry ("bit-fields larger than %d bits",
|
|
|
|
|
TYPE_PRECISION (long_long_unsigned_type_node));
|
|
|
|
|
cp_error_at (" in declaration of `%D'", field);
|
|
|
|
|
}
|
|
|
|
|
else if (width > TYPE_PRECISION (type)
|
|
|
|
|
&& TREE_CODE (type) != ENUMERAL_TYPE
|
|
|
|
|
&& TREE_CODE (type) != BOOLEAN_TYPE)
|
|
|
|
|
cp_warning_at ("width of `%D' exceeds its type", field);
|
|
|
|
|
else if (TREE_CODE (type) == ENUMERAL_TYPE
|
|
|
|
|
&& ((min_precision (TYPE_MIN_VALUE (type),
|
|
|
|
|
TREE_UNSIGNED (type)) > width)
|
|
|
|
|
|| (min_precision (TYPE_MAX_VALUE (type),
|
|
|
|
|
TREE_UNSIGNED (type)) > width)))
|
|
|
|
|
cp_warning_at ("`%D' is too small to hold all values of `%#T'",
|
|
|
|
|
field, type);
|
|
|
|
|
|
|
|
|
|
if (DECL_INITIAL (field))
|
|
|
|
|
{
|
|
|
|
|
DECL_INITIAL (field) = NULL_TREE;
|
|
|
|
|
DECL_FIELD_SIZE (field) = width;
|
|
|
|
|
DECL_BIT_FIELD (field) = 1;
|
|
|
|
|
|
|
|
|
|
if (width == 0)
|
|
|
|
|
{
|
|
|
|
|
#ifdef EMPTY_FIELD_BOUNDARY
|
|
|
|
|
DECL_ALIGN (field) = MAX (DECL_ALIGN (field),
|
|
|
|
|
EMPTY_FIELD_BOUNDARY);
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef PCC_BITFIELD_TYPE_MATTERS
|
|
|
|
|
if (PCC_BITFIELD_TYPE_MATTERS)
|
|
|
|
|
DECL_ALIGN (field) = MAX (DECL_ALIGN (field),
|
|
|
|
|
TYPE_ALIGN (type));
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
/* Non-bit-fields are aligned for their type. */
|
|
|
|
|
DECL_ALIGN (field) = MAX (DECL_ALIGN (field), TYPE_ALIGN (type));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* FIELD is a non bit-field. We are finishing the processing for its
|
|
|
|
|
enclosing type T. Issue any appropriate messages and set appropriate
|
|
|
|
|
flags. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
check_field_decl (field, t, cant_have_const_ctor,
|
|
|
|
|
cant_have_default_ctor, no_const_asn_ref,
|
|
|
|
|
any_default_members)
|
|
|
|
|
tree field;
|
|
|
|
|
tree t;
|
|
|
|
|
int *cant_have_const_ctor;
|
|
|
|
|
int *cant_have_default_ctor;
|
|
|
|
|
int *no_const_asn_ref;
|
|
|
|
|
int *any_default_members;
|
|
|
|
|
{
|
|
|
|
|
tree type = strip_array_types (TREE_TYPE (field));
|
|
|
|
|
|
|
|
|
|
/* An anonymous union cannot contain any fields which would change
|
|
|
|
|
the settings of CANT_HAVE_CONST_CTOR and friends. */
|
|
|
|
|
if (ANON_UNION_TYPE_P (type))
|
|
|
|
|
;
|
|
|
|
|
/* And, we don't set TYPE_HAS_CONST_INIT_REF, etc., for anonymous
|
|
|
|
|
structs. So, we recurse through their fields here. */
|
|
|
|
|
else if (ANON_AGGR_TYPE_P (type))
|
|
|
|
|
{
|
|
|
|
|
tree fields;
|
|
|
|
|
|
|
|
|
|
for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
|
|
|
|
|
if (TREE_CODE (field) == FIELD_DECL && !DECL_C_BIT_FIELD (field))
|
|
|
|
|
check_field_decl (fields, t, cant_have_const_ctor,
|
|
|
|
|
cant_have_default_ctor, no_const_asn_ref,
|
|
|
|
|
any_default_members);
|
|
|
|
|
}
|
|
|
|
|
/* Check members with class type for constructors, destructors,
|
|
|
|
|
etc. */
|
|
|
|
|
else if (CLASS_TYPE_P (type))
|
|
|
|
|
{
|
|
|
|
|
/* Never let anything with uninheritable virtuals
|
|
|
|
|
make it through without complaint. */
|
|
|
|
|
abstract_virtuals_error (field, type);
|
|
|
|
|
|
|
|
|
|
if (TREE_CODE (t) == UNION_TYPE)
|
|
|
|
|
{
|
|
|
|
|
if (TYPE_NEEDS_CONSTRUCTING (type))
|
|
|
|
|
cp_error_at ("member `%#D' with constructor not allowed in union",
|
|
|
|
|
field);
|
|
|
|
|
if (TYPE_NEEDS_DESTRUCTOR (type))
|
|
|
|
|
cp_error_at ("member `%#D' with destructor not allowed in union",
|
|
|
|
|
field);
|
|
|
|
|
if (TYPE_HAS_COMPLEX_ASSIGN_REF (type))
|
|
|
|
|
cp_error_at ("member `%#D' with copy assignment operator not allowed in union",
|
|
|
|
|
field);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (type);
|
|
|
|
|
TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (type);
|
|
|
|
|
TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (type);
|
|
|
|
|
TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!TYPE_HAS_CONST_INIT_REF (type))
|
|
|
|
|
*cant_have_const_ctor = 1;
|
|
|
|
|
|
|
|
|
|
if (!TYPE_HAS_CONST_ASSIGN_REF (type))
|
|
|
|
|
*no_const_asn_ref = 1;
|
|
|
|
|
|
|
|
|
|
if (TYPE_HAS_CONSTRUCTOR (type)
|
|
|
|
|
&& ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
|
|
|
|
|
*cant_have_default_ctor = 1;
|
|
|
|
|
}
|
|
|
|
|
if (DECL_INITIAL (field) != NULL_TREE)
|
|
|
|
|
{
|
|
|
|
|
/* `build_class_init_list' does not recognize
|
|
|
|
|
non-FIELD_DECLs. */
|
|
|
|
|
if (TREE_CODE (t) == UNION_TYPE && any_default_members != 0)
|
|
|
|
|
cp_error_at ("multiple fields in union `%T' initialized");
|
|
|
|
|
*any_default_members = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Non-bit-fields are aligned for their type, except packed fields
|
|
|
|
|
which require only BITS_PER_UNIT alignment. */
|
|
|
|
|
DECL_ALIGN (field) = MAX (DECL_ALIGN (field),
|
|
|
|
|
(DECL_PACKED (field)
|
|
|
|
|
? BITS_PER_UNIT
|
|
|
|
|
: TYPE_ALIGN (TREE_TYPE (field))));
|
2000-01-13 01:35:38 +01:00
|
|
|
|
}
|
1999-11-03 22:34:04 +01:00
|
|
|
|
|
1999-12-15 01:36:57 +01:00
|
|
|
|
/* Check the data members (both static and non-static), class-scoped
|
|
|
|
|
typedefs, etc., appearing in the declaration of T. Issue
|
|
|
|
|
appropriate diagnostics. Sets ACCESS_DECLS to a list (in
|
|
|
|
|
declaration order) of access declarations; each TREE_VALUE in this
|
|
|
|
|
list is a USING_DECL.
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-15 01:36:57 +01:00
|
|
|
|
In addition, set the following flags:
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-15 01:36:57 +01:00
|
|
|
|
EMPTY_P
|
|
|
|
|
The class is empty, i.e., contains no non-static data members.
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-15 01:36:57 +01:00
|
|
|
|
CANT_HAVE_DEFAULT_CTOR_P
|
|
|
|
|
This class cannot have an implicitly generated default
|
|
|
|
|
constructor.
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-15 01:36:57 +01:00
|
|
|
|
CANT_HAVE_CONST_CTOR_P
|
|
|
|
|
This class cannot have an implicitly generated copy constructor
|
|
|
|
|
taking a const reference.
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-15 01:36:57 +01:00
|
|
|
|
CANT_HAVE_CONST_ASN_REF
|
|
|
|
|
This class cannot have an implicitly generated assignment
|
|
|
|
|
operator taking a const reference.
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-15 01:36:57 +01:00
|
|
|
|
All of these flags should be initialized before calling this
|
|
|
|
|
function.
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-15 01:36:57 +01:00
|
|
|
|
Returns a pointer to the end of the TYPE_FIELDs chain; additional
|
|
|
|
|
fields can be added by adding to this chain. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
static void
|
1999-12-15 01:36:57 +01:00
|
|
|
|
check_field_decls (t, access_decls, empty_p,
|
|
|
|
|
cant_have_default_ctor_p, cant_have_const_ctor_p,
|
|
|
|
|
no_const_asn_ref_p)
|
|
|
|
|
tree t;
|
|
|
|
|
tree *access_decls;
|
|
|
|
|
int *empty_p;
|
|
|
|
|
int *cant_have_default_ctor_p;
|
|
|
|
|
int *cant_have_const_ctor_p;
|
|
|
|
|
int *no_const_asn_ref_p;
|
|
|
|
|
{
|
|
|
|
|
tree *field;
|
|
|
|
|
tree *next;
|
|
|
|
|
int has_pointers;
|
|
|
|
|
int any_default_members;
|
|
|
|
|
|
1999-12-16 04:10:12 +01:00
|
|
|
|
/* First, delete any duplicate fields. */
|
|
|
|
|
delete_duplicate_fields (TYPE_FIELDS (t));
|
|
|
|
|
|
1999-12-15 01:36:57 +01:00
|
|
|
|
/* Assume there are no access declarations. */
|
|
|
|
|
*access_decls = NULL_TREE;
|
|
|
|
|
/* Assume this class has no pointer members. */
|
|
|
|
|
has_pointers = 0;
|
|
|
|
|
/* Assume none of the members of this class have default
|
|
|
|
|
initializations. */
|
|
|
|
|
any_default_members = 0;
|
|
|
|
|
|
|
|
|
|
for (field = &TYPE_FIELDS (t); *field; field = next)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1999-12-15 01:36:57 +01:00
|
|
|
|
tree x = *field;
|
|
|
|
|
tree type = TREE_TYPE (x);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
GNU_xref_member (current_class_name, x);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-12-15 01:36:57 +01:00
|
|
|
|
next = &TREE_CHAIN (x);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1996-04-02 23:44:27 +02:00
|
|
|
|
if (TREE_CODE (x) == FIELD_DECL)
|
1996-10-31 18:08:58 +01:00
|
|
|
|
{
|
|
|
|
|
DECL_PACKED (x) |= TYPE_PACKED (t);
|
1998-11-24 00:57:32 +01:00
|
|
|
|
|
|
|
|
|
if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
|
1999-12-15 01:36:57 +01:00
|
|
|
|
/* We don't treat zero-width bitfields as making a class
|
|
|
|
|
non-empty. */
|
|
|
|
|
;
|
1998-11-24 00:57:32 +01:00
|
|
|
|
else
|
1999-12-29 09:28:50 +01:00
|
|
|
|
{
|
|
|
|
|
/* The class is non-empty. */
|
|
|
|
|
*empty_p = 0;
|
|
|
|
|
/* The class is not even nearly empty. */
|
|
|
|
|
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
|
|
|
|
|
}
|
1996-10-31 18:08:58 +01:00
|
|
|
|
}
|
1996-04-02 23:44:27 +02:00
|
|
|
|
|
1996-02-20 21:35:10 +01:00
|
|
|
|
if (TREE_CODE (x) == USING_DECL)
|
1995-10-12 03:33:51 +01:00
|
|
|
|
{
|
1999-12-15 01:36:57 +01:00
|
|
|
|
/* Prune the access declaration from the list of fields. */
|
|
|
|
|
*field = TREE_CHAIN (x);
|
|
|
|
|
|
|
|
|
|
/* Save the access declarations for our caller. */
|
|
|
|
|
*access_decls = tree_cons (NULL_TREE, x, *access_decls);
|
|
|
|
|
|
|
|
|
|
/* Since we've reset *FIELD there's no reason to skip to the
|
|
|
|
|
next field. */
|
|
|
|
|
next = field;
|
1995-10-12 03:33:51 +01:00
|
|
|
|
continue;
|
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1998-03-24 11:25:44 +01:00
|
|
|
|
if (TREE_CODE (x) == TYPE_DECL
|
|
|
|
|
|| TREE_CODE (x) == TEMPLATE_DECL)
|
1995-10-12 03:33:51 +01:00
|
|
|
|
continue;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
/* If we've gotten this far, it's a data member, possibly static,
|
1996-07-11 03:13:25 +02:00
|
|
|
|
or an enumerator. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
DECL_FIELD_CONTEXT (x) = t;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
/* ``A local class cannot have static data members.'' ARM 9.4 */
|
|
|
|
|
if (current_function_decl && TREE_STATIC (x))
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_error_at ("field `%D' in local class cannot be static", x);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
/* Perform error checking that did not get done in
|
|
|
|
|
grokdeclarator. */
|
1999-08-03 17:04:49 +02:00
|
|
|
|
if (TREE_CODE (type) == FUNCTION_TYPE)
|
1995-10-12 03:33:51 +01:00
|
|
|
|
{
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_error_at ("field `%D' invalidly declared function type",
|
1995-10-12 03:33:51 +01:00
|
|
|
|
x);
|
1999-08-03 17:04:49 +02:00
|
|
|
|
type = build_pointer_type (type);
|
|
|
|
|
TREE_TYPE (x) = type;
|
1995-10-12 03:33:51 +01:00
|
|
|
|
}
|
1999-08-03 17:04:49 +02:00
|
|
|
|
else if (TREE_CODE (type) == METHOD_TYPE)
|
1995-10-12 03:33:51 +01:00
|
|
|
|
{
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_error_at ("field `%D' invalidly declared method type", x);
|
1999-08-03 17:04:49 +02:00
|
|
|
|
type = build_pointer_type (type);
|
|
|
|
|
TREE_TYPE (x) = type;
|
1995-10-12 03:33:51 +01:00
|
|
|
|
}
|
1999-08-03 17:04:49 +02:00
|
|
|
|
else if (TREE_CODE (type) == OFFSET_TYPE)
|
1995-10-12 03:33:51 +01:00
|
|
|
|
{
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_error_at ("field `%D' invalidly declared offset type", x);
|
1999-08-03 17:04:49 +02:00
|
|
|
|
type = build_pointer_type (type);
|
|
|
|
|
TREE_TYPE (x) = type;
|
1995-10-12 03:33:51 +01:00
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-08-03 17:04:49 +02:00
|
|
|
|
if (type == error_mark_node)
|
1995-10-12 03:33:51 +01:00
|
|
|
|
continue;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-08-09 16:00:21 +02:00
|
|
|
|
DECL_SAVED_INSNS (x) = 0;
|
1995-10-12 03:33:51 +01:00
|
|
|
|
DECL_FIELD_SIZE (x) = 0;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
/* When this goes into scope, it will be a non-local reference. */
|
|
|
|
|
DECL_NONLOCAL (x) = 1;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
if (TREE_CODE (x) == CONST_DECL)
|
|
|
|
|
continue;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
if (TREE_CODE (x) == VAR_DECL)
|
|
|
|
|
{
|
|
|
|
|
if (TREE_CODE (t) == UNION_TYPE)
|
|
|
|
|
/* Unions cannot have static members. */
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_error_at ("field `%D' declared static in union", x);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
continue;
|
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
/* Now it can only be a FIELD_DECL. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
|
1999-12-15 01:36:57 +01:00
|
|
|
|
CLASSTYPE_NON_AGGREGATE (t) = 1;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
/* If this is of reference type, check if it needs an init.
|
|
|
|
|
Also do a little ANSI jig if necessary. */
|
1999-08-03 17:04:49 +02:00
|
|
|
|
if (TREE_CODE (type) == REFERENCE_TYPE)
|
1995-10-12 03:33:51 +01:00
|
|
|
|
{
|
1999-12-15 01:36:57 +01:00
|
|
|
|
CLASSTYPE_NON_POD_P (t) = 1;
|
1995-10-12 03:33:51 +01:00
|
|
|
|
if (DECL_INITIAL (x) == NULL_TREE)
|
1999-12-15 01:36:57 +01:00
|
|
|
|
CLASSTYPE_REF_FIELDS_NEED_INIT (t) = 1;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
/* ARM $12.6.2: [A member initializer list] (or, for an
|
|
|
|
|
aggregate, initialization by a brace-enclosed list) is the
|
|
|
|
|
only way to initialize nonstatic const and reference
|
|
|
|
|
members. */
|
1999-12-15 01:36:57 +01:00
|
|
|
|
*cant_have_default_ctor_p = 1;
|
1996-05-30 21:11:58 +02:00
|
|
|
|
TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
|
1995-10-12 03:33:51 +01:00
|
|
|
|
|
|
|
|
|
if (! TYPE_HAS_CONSTRUCTOR (t) && extra_warnings)
|
|
|
|
|
{
|
|
|
|
|
if (DECL_NAME (x))
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_warning_at ("non-static reference `%#D' in class without a constructor", x);
|
1995-10-12 03:33:51 +01:00
|
|
|
|
else
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_warning_at ("non-static reference in class without a constructor", x);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
1995-10-12 03:33:51 +01:00
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-11-03 22:34:04 +01:00
|
|
|
|
type = strip_array_types (type);
|
1999-08-03 17:04:49 +02:00
|
|
|
|
|
|
|
|
|
if (TREE_CODE (type) == POINTER_TYPE)
|
1997-02-04 03:31:49 +01:00
|
|
|
|
has_pointers = 1;
|
|
|
|
|
|
1999-08-03 17:04:49 +02:00
|
|
|
|
if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
|
1999-12-15 01:36:57 +01:00
|
|
|
|
CLASSTYPE_HAS_MUTABLE (t) = 1;
|
1999-01-16 17:31:12 +01:00
|
|
|
|
|
1999-11-02 08:26:47 +01:00
|
|
|
|
if (! pod_type_p (type)
|
|
|
|
|
/* For some reason, pointers to members are POD types themselves,
|
|
|
|
|
but are not allowed in POD structs. Silly. */
|
|
|
|
|
|| TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type))
|
1999-12-15 01:36:57 +01:00
|
|
|
|
CLASSTYPE_NON_POD_P (t) = 1;
|
1999-08-03 17:04:49 +02:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
/* If any field is const, the structure type is pseudo-const. */
|
1999-08-03 17:04:49 +02:00
|
|
|
|
if (CP_TYPE_CONST_P (type))
|
1995-10-12 03:33:51 +01:00
|
|
|
|
{
|
|
|
|
|
C_TYPE_FIELDS_READONLY (t) = 1;
|
|
|
|
|
if (DECL_INITIAL (x) == NULL_TREE)
|
1999-12-15 01:36:57 +01:00
|
|
|
|
CLASSTYPE_READONLY_FIELDS_NEED_INIT (t) = 1;
|
1995-10-12 03:33:51 +01:00
|
|
|
|
|
|
|
|
|
/* ARM $12.6.2: [A member initializer list] (or, for an
|
|
|
|
|
aggregate, initialization by a brace-enclosed list) is the
|
|
|
|
|
only way to initialize nonstatic const and reference
|
|
|
|
|
members. */
|
1999-12-15 01:36:57 +01:00
|
|
|
|
*cant_have_default_ctor_p = 1;
|
1996-05-30 21:11:58 +02:00
|
|
|
|
TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
|
1995-10-12 03:33:51 +01:00
|
|
|
|
|
extend.texi (C++ Signatures): Remove node.
* extend.texi (C++ Signatures): Remove node.
* invoke.texi: Remove discussion of -fhandle-signatures,
signature, sigof, __signature__, and __sigof__.
* Make-lang.in (CXX_SRCS): Remove sig.c.
* Makefile.in (CXX_OBJS): Remove sig.o.
(sig.o): Remove.
* cp-tree.h (CPTI_OPAQUE_TYPE): Remove.
(CPTI_SIGNATURE_TYPE): Likewise.
(CPTI_SIGTABLE_ENTRY_TYPE): Likewise.
(opaque_type_node): Likewise.
(signature_type_node): Likewise.
(sigtable_entry_type): Likewise.
(flag_handle_signatures): Likewise.
(lang_type): Remove is_signature, is_signature_pointer,
is_signature_reference, has_opaque_typedecls,
sigtables_has_been_generated. Adjust dummy. Remove signature,
signature_pointer_to, signature_reference_to.
(IS_SIGNATURE): Remove.
(SET_SIGNATURE): Remove.
(CLEAR_SIGNATURE): Remove.
(IS_SIGNATURE_POINTER): Remove.
(IS_SIGNATURE_REFERENCE): Remove.
(SIGNATURE_HAS_OPAQUE_TYPEDECLS): Remove.
(SIGTABLE_HAS_BEEN_GENERATED): Remove.
(CLASSTYPE_SIGNATURE): Remove.
(SIGNATURE_TYPE): Remove.
(SIGNATURE_METHOD_VEC): Remove.
(SIGNATURE_POINTER_TO): Remove.
(SIGNATURE_REFERENCE_TO): Remove.
(lang_decl_flags): Remove is_default_implementation. Rename
memfunc_pointer_to to saved_tree.
(IS_DEFAULT_IMPLEMENTATION): Remove.
(DECL_MEMFUNC_POINTER_TO): Remove.
(DECL_MEMFUNC_POINTING_TO): Remove.
(DECL_SAVED_TREE): Adjust definition.
(tag_types): Remove signature_type_node.
(SIGNATURE_FIELD_NAME): Remove.
(SIGNATURE_FIELD_NAME_FORMAT): Likewise.
(SIGNATURE_OPTR_NAME): Likewise.
(SIGNATURE_SPTR_NAME): Likewise.
(SIGNATURE_POINTER_NAME): Likewise.
(SIGNATURE_POINTER_NAME_FORMAT): Likewise.
(SIGNATURE_REFERENCE_NAME): Likewise.
(SIGNATURE_REFERNECE_NAME_FORMAT): Likewise.
(SIGTABLE_PTR_TYPE): Likewise.
(SIGTABLE_NAME_FORMAT): Likewise.
(SIGTABLE_NAME_FORMAT_LONG): Likewise.
(SIGTABLE_TAG_NAME): Likewise.
(SIGTABLE_VB_OFF_NAME): Likewise.
(SIGTABLE_VT_OFF_NAME): Likewise.
(finish_base_specifiers): Change prototype.
(build_signature_pointer_type): Remove.
(build_signature_reference_type): Remove.
(build_signature_pointer_constructor): Remove.
(build_signature_method_call): Remove.
(build_optr_ref): Likewise.
(append_signature_fields): Likewise.
(signature_error): Likewise.
* call.c (build_this): Remove signature support.
(build_over_call): Likewise.
(build_new_method_call): Likewise.
* class.c (add_implicitly_declared_members): Likewise.
(finish_struct_1): Likewise.
(finish_struct): Likewise.
* cvt.c (cp_convert_to_pointer): Likewise.
(convert_to_pointer_force): Likewise.
(ocp_convert): Likewise.
* decl.c (sigtable_decl_p): Remove.
(init_decl_processing): Remove support for signatures.
(cp_finish_decl): Likewise.
(grokdeclarator): Likewise.
(grokparms): Likewise.
(xref_tag): Likewise.
(start_function): Likewise.
(start_method): Likewise.
* decl2.c (finish_sigtable_vardecl): Remove.
(flag_handle_signatures): Remove.
(lang_f_options): Remove handle-signatures.
(grokfield): Remove support for signatures.
(grokbitfield): Likewise.
(finish_file): Likewise.
(reparse_absdcl_as_casts): Likewise.
* error.c (dump_type_real): Likewise.
(dump_function_decl): Likewise.
* friend.c (make_friend_class): Likewise.
* gxx.gperf: Remove __signature__, signature, __sigof__, sigof.
* hash.h: Regenerated.
* init.c (build_new_1): Remove support for signatures.
* lang-options.h: Remove -fhandle-signatures,
-fno-handle-signatures.
* lex.c (init_parse): Remove support for signatures.
(yyprint): Likewise.
* lex.h (rid): Remove RID_SIGNATURE.
* method.c (build_decl_overload_real): Remove support for
signatures.
(hack_identifier): Likewise.
* parse.y (base_class): Likewise.
(base_class.1): Likewise.
(access_specifier): Likewise.
* search.c (lookup_member): Likewise.
* semantics.c (finish_qualified_object_call_expr): Likewise.
(finish_template_type_parm): Likewise.
(begin_class_definition): Likewise.
(finish_base_specifier): Likewise.
* sig.c: Remove.
* tree.c (build_cplus_method_type): Remove support for signatures.
* typeck.c (require_complete_type): Likewise.
(c_sizeof): Likewise.
(c_alignof): Likewise.
(build_object_ref): Likewise.
(build_component_ref): Likewise.
(build_indirect_ref): Likewise.
(build_c_cast): Likewise.
(build_modify_expr): Likewise.
(convert_for_initialization): Likewise.
* typeck2.c (signature_error): Remove.
(store_init_value): Remove support for signatures.
(digest_init): Likewise.
(build_x_arrow): Likewise.
(build_functional_cast): Likewise.
* xref.c (GNU_xref_decl): Likewise.
From-SVN: r28677
1999-08-11 22:22:41 +02:00
|
|
|
|
if (! TYPE_HAS_CONSTRUCTOR (t) && extra_warnings)
|
1995-10-12 03:33:51 +01:00
|
|
|
|
{
|
|
|
|
|
if (DECL_NAME (x))
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_warning_at ("non-static const member `%#D' in class without a constructor", x);
|
1995-10-12 03:33:51 +01:00
|
|
|
|
else
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_warning_at ("non-static const member in class without a constructor", x);
|
1995-10-12 03:33:51 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
1999-12-15 01:36:57 +01:00
|
|
|
|
/* A field that is pseudo-const makes the structure likewise. */
|
|
|
|
|
else if (IS_AGGR_TYPE (type))
|
1995-10-12 03:33:51 +01:00
|
|
|
|
{
|
1999-12-15 01:36:57 +01:00
|
|
|
|
C_TYPE_FIELDS_READONLY (t) |= C_TYPE_FIELDS_READONLY (type);
|
|
|
|
|
CLASSTYPE_READONLY_FIELDS_NEED_INIT (t)
|
|
|
|
|
|= CLASSTYPE_READONLY_FIELDS_NEED_INIT (type);
|
1995-10-12 03:33:51 +01:00
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1998-10-16 05:37:43 +02:00
|
|
|
|
/* We set DECL_C_BIT_FIELD in grokbitfield.
|
|
|
|
|
If the type and width are valid, we'll also set DECL_BIT_FIELD. */
|
|
|
|
|
if (DECL_C_BIT_FIELD (x))
|
1999-11-03 22:34:04 +01:00
|
|
|
|
check_bitfield_decl (x);
|
1995-10-12 03:33:51 +01:00
|
|
|
|
else
|
1999-11-03 22:34:04 +01:00
|
|
|
|
check_field_decl (x, t,
|
1999-12-15 01:36:57 +01:00
|
|
|
|
cant_have_const_ctor_p,
|
|
|
|
|
cant_have_default_ctor_p,
|
|
|
|
|
no_const_asn_ref_p,
|
1999-11-03 22:34:04 +01:00
|
|
|
|
&any_default_members);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
1997-02-04 03:31:49 +01:00
|
|
|
|
/* Effective C++ rule 11. */
|
1997-07-08 02:17:49 +02:00
|
|
|
|
if (has_pointers && warn_ecpp && TYPE_HAS_CONSTRUCTOR (t)
|
1997-02-04 03:31:49 +01:00
|
|
|
|
&& ! (TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
|
|
|
|
|
{
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_warning ("`%#T' has pointer data members", t);
|
1997-02-04 03:31:49 +01:00
|
|
|
|
|
|
|
|
|
if (! TYPE_HAS_INIT_REF (t))
|
|
|
|
|
{
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_warning (" but does not override `%T(const %T&)'", t, t);
|
1997-02-04 03:31:49 +01:00
|
|
|
|
if (! TYPE_HAS_ASSIGN_REF (t))
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_warning (" or `operator=(const %T&)'", t);
|
1997-02-04 03:31:49 +01:00
|
|
|
|
}
|
|
|
|
|
else if (! TYPE_HAS_ASSIGN_REF (t))
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_warning (" but does not override `operator=(const %T&)'", t);
|
1997-02-04 03:31:49 +01:00
|
|
|
|
}
|
1999-12-15 01:36:57 +01:00
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
|
|
|
|
|
/* Check anonymous struct/anonymous union fields. */
|
|
|
|
|
finish_struct_anon (t);
|
|
|
|
|
|
1999-12-15 01:36:57 +01:00
|
|
|
|
/* We've built up the list of access declarations in reverse order.
|
|
|
|
|
Fix that now. */
|
|
|
|
|
*access_decls = nreverse (*access_decls);
|
|
|
|
|
}
|
|
|
|
|
|
1999-12-16 04:10:12 +01:00
|
|
|
|
/* Return a FIELD_DECL for a pointer-to-virtual-table or
|
|
|
|
|
pointer-to-virtual-base. The NAME, ASSEMBLER_NAME, and TYPE of the
|
|
|
|
|
field are as indicated. The CLASS_TYPE in which this field occurs
|
2000-02-01 03:17:06 +01:00
|
|
|
|
is also indicated. FCONTEXT is the type that is needed for the debug
|
|
|
|
|
info output routines. *EMPTY_P is set to a non-zero value by this
|
1999-12-16 04:10:12 +01:00
|
|
|
|
function to indicate that a class containing this field is
|
|
|
|
|
non-empty. */
|
|
|
|
|
|
|
|
|
|
static tree
|
2000-02-01 03:17:06 +01:00
|
|
|
|
build_vtbl_or_vbase_field (name, assembler_name, type, class_type, fcontext,
|
1999-12-16 04:10:12 +01:00
|
|
|
|
empty_p)
|
|
|
|
|
tree name;
|
|
|
|
|
tree assembler_name;
|
|
|
|
|
tree type;
|
|
|
|
|
tree class_type;
|
2000-02-01 03:17:06 +01:00
|
|
|
|
tree fcontext;
|
1999-12-16 04:10:12 +01:00
|
|
|
|
int *empty_p;
|
|
|
|
|
{
|
|
|
|
|
tree field;
|
|
|
|
|
|
|
|
|
|
/* This class is non-empty. */
|
|
|
|
|
*empty_p = 0;
|
|
|
|
|
|
|
|
|
|
/* Build the FIELD_DECL. */
|
|
|
|
|
field = build_lang_decl (FIELD_DECL, name, type);
|
|
|
|
|
DECL_ASSEMBLER_NAME (field) = assembler_name;
|
|
|
|
|
DECL_VIRTUAL_P (field) = 1;
|
|
|
|
|
DECL_ARTIFICIAL (field) = 1;
|
|
|
|
|
DECL_FIELD_CONTEXT (field) = class_type;
|
2000-02-01 03:17:06 +01:00
|
|
|
|
DECL_FCONTEXT (field) = fcontext;
|
1999-12-16 04:10:12 +01:00
|
|
|
|
DECL_SAVED_INSNS (field) = 0;
|
|
|
|
|
DECL_FIELD_SIZE (field) = 0;
|
|
|
|
|
DECL_ALIGN (field) = TYPE_ALIGN (type);
|
|
|
|
|
|
|
|
|
|
/* Return it. */
|
|
|
|
|
return field;
|
|
|
|
|
}
|
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
/* If the empty base field in DECL overlaps with a base of the same type in
|
|
|
|
|
NEWDECL, which is either another base field or the first data field of
|
|
|
|
|
the class, pad the base just before NEWDECL and return 1. Otherwise,
|
|
|
|
|
return 0. */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
avoid_overlap (decl, newdecl, empty_p)
|
|
|
|
|
tree decl, newdecl;
|
|
|
|
|
int *empty_p;
|
|
|
|
|
{
|
|
|
|
|
tree field;
|
|
|
|
|
|
|
|
|
|
if (newdecl == NULL_TREE
|
|
|
|
|
|| ! types_overlap_p (TREE_TYPE (decl), TREE_TYPE (newdecl)))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
for (field = decl; TREE_CHAIN (field) && TREE_CHAIN (field) != newdecl;
|
|
|
|
|
field = TREE_CHAIN (field))
|
|
|
|
|
;
|
|
|
|
|
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
DECL_SIZE (field) = bitsize_int (1);
|
|
|
|
|
DECL_SIZE_UNIT (field) = 0;
|
1999-12-16 23:18:22 +01:00
|
|
|
|
/* The containing class cannot be empty; this field takes up space. */
|
|
|
|
|
*empty_p = 0;
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-11 04:15:32 +01:00
|
|
|
|
/* Build a FIELD_DECL for the base given by BINFO in T. If the new
|
|
|
|
|
object is non-empty, clear *EMPTY_P. Otherwise, set *SAW_EMPTY_P.
|
|
|
|
|
*BASE_ALIGN is a running maximum of the alignments of any base
|
|
|
|
|
class. */
|
|
|
|
|
|
|
|
|
|
static tree
|
|
|
|
|
build_base_field (t, binfo, empty_p, saw_empty_p, base_align)
|
|
|
|
|
tree t;
|
|
|
|
|
tree binfo;
|
|
|
|
|
int *empty_p;
|
|
|
|
|
int *saw_empty_p;
|
|
|
|
|
unsigned int *base_align;
|
|
|
|
|
{
|
|
|
|
|
tree basetype = BINFO_TYPE (binfo);
|
|
|
|
|
tree decl;
|
|
|
|
|
|
|
|
|
|
if (TYPE_SIZE (basetype) == 0)
|
|
|
|
|
/* This error is now reported in xref_tag, thus giving better
|
|
|
|
|
location information. */
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
|
|
|
|
|
decl = build_lang_decl (FIELD_DECL, NULL_TREE, basetype);
|
|
|
|
|
DECL_ARTIFICIAL (decl) = 1;
|
Make DECL_CONTEXT mean the class in which a member function was declared, even for a virtual function.
Make DECL_CONTEXT mean the class in which a member function was
declared, even for a virtual function.
* cp-tree.h (DECL_CLASS_CONTEXT): Adjust.
(DECL_FRIEND_CONTEXT): New macro.
(DECL_REAL_CONTEXT): Remove.
(SET_DECL_FRIEND_CONTEXT): Likewise.
(DECL_VIRTUAL_CONTEXT): Adjust.
(DECL_CLASS_SCOPE_P): Use TYPE_P.
(add_friends): Remove.
(hack_decl_function_context): Likewise.
* call.c (build_new_function_call): Replace DECL_REAL_CONTEXT with
CP_DECL_CONTEXT.
(build_over_call): Fix indentation. Use DECL_CONTEXT
instead of DECL_CLASS_CONTEXT.
* class.c (dfs_build_vcall_offset_vtbl_entries): Likewise.
(add_method): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT.
(strictly_overrides): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
(build_vtbl_or_vbase_field): Don't set DECL_CLASS_CONTEXT.
(build_base_field): Likewise.
(finish_struct_1): Likewise.
(build_self_reference): Likewise.
* decl.c (push_class_binding): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(pushtag): Use decl_function_context, not
hack_decl_function_context.
(decls_match): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
(duplicate_decls): Use DECL_VIRTUAL_CONTEXT.
(pushdecl): Remove bogus code.
(start_decl): Use DECL_CONTEXT rather than DECL_CLASS_CONTEXT.
(cp_finish_decl): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
(grokfndecl): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
Use decl_function_context, nothack_decl_function_context.
(grokvardecl): Don't set DECL_CLASS_CONTEXT.
(grokdeclarator): Likewise. Use decl_function_context, not
hack_decl_function_context.
(copy_args_p): Document. Don't use DECL_CLASS_CONTEXT.
(start_function): Use DECL_FRIEND_CONTEXT, not
DECL_CLASS_CONTEXT. Use decl_function_context, not
hack_decl_function_context.
(finish_function): Use decl_function_context, not
hack_decl_function_context.
(maybe_retrofit_in_chrg): Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
(grokclassfn): Set DECL_VIRTUAL_CONTEXT, not DECL_CONTEXT.
(finish_static_data_member_decl): Don't set DECL_CLASS_CONTEXT.
(grokfield): Likewise.
(finish_builtin_type): Likewise.
(finish_vtable_vardec): Use decl_function_context, not
hack_decl_function_context.
(import_export_decl): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
(start_static_initialization_or_destruction): Likewise.
(finish_static_initialization_or_destruction): Likewise.
(mark_used): Adjust logic for deciding when to synthesize methods.
* dump.c (dequeue_and_dump): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
* error.c (dump_function_decl): Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
* friend.c (is_friend): Likewise.
(add_friends): Remove.
(do_friend): Use SET_DECL_FRIEND_CONTEXT.
* lex.c (begin_definition_of_inclass_inline): Use
decl_function_context, not hack_decl_function_context.
(process_next_inline): Likewise.
(do_identifier): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
* method.c (set_mangled_name_for_decl): Use DECL_CONTEXT, not
DECL_CLASSS_CONTEXT.
(hack_identifier): Likewise.
(synthesize_method): Use decl_function_context, not
hack_decl_function_context.
* pt.c (template_class_depth_real): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(is_member_template): Use decl_function_context, not
hack_decl_function_context. Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
(build_template_decl): Set DECL_VIRTUAL_CONTEXT, not
DECL_CLASS_CONTEXT.
(check_default_tmpl_args): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(push_template_decl_real): Likewise.
(instantiate_class_template): Don't call add_friends.
(tsubst_default_argument): Use DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(tsubst_decl): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT.
Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
(set_meangled_name_for_template_decl): Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
* repo.c (repo_inline_used): Likewise.
* search.c (current_scope): Adjust for new _CONTEXT macros.
(context_for_name_lookup): Use CP_DECL_CONTEXT, not
DECL_REAL_CONTEXT.
(friend_accessible_p): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
(lookup_fnfields_here):Likewise.
(check_final_overrider): Likewise.
(init_vbase_pointers): Likewise.
(virtual_context): Likewise.
* semantics.c (finish_member_declaration): Just set DECL_CONTEXT.
(expand_body): Use decl_function_context, not
hack_decl_function_context.
* tree.c (hack_decl_function_context): Remove.
* typeck.c (build_x_function_call): Use DECL_CONTEXT, not
DECL_CLASS_CONTEXT.
* typeck2.c (error_not_base_type): Likewise.
From-SVN: r32018
2000-02-17 00:54:23 +01:00
|
|
|
|
DECL_FIELD_CONTEXT (decl) = t;
|
2000-01-11 04:15:32 +01:00
|
|
|
|
DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
|
2000-01-11 04:15:32 +01:00
|
|
|
|
DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
|
|
|
|
|
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
if (flag_new_abi && integer_zerop (DECL_SIZE (decl)))
|
2000-01-11 04:15:32 +01:00
|
|
|
|
{
|
|
|
|
|
*saw_empty_p = 1;
|
|
|
|
|
return decl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The containing class is non-empty because it has a non-empty base
|
|
|
|
|
class. */
|
|
|
|
|
*empty_p = 0;
|
|
|
|
|
|
|
|
|
|
if (! flag_new_abi)
|
|
|
|
|
{
|
|
|
|
|
/* Brain damage for backwards compatibility. For no good
|
|
|
|
|
reason, the old layout_basetypes made every base at least
|
|
|
|
|
as large as the alignment for the bases up to that point,
|
|
|
|
|
gratuitously wasting space. So we do the same thing
|
|
|
|
|
here. */
|
|
|
|
|
*base_align = MAX (*base_align, DECL_ALIGN (decl));
|
|
|
|
|
DECL_SIZE (decl)
|
|
|
|
|
= size_int (MAX (TREE_INT_CST_LOW (DECL_SIZE (decl)),
|
|
|
|
|
(int) (*base_align)));
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
DECL_SIZE_UNIT (decl)
|
|
|
|
|
= size_int (MAX (TREE_INT_CST_LOW (DECL_SIZE_UNIT (decl)),
|
|
|
|
|
(int) *base_align / BITS_PER_UNIT));
|
2000-01-11 04:15:32 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return decl;
|
|
|
|
|
}
|
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
/* Returns a list of fields to stand in for the base class subobjects
|
|
|
|
|
of REC. These fields are later removed by layout_basetypes. */
|
|
|
|
|
|
|
|
|
|
static tree
|
|
|
|
|
build_base_fields (rec, empty_p)
|
|
|
|
|
tree rec;
|
|
|
|
|
int *empty_p;
|
|
|
|
|
{
|
|
|
|
|
/* Chain to hold all the new FIELD_DECLs which stand in for base class
|
|
|
|
|
subobjects. */
|
|
|
|
|
tree base_decls = NULL_TREE;
|
|
|
|
|
int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec);
|
|
|
|
|
tree decl, nextdecl;
|
|
|
|
|
int i, saw_empty = 0;
|
|
|
|
|
unsigned int base_align = 0;
|
|
|
|
|
|
2000-01-11 04:15:32 +01:00
|
|
|
|
/* Under the new ABI, the primary base class is always allocated
|
|
|
|
|
first. */
|
|
|
|
|
if (flag_new_abi && CLASSTYPE_HAS_PRIMARY_BASE_P (rec))
|
|
|
|
|
{
|
|
|
|
|
tree primary_base;
|
|
|
|
|
|
|
|
|
|
primary_base = CLASSTYPE_PRIMARY_BINFO (rec);
|
|
|
|
|
base_decls = chainon (build_base_field (rec,
|
|
|
|
|
primary_base,
|
|
|
|
|
empty_p,
|
|
|
|
|
&saw_empty,
|
|
|
|
|
&base_align),
|
|
|
|
|
base_decls);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now allocate the rest of the bases. */
|
1999-12-16 23:18:22 +01:00
|
|
|
|
for (i = 0; i < n_baseclasses; ++i)
|
|
|
|
|
{
|
2000-01-11 04:15:32 +01:00
|
|
|
|
tree base_binfo;
|
1999-12-16 23:18:22 +01:00
|
|
|
|
|
2000-01-11 04:15:32 +01:00
|
|
|
|
/* Under the new ABI, the primary base was already allocated
|
|
|
|
|
above, so we don't need to allocate it again here. */
|
|
|
|
|
if (flag_new_abi && i == CLASSTYPE_VFIELD_PARENT (rec))
|
1999-12-16 23:18:22 +01:00
|
|
|
|
continue;
|
|
|
|
|
|
2000-01-11 04:15:32 +01:00
|
|
|
|
base_binfo = BINFO_BASETYPE (TYPE_BINFO (rec), i);
|
|
|
|
|
|
2000-01-03 07:56:21 +01:00
|
|
|
|
/* A primary virtual base class is allocated just like any other
|
|
|
|
|
base class, but a non-primary virtual base is allocated
|
|
|
|
|
later, in layout_basetypes. */
|
|
|
|
|
if (TREE_VIA_VIRTUAL (base_binfo)
|
2000-01-11 04:15:32 +01:00
|
|
|
|
&& !BINFO_PRIMARY_MARKED_P (base_binfo))
|
1999-12-16 23:18:22 +01:00
|
|
|
|
continue;
|
|
|
|
|
|
2000-01-11 04:15:32 +01:00
|
|
|
|
base_decls = chainon (build_base_field (rec, base_binfo,
|
|
|
|
|
empty_p,
|
|
|
|
|
&saw_empty,
|
|
|
|
|
&base_align),
|
|
|
|
|
base_decls);
|
1999-12-16 23:18:22 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Reverse the list of fields so we allocate the bases in the proper
|
|
|
|
|
order. */
|
|
|
|
|
base_decls = nreverse (base_decls);
|
|
|
|
|
|
|
|
|
|
/* In the presence of empty base classes, we run the risk of allocating
|
|
|
|
|
two objects of the same class on top of one another. Avoid that. */
|
|
|
|
|
if (flag_new_abi && saw_empty)
|
|
|
|
|
for (decl = base_decls; decl; decl = TREE_CHAIN (decl))
|
|
|
|
|
{
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
if (integer_zerop (DECL_SIZE (decl)))
|
1999-12-16 23:18:22 +01:00
|
|
|
|
{
|
|
|
|
|
/* First step through the following bases until we find
|
|
|
|
|
an overlap or a non-empty base. */
|
|
|
|
|
for (nextdecl = TREE_CHAIN (decl); nextdecl;
|
|
|
|
|
nextdecl = TREE_CHAIN (nextdecl))
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
if (avoid_overlap (decl, nextdecl, empty_p)
|
|
|
|
|
|| ! integer_zerop (DECL_SIZE (nextdecl)))
|
|
|
|
|
goto nextbase;
|
1999-12-16 23:18:22 +01:00
|
|
|
|
|
|
|
|
|
/* If we're still looking, also check against the first
|
|
|
|
|
field. */
|
|
|
|
|
for (nextdecl = TYPE_FIELDS (rec);
|
|
|
|
|
nextdecl && TREE_CODE (nextdecl) != FIELD_DECL;
|
|
|
|
|
nextdecl = TREE_CHAIN (nextdecl))
|
|
|
|
|
/* keep looking */;
|
|
|
|
|
avoid_overlap (decl, nextdecl, empty_p);
|
|
|
|
|
}
|
|
|
|
|
nextbase:;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return base_decls;
|
|
|
|
|
}
|
|
|
|
|
|
1999-12-16 04:10:12 +01:00
|
|
|
|
/* Go through the TYPE_METHODS of T issuing any appropriate
|
|
|
|
|
diagnostics, figuring out which methods override which other
|
1999-12-21 03:11:10 +01:00
|
|
|
|
methods, and so forth. */
|
1999-12-16 04:10:12 +01:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
check_methods (t)
|
|
|
|
|
tree t;
|
|
|
|
|
{
|
|
|
|
|
tree x;
|
|
|
|
|
|
|
|
|
|
for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x))
|
|
|
|
|
{
|
|
|
|
|
GNU_xref_member (current_class_name, x);
|
|
|
|
|
|
|
|
|
|
/* If this was an evil function, don't keep it in class. */
|
|
|
|
|
if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (x)))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Do both of these, even though they're in the same union;
|
|
|
|
|
if the insn `r' member and the size `i' member are
|
|
|
|
|
different sizes, as on the alpha, the larger of the two
|
|
|
|
|
will end up with garbage in it. */
|
|
|
|
|
DECL_SAVED_INSNS (x) = 0;
|
|
|
|
|
DECL_FIELD_SIZE (x) = 0;
|
|
|
|
|
|
|
|
|
|
check_for_override (x, t);
|
1999-12-29 07:39:42 +01:00
|
|
|
|
if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x))
|
1999-12-16 04:10:12 +01:00
|
|
|
|
cp_error_at ("initializer specified for non-virtual method `%D'", x);
|
|
|
|
|
|
|
|
|
|
/* The name of the field is the original field name
|
|
|
|
|
Save this in auxiliary field for later overloading. */
|
|
|
|
|
if (DECL_VINDEX (x))
|
|
|
|
|
{
|
1999-12-21 03:11:10 +01:00
|
|
|
|
TYPE_POLYMORPHIC_P (t) = 1;
|
1999-12-29 07:39:42 +01:00
|
|
|
|
if (DECL_PURE_VIRTUAL_P (x))
|
|
|
|
|
CLASSTYPE_PURE_VIRTUALS (t)
|
|
|
|
|
= tree_cons (NULL_TREE, x, CLASSTYPE_PURE_VIRTUALS (t));
|
1999-12-16 04:10:12 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Remove all zero-width bit-fields from T. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
remove_zero_width_bit_fields (t)
|
|
|
|
|
tree t;
|
|
|
|
|
{
|
|
|
|
|
tree *fieldsp;
|
|
|
|
|
|
|
|
|
|
fieldsp = &TYPE_FIELDS (t);
|
|
|
|
|
while (*fieldsp)
|
|
|
|
|
{
|
|
|
|
|
if (TREE_CODE (*fieldsp) == FIELD_DECL
|
|
|
|
|
&& DECL_C_BIT_FIELD (*fieldsp)
|
|
|
|
|
&& DECL_INITIAL (*fieldsp))
|
|
|
|
|
*fieldsp = TREE_CHAIN (*fieldsp);
|
|
|
|
|
else
|
|
|
|
|
fieldsp = &TREE_CHAIN (*fieldsp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
/* Check the validity of the bases and members declared in T. Add any
|
|
|
|
|
implicitly-generated functions (like copy-constructors and
|
|
|
|
|
assignment operators). Compute various flag bits (like
|
|
|
|
|
CLASSTYPE_NON_POD_T) for T. This routine works purely at the C++
|
|
|
|
|
level: i.e., independently of the ABI in use. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
check_bases_and_members (t, empty_p)
|
|
|
|
|
tree t;
|
|
|
|
|
int *empty_p;
|
|
|
|
|
{
|
|
|
|
|
/* Nonzero if we are not allowed to generate a default constructor
|
|
|
|
|
for this case. */
|
|
|
|
|
int cant_have_default_ctor;
|
|
|
|
|
/* Nonzero if the implicitly generated copy constructor should take
|
|
|
|
|
a non-const reference argument. */
|
|
|
|
|
int cant_have_const_ctor;
|
|
|
|
|
/* Nonzero if the the implicitly generated assignment operator
|
|
|
|
|
should take a non-const reference argument. */
|
|
|
|
|
int no_const_asn_ref;
|
|
|
|
|
tree access_decls;
|
|
|
|
|
|
|
|
|
|
/* By default, we use const reference arguments and generate default
|
|
|
|
|
constructors. */
|
|
|
|
|
cant_have_default_ctor = 0;
|
|
|
|
|
cant_have_const_ctor = 0;
|
|
|
|
|
no_const_asn_ref = 0;
|
|
|
|
|
|
1999-12-29 09:28:50 +01:00
|
|
|
|
/* Assume that the class is nearly empty; we'll clear this flag if
|
|
|
|
|
it turns out not to be nearly empty. */
|
|
|
|
|
CLASSTYPE_NEARLY_EMPTY_P (t) = 1;
|
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
/* Check all the base-classes. */
|
|
|
|
|
check_bases (t, &cant_have_default_ctor, &cant_have_const_ctor,
|
|
|
|
|
&no_const_asn_ref);
|
|
|
|
|
|
|
|
|
|
/* Check all the data member declarations. */
|
|
|
|
|
check_field_decls (t, &access_decls, empty_p,
|
|
|
|
|
&cant_have_default_ctor,
|
|
|
|
|
&cant_have_const_ctor,
|
|
|
|
|
&no_const_asn_ref);
|
|
|
|
|
|
|
|
|
|
/* Check all the method declarations. */
|
|
|
|
|
check_methods (t);
|
|
|
|
|
|
2000-01-17 05:08:01 +01:00
|
|
|
|
/* A nearly-empty class has to be vptr-containing; a nearly empty
|
|
|
|
|
class contains just a vptr. */
|
|
|
|
|
if (!TYPE_CONTAINS_VPTR_P (t))
|
1999-12-29 09:28:50 +01:00
|
|
|
|
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
|
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
/* Do some bookkeeping that will guide the generation of implicitly
|
|
|
|
|
declared member functions. */
|
|
|
|
|
TYPE_HAS_COMPLEX_INIT_REF (t)
|
1999-12-21 03:11:10 +01:00
|
|
|
|
|= (TYPE_HAS_INIT_REF (t)
|
|
|
|
|
|| TYPE_USES_VIRTUAL_BASECLASSES (t)
|
|
|
|
|
|| TYPE_POLYMORPHIC_P (t));
|
1999-12-16 23:18:22 +01:00
|
|
|
|
TYPE_NEEDS_CONSTRUCTING (t)
|
1999-12-21 03:11:10 +01:00
|
|
|
|
|= (TYPE_HAS_CONSTRUCTOR (t)
|
|
|
|
|
|| TYPE_USES_VIRTUAL_BASECLASSES (t)
|
|
|
|
|
|| TYPE_POLYMORPHIC_P (t));
|
|
|
|
|
CLASSTYPE_NON_AGGREGATE (t) |= (TYPE_HAS_CONSTRUCTOR (t)
|
|
|
|
|
|| TYPE_POLYMORPHIC_P (t));
|
1999-12-16 23:18:22 +01:00
|
|
|
|
CLASSTYPE_NON_POD_P (t)
|
|
|
|
|
|= (CLASSTYPE_NON_AGGREGATE (t) || TYPE_HAS_DESTRUCTOR (t)
|
|
|
|
|
|| TYPE_HAS_ASSIGN_REF (t));
|
|
|
|
|
TYPE_HAS_REAL_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t);
|
|
|
|
|
TYPE_HAS_COMPLEX_ASSIGN_REF (t)
|
|
|
|
|
|= TYPE_HAS_ASSIGN_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t);
|
|
|
|
|
|
|
|
|
|
/* Synthesize any needed methods. Note that methods will be synthesized
|
|
|
|
|
for anonymous unions; grok_x_components undoes that. */
|
|
|
|
|
add_implicitly_declared_members (t, cant_have_default_ctor,
|
|
|
|
|
cant_have_const_ctor,
|
|
|
|
|
no_const_asn_ref);
|
|
|
|
|
|
|
|
|
|
/* Build and sort the CLASSTYPE_METHOD_VEC. */
|
|
|
|
|
finish_struct_methods (t);
|
|
|
|
|
|
|
|
|
|
/* Process the access-declarations. We wait until now to do this
|
|
|
|
|
because handle_using_decls requires that the CLASSTYPE_METHOD_VEC
|
|
|
|
|
be set up correctly. */
|
|
|
|
|
while (access_decls)
|
|
|
|
|
{
|
|
|
|
|
handle_using_decl (TREE_VALUE (access_decls), t);
|
|
|
|
|
access_decls = TREE_CHAIN (access_decls);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-12-21 03:11:10 +01:00
|
|
|
|
/* If T needs a pointer to its virtual function table, set TYPE_VFIELD
|
|
|
|
|
accordingly, and, if necessary, add the TYPE_VFIELD to the
|
|
|
|
|
TYPE_FIELDS list. */
|
|
|
|
|
|
|
|
|
|
static void
|
2000-01-03 05:05:43 +01:00
|
|
|
|
create_vtable_ptr (t, empty_p, has_virtual_p,
|
2000-01-17 21:18:43 +01:00
|
|
|
|
new_virtuals_p, overridden_virtuals_p)
|
1999-12-21 03:11:10 +01:00
|
|
|
|
tree t;
|
|
|
|
|
int *empty_p;
|
|
|
|
|
int *has_virtual_p;
|
2000-01-17 21:18:43 +01:00
|
|
|
|
tree *new_virtuals_p;
|
|
|
|
|
tree *overridden_virtuals_p;
|
1999-12-21 03:11:10 +01:00
|
|
|
|
{
|
|
|
|
|
tree fn;
|
|
|
|
|
|
|
|
|
|
/* Loop over the virtual functions, adding them to our various
|
|
|
|
|
vtables. */
|
|
|
|
|
for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
|
|
|
|
|
if (DECL_VINDEX (fn))
|
2000-01-17 21:18:43 +01:00
|
|
|
|
add_virtual_function (new_virtuals_p, overridden_virtuals_p,
|
1999-12-21 03:11:10 +01:00
|
|
|
|
has_virtual_p, fn, t);
|
|
|
|
|
|
2000-01-17 05:08:01 +01:00
|
|
|
|
/* Even if there weren't any new virtual functions, we might need a
|
|
|
|
|
new virtual function table if we're supposed to include vptrs in
|
|
|
|
|
all classes that need them. */
|
|
|
|
|
if (TYPE_CONTAINS_VPTR_P (t) && vptrs_present_everywhere_p ())
|
|
|
|
|
start_vtable (t, has_virtual_p);
|
|
|
|
|
|
1999-12-21 03:11:10 +01:00
|
|
|
|
/* If we couldn't find an appropriate base class, create a new field
|
|
|
|
|
here. */
|
|
|
|
|
if (*has_virtual_p && !TYPE_VFIELD (t))
|
|
|
|
|
{
|
|
|
|
|
/* We build this decl with vtbl_ptr_type_node, which is a
|
|
|
|
|
`vtable_entry_type*'. It might seem more precise to use
|
|
|
|
|
`vtable_entry_type (*)[N]' where N is the number of firtual
|
|
|
|
|
functions. However, that would require the vtable pointer in
|
|
|
|
|
base classes to have a different type than the vtable pointer
|
|
|
|
|
in derived classes. We could make that happen, but that
|
|
|
|
|
still wouldn't solve all the problems. In particular, the
|
|
|
|
|
type-based alias analysis code would decide that assignments
|
|
|
|
|
to the base class vtable pointer can't alias assignments to
|
|
|
|
|
the derived class vtable pointer, since they have different
|
|
|
|
|
types. Thus, in an derived class destructor, where the base
|
|
|
|
|
class constructor was inlined, we could generate bad code for
|
|
|
|
|
setting up the vtable pointer.
|
|
|
|
|
|
|
|
|
|
Therefore, we use one type for all vtable pointers. We still
|
|
|
|
|
use a type-correct type; it's just doesn't indicate the array
|
|
|
|
|
bounds. That's better than using `void*' or some such; it's
|
|
|
|
|
cleaner, and it let's the alias analysis code know that these
|
|
|
|
|
stores cannot alias stores to void*! */
|
|
|
|
|
TYPE_VFIELD (t)
|
|
|
|
|
= build_vtbl_or_vbase_field (get_vfield_name (t),
|
|
|
|
|
get_identifier (VFIELD_BASE),
|
|
|
|
|
vtbl_ptr_type_node,
|
|
|
|
|
t,
|
2000-02-01 03:17:06 +01:00
|
|
|
|
t,
|
1999-12-21 03:11:10 +01:00
|
|
|
|
empty_p);
|
|
|
|
|
|
|
|
|
|
/* Add the new field to the list of fields in this class. */
|
1999-12-29 21:05:41 +01:00
|
|
|
|
if (!flag_new_abi)
|
|
|
|
|
/* In the old ABI, the vtable pointer goes at the end of the
|
|
|
|
|
class. */
|
|
|
|
|
TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), TYPE_VFIELD (t));
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* But in the new ABI, the vtable pointer is the first thing
|
|
|
|
|
in the class. */
|
|
|
|
|
TYPE_FIELDS (t) = chainon (TYPE_VFIELD (t), TYPE_FIELDS (t));
|
|
|
|
|
/* If there were any baseclasses, they can't possibly be at
|
|
|
|
|
offset zero any more, because that's where the vtable
|
|
|
|
|
pointer is. So, converting to a base class is going to
|
|
|
|
|
take work. */
|
|
|
|
|
if (CLASSTYPE_N_BASECLASSES (t))
|
|
|
|
|
TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (t) = 1;
|
|
|
|
|
}
|
1999-12-21 03:11:10 +01:00
|
|
|
|
|
|
|
|
|
/* We can't yet add this new field to the list of all virtual
|
|
|
|
|
function table pointers in this class. The
|
|
|
|
|
modify_all_vtables function depends on this not being done.
|
|
|
|
|
So, it is done later, in finish_struct_1. */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-12-29 08:31:51 +01:00
|
|
|
|
/* Fixup the inline function given by INFO now that the class is
|
|
|
|
|
complete. */
|
1999-12-15 01:36:57 +01:00
|
|
|
|
|
1999-12-29 08:31:51 +01:00
|
|
|
|
static void
|
|
|
|
|
fixup_pending_inline (info)
|
|
|
|
|
struct pending_inline *info;
|
|
|
|
|
{
|
|
|
|
|
if (info)
|
|
|
|
|
{
|
|
|
|
|
tree args;
|
|
|
|
|
tree fn = info->fndecl;
|
1999-12-15 01:36:57 +01:00
|
|
|
|
|
1999-12-29 08:31:51 +01:00
|
|
|
|
args = DECL_ARGUMENTS (fn);
|
|
|
|
|
while (args)
|
|
|
|
|
{
|
|
|
|
|
DECL_CONTEXT (args) = fn;
|
|
|
|
|
args = TREE_CHAIN (args);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-12-15 01:36:57 +01:00
|
|
|
|
|
1999-12-29 08:31:51 +01:00
|
|
|
|
/* Fixup the inline methods and friends in TYPE now that TYPE is
|
|
|
|
|
complete. */
|
1999-12-15 01:36:57 +01:00
|
|
|
|
|
1999-12-29 08:31:51 +01:00
|
|
|
|
static void
|
|
|
|
|
fixup_inline_methods (type)
|
|
|
|
|
tree type;
|
1999-12-15 01:36:57 +01:00
|
|
|
|
{
|
1999-12-29 08:31:51 +01:00
|
|
|
|
tree method = TYPE_METHODS (type);
|
1999-12-15 01:36:57 +01:00
|
|
|
|
|
1999-12-29 08:31:51 +01:00
|
|
|
|
if (method && TREE_CODE (method) == TREE_VEC)
|
1999-12-15 01:36:57 +01:00
|
|
|
|
{
|
1999-12-29 08:31:51 +01:00
|
|
|
|
if (TREE_VEC_ELT (method, 1))
|
|
|
|
|
method = TREE_VEC_ELT (method, 1);
|
|
|
|
|
else if (TREE_VEC_ELT (method, 0))
|
|
|
|
|
method = TREE_VEC_ELT (method, 0);
|
1999-12-15 01:36:57 +01:00
|
|
|
|
else
|
1999-12-29 08:31:51 +01:00
|
|
|
|
method = TREE_VEC_ELT (method, 2);
|
1999-12-15 01:36:57 +01:00
|
|
|
|
}
|
|
|
|
|
|
1999-12-29 08:31:51 +01:00
|
|
|
|
/* Do inline member functions. */
|
|
|
|
|
for (; method; method = TREE_CHAIN (method))
|
|
|
|
|
fixup_pending_inline (DECL_PENDING_INLINE_INFO (method));
|
1999-12-15 01:36:57 +01:00
|
|
|
|
|
1999-12-29 08:31:51 +01:00
|
|
|
|
/* Do friends. */
|
|
|
|
|
for (method = CLASSTYPE_INLINE_FRIENDS (type);
|
|
|
|
|
method;
|
|
|
|
|
method = TREE_CHAIN (method))
|
|
|
|
|
fixup_pending_inline (DECL_PENDING_INLINE_INFO (TREE_VALUE (method)));
|
1999-12-30 18:23:24 +01:00
|
|
|
|
CLASSTYPE_INLINE_FRIENDS (type) = NULL_TREE;
|
1999-12-29 08:31:51 +01:00
|
|
|
|
}
|
1999-12-15 01:36:57 +01:00
|
|
|
|
|
2000-01-11 05:13:27 +01:00
|
|
|
|
/* Called from propagate_binfo_offsets via dfs_walk. */
|
|
|
|
|
|
|
|
|
|
static tree
|
|
|
|
|
dfs_propagate_binfo_offsets (binfo, data)
|
|
|
|
|
tree binfo;
|
|
|
|
|
void *data;
|
|
|
|
|
{
|
|
|
|
|
tree offset = (tree) data;
|
|
|
|
|
|
|
|
|
|
/* Update the BINFO_OFFSET for this base. */
|
|
|
|
|
BINFO_OFFSET (binfo)
|
|
|
|
|
= size_binop (PLUS_EXPR, BINFO_OFFSET (binfo), offset);
|
|
|
|
|
|
|
|
|
|
SET_BINFO_MARKED (binfo);
|
|
|
|
|
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Add OFFSET to all base types of BINFO which is a base in the
|
|
|
|
|
hierarchy dominated by T.
|
2000-01-02 20:41:09 +01:00
|
|
|
|
|
|
|
|
|
OFFSET, which is a type offset, is number of bytes.
|
|
|
|
|
|
|
|
|
|
Note that we don't have to worry about having two paths to the
|
|
|
|
|
same base type, since this type owns its association list. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
propagate_binfo_offsets (binfo, offset)
|
|
|
|
|
tree binfo;
|
|
|
|
|
tree offset;
|
|
|
|
|
{
|
2000-01-11 05:13:27 +01:00
|
|
|
|
dfs_walk (binfo,
|
|
|
|
|
dfs_propagate_binfo_offsets,
|
|
|
|
|
dfs_skip_nonprimary_vbases_unmarkedp,
|
|
|
|
|
offset);
|
|
|
|
|
dfs_walk (binfo,
|
|
|
|
|
dfs_unmark,
|
|
|
|
|
dfs_skip_nonprimary_vbases_markedp,
|
|
|
|
|
NULL);
|
2000-01-02 20:41:09 +01:00
|
|
|
|
}
|
|
|
|
|
|
2000-01-11 04:15:32 +01:00
|
|
|
|
/* Remove *FIELD (which corresponds to the base given by BINFO) from
|
|
|
|
|
the field list for T. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
remove_base_field (t, binfo, field)
|
|
|
|
|
tree t;
|
|
|
|
|
tree binfo;
|
|
|
|
|
tree *field;
|
|
|
|
|
{
|
|
|
|
|
tree basetype = BINFO_TYPE (binfo);
|
|
|
|
|
tree offset;
|
|
|
|
|
|
|
|
|
|
my_friendly_assert (TREE_TYPE (*field) == basetype, 23897);
|
|
|
|
|
|
|
|
|
|
if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
|
|
|
|
|
cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
|
|
|
|
|
basetype, t);
|
|
|
|
|
|
|
|
|
|
offset
|
|
|
|
|
= size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (*field)),
|
|
|
|
|
BITS_PER_UNIT));
|
|
|
|
|
propagate_binfo_offsets (binfo, offset);
|
|
|
|
|
|
|
|
|
|
/* Remove this field. */
|
|
|
|
|
*field = TREE_CHAIN (*field);
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-02 20:41:09 +01:00
|
|
|
|
/* Remove the FIELD_DECLs created for T's base classes in
|
|
|
|
|
build_base_fields. Simultaneously, update BINFO_OFFSET for all the
|
|
|
|
|
bases, except for non-primary virtual baseclasses. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
remove_base_fields (t)
|
|
|
|
|
tree t;
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
tree *field;
|
|
|
|
|
|
|
|
|
|
/* Now propagate offset information throughout the lattice.
|
|
|
|
|
Simultaneously, remove the temporary FIELD_DECLS we created in
|
|
|
|
|
build_base_fields to refer to base types. */
|
|
|
|
|
field = &TYPE_FIELDS (t);
|
|
|
|
|
if (TYPE_VFIELD (t) == *field)
|
|
|
|
|
{
|
|
|
|
|
/* If this class did not have a primary base, we create a
|
|
|
|
|
virtual function table pointer. It will be the first thing
|
|
|
|
|
in the class, under the new ABI. Skip it; the base fields
|
|
|
|
|
will follow it. */
|
|
|
|
|
my_friendly_assert (flag_new_abi
|
|
|
|
|
&& !CLASSTYPE_HAS_PRIMARY_BASE_P (t),
|
|
|
|
|
19991218);
|
|
|
|
|
field = &TREE_CHAIN (*field);
|
|
|
|
|
}
|
2000-01-11 04:15:32 +01:00
|
|
|
|
|
|
|
|
|
/* Under the new ABI, the primary base is always allocated first. */
|
|
|
|
|
if (flag_new_abi && CLASSTYPE_HAS_PRIMARY_BASE_P (t))
|
|
|
|
|
remove_base_field (t, CLASSTYPE_PRIMARY_BINFO (t), field);
|
|
|
|
|
|
|
|
|
|
/* Now remove the rest of the bases. */
|
2000-01-02 20:41:09 +01:00
|
|
|
|
for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++)
|
|
|
|
|
{
|
2000-01-11 04:15:32 +01:00
|
|
|
|
tree binfo;
|
2000-01-02 20:41:09 +01:00
|
|
|
|
|
2000-01-11 04:15:32 +01:00
|
|
|
|
/* Under the new ABI, we've already removed the primary base
|
|
|
|
|
above. */
|
|
|
|
|
if (flag_new_abi && i == CLASSTYPE_VFIELD_PARENT (t))
|
2000-01-02 20:41:09 +01:00
|
|
|
|
continue;
|
|
|
|
|
|
2000-01-11 04:15:32 +01:00
|
|
|
|
binfo = BINFO_BASETYPE (TYPE_BINFO (t), i);
|
2000-01-02 20:41:09 +01:00
|
|
|
|
|
2000-01-11 04:15:32 +01:00
|
|
|
|
/* We treat a primary virtual base class just like an ordinary base
|
|
|
|
|
class. But, non-primary virtual bases are laid out later. */
|
|
|
|
|
if (TREE_VIA_VIRTUAL (binfo) && !BINFO_PRIMARY_MARKED_P (binfo))
|
|
|
|
|
continue;
|
2000-01-02 20:41:09 +01:00
|
|
|
|
|
2000-01-11 04:15:32 +01:00
|
|
|
|
remove_base_field (t, binfo, field);
|
2000-01-02 20:41:09 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-11 05:13:27 +01:00
|
|
|
|
/* Called via dfs_walk from layout_virtual bases. */
|
2000-01-02 20:41:09 +01:00
|
|
|
|
|
|
|
|
|
static tree
|
2000-01-11 05:13:27 +01:00
|
|
|
|
dfs_set_offset_for_shared_vbases (binfo, data)
|
2000-01-02 20:41:09 +01:00
|
|
|
|
tree binfo;
|
|
|
|
|
void *data;
|
|
|
|
|
{
|
2000-01-11 05:13:27 +01:00
|
|
|
|
if (TREE_VIA_VIRTUAL (binfo) && BINFO_PRIMARY_MARKED_P (binfo))
|
2000-01-02 20:41:09 +01:00
|
|
|
|
{
|
2000-01-11 05:13:27 +01:00
|
|
|
|
/* Update the shared copy. */
|
|
|
|
|
tree shared_binfo;
|
2000-01-02 20:41:09 +01:00
|
|
|
|
|
2000-01-11 05:13:27 +01:00
|
|
|
|
shared_binfo = BINFO_FOR_VBASE (BINFO_TYPE (binfo), (tree) data);
|
|
|
|
|
BINFO_OFFSET (shared_binfo) = BINFO_OFFSET (binfo);
|
2000-01-02 20:41:09 +01:00
|
|
|
|
}
|
|
|
|
|
|
2000-01-11 05:13:27 +01:00
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Called via dfs_walk from layout_virtual bases. */
|
|
|
|
|
|
|
|
|
|
static tree
|
|
|
|
|
dfs_set_offset_for_unshared_vbases (binfo, data)
|
|
|
|
|
tree binfo;
|
|
|
|
|
void *data;
|
|
|
|
|
{
|
|
|
|
|
/* If this is a virtual base, make sure it has the same offset as
|
|
|
|
|
the shared copy. If it's a primary base, then we know it's
|
|
|
|
|
correct. */
|
|
|
|
|
if (TREE_VIA_VIRTUAL (binfo) && !BINFO_PRIMARY_MARKED_P (binfo))
|
|
|
|
|
{
|
|
|
|
|
tree t = (tree) data;
|
|
|
|
|
tree vbase;
|
|
|
|
|
tree offset;
|
|
|
|
|
|
|
|
|
|
vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), t);
|
|
|
|
|
offset = ssize_binop (MINUS_EXPR,
|
|
|
|
|
BINFO_OFFSET (vbase),
|
|
|
|
|
BINFO_OFFSET (binfo));
|
|
|
|
|
propagate_binfo_offsets (binfo, offset);
|
|
|
|
|
}
|
2000-01-02 20:41:09 +01:00
|
|
|
|
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Set BINFO_OFFSET for all of the virtual bases for T. Update
|
2000-01-03 05:05:43 +01:00
|
|
|
|
TYPE_ALIGN and TYPE_SIZE for T. */
|
2000-01-02 20:41:09 +01:00
|
|
|
|
|
2000-01-03 05:05:43 +01:00
|
|
|
|
static void
|
|
|
|
|
layout_virtual_bases (t)
|
2000-01-02 20:41:09 +01:00
|
|
|
|
tree t;
|
|
|
|
|
{
|
|
|
|
|
tree vbase;
|
|
|
|
|
int dsize;
|
|
|
|
|
|
|
|
|
|
/* DSIZE is the size of the class without the virtual bases. */
|
|
|
|
|
dsize = TREE_INT_CST_LOW (TYPE_SIZE (t));
|
|
|
|
|
/* Make every class have alignment of at least one. */
|
|
|
|
|
TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), BITS_PER_UNIT);
|
|
|
|
|
|
2000-01-11 05:13:27 +01:00
|
|
|
|
/* Go through the virtual bases, allocating space for each virtual
|
|
|
|
|
base that is not already a primary base class. */
|
2000-01-02 20:41:09 +01:00
|
|
|
|
for (vbase = CLASSTYPE_VBASECLASSES (t);
|
|
|
|
|
vbase;
|
|
|
|
|
vbase = TREE_CHAIN (vbase))
|
2000-01-11 05:13:27 +01:00
|
|
|
|
if (!BINFO_VBASE_PRIMARY_P (vbase))
|
2000-01-02 20:41:09 +01:00
|
|
|
|
{
|
|
|
|
|
/* This virtual base is not a primary base of any class in the
|
|
|
|
|
hierarchy, so we have to add space for it. */
|
|
|
|
|
tree basetype;
|
|
|
|
|
unsigned int desired_align;
|
|
|
|
|
|
|
|
|
|
basetype = BINFO_TYPE (vbase);
|
|
|
|
|
desired_align = TYPE_ALIGN (basetype);
|
|
|
|
|
TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), desired_align);
|
|
|
|
|
|
|
|
|
|
/* Add padding so that we can put the virtual base class at an
|
|
|
|
|
appropriately aligned offset. */
|
|
|
|
|
dsize = CEIL (dsize, desired_align) * desired_align;
|
|
|
|
|
/* And compute the offset of the virtual base. */
|
2000-01-11 05:13:27 +01:00
|
|
|
|
propagate_binfo_offsets (vbase,
|
|
|
|
|
size_int (CEIL (dsize, BITS_PER_UNIT)));
|
2000-01-02 20:41:09 +01:00
|
|
|
|
/* Every virtual baseclass takes a least a UNIT, so that we can
|
|
|
|
|
take it's address and get something different for each base. */
|
|
|
|
|
dsize += MAX (BITS_PER_UNIT,
|
|
|
|
|
TREE_INT_CST_LOW (CLASSTYPE_SIZE (basetype)));
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-11 05:13:27 +01:00
|
|
|
|
/* Make sure that all of the CLASSTYPE_VBASECLASSES have their
|
|
|
|
|
BINFO_OFFSET set correctly. Those we just allocated certainly
|
|
|
|
|
will. The others are primary baseclasses; we walk the hierarchy
|
|
|
|
|
to find the primary copies and update the shared copy. */
|
|
|
|
|
dfs_walk (TYPE_BINFO (t),
|
|
|
|
|
dfs_set_offset_for_shared_vbases,
|
|
|
|
|
dfs_unmarked_real_bases_queue_p,
|
|
|
|
|
t);
|
|
|
|
|
|
|
|
|
|
/* Now, go through the TYPE_BINFO hierarchy again, setting the
|
|
|
|
|
BINFO_OFFSETs correctly for all non-primary copies of the virtual
|
|
|
|
|
bases and their direct and indirect bases. The ambiguity checks
|
|
|
|
|
in get_base_distance depend on the BINFO_OFFSETs being set
|
|
|
|
|
correctly. */
|
|
|
|
|
dfs_walk (TYPE_BINFO (t), dfs_set_offset_for_unshared_vbases, NULL, t);
|
2000-01-31 22:00:01 +01:00
|
|
|
|
for (vbase = CLASSTYPE_VBASECLASSES (t);
|
|
|
|
|
vbase;
|
|
|
|
|
vbase = TREE_CHAIN (vbase))
|
|
|
|
|
dfs_walk (vbase, dfs_set_offset_for_unshared_vbases, NULL, t);
|
2000-01-11 05:13:27 +01:00
|
|
|
|
|
2000-01-02 20:41:09 +01:00
|
|
|
|
/* Now, make sure that the total size of the type is a multiple of
|
|
|
|
|
its alignment. */
|
|
|
|
|
dsize = CEIL (dsize, TYPE_ALIGN (t)) * TYPE_ALIGN (t);
|
|
|
|
|
TYPE_SIZE (t) = size_int (dsize);
|
|
|
|
|
TYPE_SIZE_UNIT (t) = size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (t),
|
|
|
|
|
size_int (BITS_PER_UNIT));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Finish the work of layout_record, now taking virtual bases into account.
|
|
|
|
|
Also compute the actual offsets that our base classes will have.
|
|
|
|
|
This must be performed after the fields are laid out, since virtual
|
2000-01-03 05:05:43 +01:00
|
|
|
|
baseclasses must lay down at the end of the record. */
|
2000-01-02 20:41:09 +01:00
|
|
|
|
|
2000-01-03 05:05:43 +01:00
|
|
|
|
static void
|
|
|
|
|
layout_basetypes (rec)
|
2000-01-02 20:41:09 +01:00
|
|
|
|
tree rec;
|
|
|
|
|
{
|
|
|
|
|
tree vbase_types;
|
|
|
|
|
|
|
|
|
|
#ifdef STRUCTURE_SIZE_BOUNDARY
|
|
|
|
|
/* Packed structures don't need to have minimum size. */
|
|
|
|
|
if (! TYPE_PACKED (rec))
|
|
|
|
|
TYPE_ALIGN (rec) = MAX (TYPE_ALIGN (rec), STRUCTURE_SIZE_BOUNDARY);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Remove the FIELD_DECLs we created for baseclasses in
|
|
|
|
|
build_base_fields. Simultaneously, update the BINFO_OFFSETs for
|
|
|
|
|
everything in the hierarcy except non-primary virtual bases. */
|
|
|
|
|
remove_base_fields (rec);
|
|
|
|
|
|
|
|
|
|
/* Allocate the virtual base classes. */
|
2000-01-03 05:05:43 +01:00
|
|
|
|
layout_virtual_bases (rec);
|
2000-01-02 20:41:09 +01:00
|
|
|
|
|
|
|
|
|
/* Get all the virtual base types that this type uses. The
|
|
|
|
|
TREE_VALUE slot holds the virtual baseclass type. Note that
|
|
|
|
|
get_vbase_types makes copies of the virtual base BINFOs, so that
|
|
|
|
|
the vbase_types are unshared. */
|
|
|
|
|
for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types;
|
|
|
|
|
vbase_types = TREE_CHAIN (vbase_types))
|
2000-01-11 05:13:27 +01:00
|
|
|
|
if (extra_warnings)
|
|
|
|
|
{
|
|
|
|
|
tree basetype = BINFO_TYPE (vbase_types);
|
|
|
|
|
if (get_base_distance (basetype, rec, 0, (tree*)0) == -2)
|
|
|
|
|
cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
|
|
|
|
|
basetype, rec);
|
|
|
|
|
}
|
2000-01-02 20:41:09 +01:00
|
|
|
|
}
|
|
|
|
|
|
1999-12-29 08:31:51 +01:00
|
|
|
|
/* Calculate the TYPE_SIZE, TYPE_ALIGN, etc for T. Calculate
|
|
|
|
|
BINFO_OFFSETs for all of the base-classes. Position the vtable
|
|
|
|
|
pointer. */
|
1999-12-16 23:18:22 +01:00
|
|
|
|
|
1999-12-29 08:31:51 +01:00
|
|
|
|
static void
|
2000-01-03 05:05:43 +01:00
|
|
|
|
layout_class_type (t, empty_p, has_virtual_p,
|
2000-01-17 21:18:43 +01:00
|
|
|
|
new_virtuals_p, overridden_virtuals_p)
|
1999-12-29 08:31:51 +01:00
|
|
|
|
tree t;
|
|
|
|
|
int *empty_p;
|
|
|
|
|
int *has_virtual_p;
|
2000-01-17 21:18:43 +01:00
|
|
|
|
tree *new_virtuals_p;
|
|
|
|
|
tree *overridden_virtuals_p;
|
1999-12-29 08:31:51 +01:00
|
|
|
|
{
|
2000-01-25 07:33:06 +01:00
|
|
|
|
tree padding = NULL_TREE;
|
|
|
|
|
|
2000-01-03 07:56:21 +01:00
|
|
|
|
/* If possible, we reuse the virtual function table pointer from one
|
|
|
|
|
of our base classes. */
|
|
|
|
|
determine_primary_base (t, has_virtual_p);
|
|
|
|
|
|
1999-12-16 23:18:22 +01:00
|
|
|
|
/* Add pointers to all of our virtual base-classes. */
|
1999-12-29 08:31:51 +01:00
|
|
|
|
TYPE_FIELDS (t) = chainon (build_vbase_pointer_fields (t, empty_p),
|
1999-12-16 23:18:22 +01:00
|
|
|
|
TYPE_FIELDS (t));
|
|
|
|
|
/* Build FIELD_DECLs for all of the non-virtual base-types. */
|
1999-12-29 08:31:51 +01:00
|
|
|
|
TYPE_FIELDS (t) = chainon (build_base_fields (t, empty_p),
|
1999-12-16 23:18:22 +01:00
|
|
|
|
TYPE_FIELDS (t));
|
|
|
|
|
|
1999-12-21 03:11:10 +01:00
|
|
|
|
/* Create a pointer to our virtual function table. */
|
2000-01-03 05:05:43 +01:00
|
|
|
|
create_vtable_ptr (t, empty_p, has_virtual_p,
|
2000-01-17 21:18:43 +01:00
|
|
|
|
new_virtuals_p, overridden_virtuals_p);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-05-17 09:42:26 +02:00
|
|
|
|
/* CLASSTYPE_INLINE_FRIENDS is really TYPE_NONCOPIED_PARTS. Thus,
|
|
|
|
|
we have to save this before we start modifying
|
|
|
|
|
TYPE_NONCOPIED_PARTS. */
|
1999-12-29 08:31:51 +01:00
|
|
|
|
fixup_inline_methods (t);
|
1999-05-17 09:42:26 +02:00
|
|
|
|
|
1999-12-16 04:10:12 +01:00
|
|
|
|
/* We make all structures have at least one element, so that they
|
|
|
|
|
have non-zero size. The field that we add here is fake, in the
|
|
|
|
|
sense that, for example, we don't want people to be able to
|
|
|
|
|
initialize it later. So, we add it just long enough to let the
|
2000-01-25 07:33:06 +01:00
|
|
|
|
back-end lay out the type, and then remove it. In the new ABI,
|
|
|
|
|
the class may be empty even if it has basetypes. Therefore, we
|
|
|
|
|
add the fake field at the end of the fields list; if there are
|
|
|
|
|
already FIELD_DECLs on the list, their offsets will not be
|
|
|
|
|
disturbed. */
|
1999-12-29 08:31:51 +01:00
|
|
|
|
if (*empty_p)
|
1996-10-31 18:08:58 +01:00
|
|
|
|
{
|
2000-01-25 07:33:06 +01:00
|
|
|
|
padding = build_lang_decl (FIELD_DECL, NULL_TREE, char_type_node);
|
|
|
|
|
TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), padding);
|
1999-05-17 09:42:26 +02:00
|
|
|
|
TYPE_NONCOPIED_PARTS (t)
|
2000-01-25 07:33:06 +01:00
|
|
|
|
= tree_cons (NULL_TREE, padding, TYPE_NONCOPIED_PARTS (t));
|
1999-05-17 09:42:26 +02:00
|
|
|
|
TREE_STATIC (TYPE_NONCOPIED_PARTS (t)) = 1;
|
1996-10-31 18:08:58 +01:00
|
|
|
|
}
|
1999-05-17 09:42:26 +02:00
|
|
|
|
|
1999-12-21 03:11:10 +01:00
|
|
|
|
/* Let the back-end lay out the type. Note that at this point we
|
|
|
|
|
have only included non-virtual base-classes; we will lay out the
|
|
|
|
|
virtual base classes later. So, the TYPE_SIZE/TYPE_ALIGN after
|
|
|
|
|
this call are not necessarily correct; they are just the size and
|
|
|
|
|
alignment when no virtual base clases are used. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
layout_type (t);
|
|
|
|
|
|
1999-12-16 04:10:12 +01:00
|
|
|
|
/* If we added an extra field to make this class non-empty, remove
|
|
|
|
|
it now. */
|
1999-12-29 08:31:51 +01:00
|
|
|
|
if (*empty_p)
|
2000-01-25 07:33:06 +01:00
|
|
|
|
{
|
|
|
|
|
tree *declp;
|
|
|
|
|
|
|
|
|
|
declp = &TYPE_FIELDS (t);
|
|
|
|
|
while (*declp != padding)
|
|
|
|
|
declp = &TREE_CHAIN (*declp);
|
|
|
|
|
*declp = TREE_CHAIN (*declp);
|
|
|
|
|
}
|
1999-12-16 04:10:12 +01:00
|
|
|
|
|
1999-12-21 03:11:10 +01:00
|
|
|
|
/* Delete all zero-width bit-fields from the list of fields. Now
|
|
|
|
|
that the type is laid out they are no longer important. */
|
|
|
|
|
remove_zero_width_bit_fields (t);
|
|
|
|
|
|
1998-04-03 05:41:20 +02:00
|
|
|
|
/* Remember the size and alignment of the class before adding
|
cp-tree.h: Lose CLASSTYPE_VBASE_SIZE, some unused stuff.
* cp-tree.h: Lose CLASSTYPE_VBASE_SIZE, some unused stuff.
* decl.c, decl2.c, pt.c, ptree.c, lex.c: Likewise.
* class.c (duplicate_tag_error): Likewise.
(finish_struct_1): Set CLASSTYPE_SIZE, CLASSTYPE_MODE, CLASSTYPE_ALIGN.
* tree.c (layout_vbasetypes): Update from layout_record, remove
var_size support, use CLASSTYPE_SIZE instead of CLASSTYPE_VBASE_SIZE.
(layout_basetypes): Likewise.
From-SVN: r18965
1998-04-02 19:05:40 +02:00
|
|
|
|
the virtual bases. */
|
1999-12-29 08:31:51 +01:00
|
|
|
|
if (*empty_p && flag_new_abi)
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
{
|
|
|
|
|
CLASSTYPE_SIZE (t) = bitsize_int (0);
|
|
|
|
|
CLASSTYPE_SIZE_UNIT (t) = size_int (0);
|
|
|
|
|
}
|
1998-05-15 22:03:17 +02:00
|
|
|
|
else if (flag_new_abi && TYPE_HAS_COMPLEX_INIT_REF (t)
|
|
|
|
|
&& TYPE_HAS_COMPLEX_ASSIGN_REF (t))
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
{
|
|
|
|
|
CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t);
|
|
|
|
|
CLASSTYPE_SIZE_UNIT (t) = TYPE_BINFO_SIZE_UNIT (t);
|
|
|
|
|
}
|
1998-04-03 16:13:24 +02:00
|
|
|
|
else
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
{
|
|
|
|
|
CLASSTYPE_SIZE (t) = TYPE_SIZE (t);
|
|
|
|
|
CLASSTYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (t);
|
|
|
|
|
}
|
|
|
|
|
|
cp-tree.h: Lose CLASSTYPE_VBASE_SIZE, some unused stuff.
* cp-tree.h: Lose CLASSTYPE_VBASE_SIZE, some unused stuff.
* decl.c, decl2.c, pt.c, ptree.c, lex.c: Likewise.
* class.c (duplicate_tag_error): Likewise.
(finish_struct_1): Set CLASSTYPE_SIZE, CLASSTYPE_MODE, CLASSTYPE_ALIGN.
* tree.c (layout_vbasetypes): Update from layout_record, remove
var_size support, use CLASSTYPE_SIZE instead of CLASSTYPE_VBASE_SIZE.
(layout_basetypes): Likewise.
From-SVN: r18965
1998-04-02 19:05:40 +02:00
|
|
|
|
CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t);
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
/* Set the TYPE_DECL for this type to contain the right
|
|
|
|
|
value for DECL_OFFSET, so that we can use it as part
|
|
|
|
|
of a COMPONENT_REF for multiple inheritance. */
|
1996-12-18 03:46:25 +01:00
|
|
|
|
layout_decl (TYPE_MAIN_DECL (t), 0);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1994-04-22 01:30:18 +02:00
|
|
|
|
/* Now fix up any virtual base class types that we left lying
|
|
|
|
|
around. We must get these done before we try to lay out the
|
|
|
|
|
virtual function table. */
|
1999-12-29 08:31:51 +01:00
|
|
|
|
if (CLASSTYPE_N_BASECLASSES (t))
|
1998-04-03 05:41:20 +02:00
|
|
|
|
/* layout_basetypes will remove the base subobject fields. */
|
2000-01-03 05:05:43 +01:00
|
|
|
|
layout_basetypes (t);
|
1999-12-29 08:31:51 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration
|
|
|
|
|
(or C++ class declaration).
|
|
|
|
|
|
|
|
|
|
For C++, we must handle the building of derived classes.
|
|
|
|
|
Also, C++ allows static class members. The way that this is
|
|
|
|
|
handled is to keep the field name where it is (as the DECL_NAME
|
|
|
|
|
of the field), and place the overloaded decl in the DECL_FIELD_BITPOS
|
|
|
|
|
of the field. layout_record and layout_union will know about this.
|
|
|
|
|
|
|
|
|
|
More C++ hair: inline functions have text in their
|
|
|
|
|
DECL_PENDING_INLINE_INFO nodes which must somehow be parsed into
|
|
|
|
|
meaningful tree structure. After the struct has been laid out, set
|
|
|
|
|
things up so that this can happen.
|
|
|
|
|
|
|
|
|
|
And still more: virtual functions. In the case of single inheritance,
|
|
|
|
|
when a new virtual function is seen which redefines a virtual function
|
|
|
|
|
from the base class, the new virtual function is placed into
|
|
|
|
|
the virtual function table at exactly the same address that
|
|
|
|
|
it had in the base class. When this is extended to multiple
|
|
|
|
|
inheritance, the same thing happens, except that multiple virtual
|
|
|
|
|
function tables must be maintained. The first virtual function
|
|
|
|
|
table is treated in exactly the same way as in the case of single
|
|
|
|
|
inheritance. Additional virtual function tables have different
|
|
|
|
|
DELTAs, which tell how to adjust `this' to point to the right thing.
|
|
|
|
|
|
|
|
|
|
ATTRIBUTES is the set of decl attributes to be applied, if any. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
finish_struct_1 (t)
|
|
|
|
|
tree t;
|
|
|
|
|
{
|
|
|
|
|
tree x;
|
|
|
|
|
int has_virtual;
|
2000-01-17 21:18:43 +01:00
|
|
|
|
/* The NEW_VIRTUALS is a TREE_LIST. The TREE_VALUE of each node is
|
|
|
|
|
a FUNCTION_DECL. Each of these functions is a virtual function
|
|
|
|
|
declared in T that does not override any virtual function from a
|
|
|
|
|
base class. */
|
|
|
|
|
tree new_virtuals = NULL_TREE;
|
|
|
|
|
/* The OVERRIDDEN_VIRTUALS list is like the NEW_VIRTUALS list,
|
|
|
|
|
except that each declaration here overrides the declaration from
|
|
|
|
|
a base class. */
|
|
|
|
|
tree overridden_virtuals = NULL_TREE;
|
1999-12-29 08:31:51 +01:00
|
|
|
|
int n_fields = 0;
|
|
|
|
|
tree vfield;
|
|
|
|
|
int empty = 1;
|
|
|
|
|
|
|
|
|
|
if (TYPE_SIZE (t))
|
|
|
|
|
{
|
|
|
|
|
if (IS_AGGR_TYPE (t))
|
|
|
|
|
cp_error ("redefinition of `%#T'", t);
|
|
|
|
|
else
|
|
|
|
|
my_friendly_abort (172);
|
|
|
|
|
popclass ();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GNU_xref_decl (current_function_decl, t);
|
|
|
|
|
|
|
|
|
|
/* If this type was previously laid out as a forward reference,
|
|
|
|
|
make sure we lay it out again. */
|
|
|
|
|
TYPE_SIZE (t) = NULL_TREE;
|
|
|
|
|
CLASSTYPE_GOT_SEMICOLON (t) = 0;
|
|
|
|
|
CLASSTYPE_VFIELD_PARENT (t) = -1;
|
|
|
|
|
has_virtual = 0;
|
|
|
|
|
CLASSTYPE_RTTI (t) = NULL_TREE;
|
|
|
|
|
|
|
|
|
|
/* Do end-of-class semantic processing: checking the validity of the
|
2000-01-01 04:04:27 +01:00
|
|
|
|
bases and members and add implicitly generated methods. */
|
1999-12-29 08:31:51 +01:00
|
|
|
|
check_bases_and_members (t, &empty);
|
|
|
|
|
|
|
|
|
|
/* Layout the class itself. */
|
2000-01-03 05:05:43 +01:00
|
|
|
|
layout_class_type (t, &empty, &has_virtual,
|
2000-01-17 21:18:43 +01:00
|
|
|
|
&new_virtuals, &overridden_virtuals);
|
1998-11-18 03:21:54 +01:00
|
|
|
|
|
1994-05-19 22:19:03 +02:00
|
|
|
|
/* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we
|
|
|
|
|
might need to know it for setting up the offsets in the vtable
|
|
|
|
|
(or in thunks) below. */
|
1999-12-21 03:11:10 +01:00
|
|
|
|
vfield = TYPE_VFIELD (t);
|
1994-05-19 22:19:03 +02:00
|
|
|
|
if (vfield != NULL_TREE
|
|
|
|
|
&& DECL_FIELD_CONTEXT (vfield) != t)
|
|
|
|
|
{
|
|
|
|
|
tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0);
|
|
|
|
|
tree offset = BINFO_OFFSET (binfo);
|
|
|
|
|
|
|
|
|
|
vfield = copy_node (vfield);
|
|
|
|
|
copy_lang_decl (vfield);
|
|
|
|
|
|
|
|
|
|
if (! integer_zerop (offset))
|
|
|
|
|
offset = size_binop (MULT_EXPR, offset, size_int (BITS_PER_UNIT));
|
|
|
|
|
DECL_FIELD_CONTEXT (vfield) = t;
|
|
|
|
|
DECL_FIELD_BITPOS (vfield)
|
|
|
|
|
= size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield));
|
1999-10-06 21:01:44 +02:00
|
|
|
|
TYPE_VFIELD (t) = vfield;
|
1994-05-19 22:19:03 +02:00
|
|
|
|
}
|
1999-12-21 01:19:01 +01:00
|
|
|
|
|
2000-01-17 23:54:23 +01:00
|
|
|
|
overridden_virtuals
|
|
|
|
|
= modify_all_vtables (t, &has_virtual, nreverse (overridden_virtuals));
|
1994-11-29 01:59:16 +01:00
|
|
|
|
|
2000-01-31 22:00:01 +01:00
|
|
|
|
/* If necessary, create the primary vtable for this class. */
|
2000-01-17 21:18:43 +01:00
|
|
|
|
if (new_virtuals
|
2000-01-17 23:54:23 +01:00
|
|
|
|
|| overridden_virtuals
|
2000-01-17 05:08:01 +01:00
|
|
|
|
|| (TYPE_CONTAINS_VPTR_P (t) && vptrs_present_everywhere_p ()))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
2000-01-17 21:18:43 +01:00
|
|
|
|
new_virtuals = nreverse (new_virtuals);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
/* We must enter these virtuals into the table. */
|
1999-12-21 03:11:10 +01:00
|
|
|
|
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1999-04-13 02:39:32 +02:00
|
|
|
|
if (! CLASSTYPE_COM_INTERFACE (t))
|
|
|
|
|
{
|
2000-01-17 23:54:23 +01:00
|
|
|
|
/* The second slot is for the tdesc pointer when thunks
|
|
|
|
|
are used. */
|
1999-04-13 02:39:32 +02:00
|
|
|
|
if (flag_vtable_thunks)
|
2000-01-17 21:18:43 +01:00
|
|
|
|
new_virtuals = tree_cons (NULL_TREE, NULL_TREE, new_virtuals);
|
1995-10-12 03:33:51 +01:00
|
|
|
|
|
1999-04-13 02:39:32 +02:00
|
|
|
|
/* The first slot is for the rtti offset. */
|
2000-01-17 21:18:43 +01:00
|
|
|
|
new_virtuals = tree_cons (NULL_TREE, NULL_TREE, new_virtuals);
|
1996-04-13 01:55:07 +02:00
|
|
|
|
|
2000-01-17 21:18:43 +01:00
|
|
|
|
set_rtti_entry (new_virtuals,
|
1999-04-13 02:39:32 +02:00
|
|
|
|
convert (ssizetype, integer_zero_node), t);
|
|
|
|
|
}
|
2000-01-31 05:03:01 +01:00
|
|
|
|
build_primary_vtable (NULL_TREE, t);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
2000-01-02 03:13:53 +01:00
|
|
|
|
else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
|
|
|
|
|
/* Here we know enough to change the type of our virtual
|
|
|
|
|
function table, but we will wait until later this function. */
|
2000-01-31 05:03:01 +01:00
|
|
|
|
build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
/* If this type has basetypes with constructors, then those
|
|
|
|
|
constructors might clobber the virtual function table. But
|
|
|
|
|
they don't if the derived class shares the exact vtable of the base
|
|
|
|
|
class. */
|
|
|
|
|
|
|
|
|
|
CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1;
|
|
|
|
|
}
|
2000-01-17 05:08:01 +01:00
|
|
|
|
/* If we didn't need a new vtable, see if we should copy one from
|
|
|
|
|
the base. */
|
1999-12-21 03:11:10 +01:00
|
|
|
|
else if (CLASSTYPE_HAS_PRIMARY_BASE_P (t))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1999-12-21 03:11:10 +01:00
|
|
|
|
tree binfo = CLASSTYPE_PRIMARY_BINFO (t);
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
/* This class contributes nothing new to the virtual function
|
|
|
|
|
table. However, it may have declared functions which
|
|
|
|
|
went into the virtual function table "inherited" from the
|
|
|
|
|
base class. If so, we grab a copy of those updated functions,
|
|
|
|
|
and pretend they are ours. */
|
|
|
|
|
|
|
|
|
|
/* See if we should steal the virtual info from base class. */
|
|
|
|
|
if (TYPE_BINFO_VTABLE (t) == NULL_TREE)
|
|
|
|
|
TYPE_BINFO_VTABLE (t) = BINFO_VTABLE (binfo);
|
|
|
|
|
if (TYPE_BINFO_VIRTUALS (t) == NULL_TREE)
|
|
|
|
|
TYPE_BINFO_VIRTUALS (t) = BINFO_VIRTUALS (binfo);
|
|
|
|
|
if (TYPE_BINFO_VTABLE (t) != BINFO_VTABLE (binfo))
|
|
|
|
|
CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1;
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-17 05:08:01 +01:00
|
|
|
|
if (TYPE_CONTAINS_VPTR_P (t))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
2000-01-17 06:12:39 +01:00
|
|
|
|
if (TYPE_BINFO_VTABLE (t))
|
|
|
|
|
my_friendly_assert (DECL_VIRTUAL_P (TYPE_BINFO_VTABLE (t)),
|
|
|
|
|
20000116);
|
|
|
|
|
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
|
|
|
|
|
my_friendly_assert (TYPE_BINFO_VIRTUALS (t) == NULL_TREE,
|
|
|
|
|
20000116);
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
CLASSTYPE_VSIZE (t) = has_virtual;
|
2000-01-17 06:12:39 +01:00
|
|
|
|
/* Entries for virtual functions defined in the primary base are
|
|
|
|
|
followed by entries for new functions unique to this class. */
|
|
|
|
|
TYPE_BINFO_VIRTUALS (t)
|
2000-01-17 21:18:43 +01:00
|
|
|
|
= chainon (TYPE_BINFO_VIRTUALS (t), new_virtuals);
|
2000-01-17 23:54:23 +01:00
|
|
|
|
/* Finally, add entries for functions that override virtuals
|
|
|
|
|
from non-primary bases. */
|
|
|
|
|
TYPE_BINFO_VIRTUALS (t)
|
|
|
|
|
= chainon (TYPE_BINFO_VIRTUALS (t), overridden_virtuals);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
1999-12-21 03:11:10 +01:00
|
|
|
|
/* If we created a new vtbl pointer for this class, add it to the
|
|
|
|
|
list. */
|
|
|
|
|
if (TYPE_VFIELD (t) && CLASSTYPE_VFIELD_PARENT (t) == -1)
|
|
|
|
|
CLASSTYPE_VFIELDS (t)
|
|
|
|
|
= chainon (CLASSTYPE_VFIELDS (t), build_tree_list (NULL_TREE, t));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
2000-01-03 05:05:43 +01:00
|
|
|
|
finish_struct_bits (t);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
/* Complete the rtl for any static member objects of the type we're
|
|
|
|
|
working on. */
|
1999-12-16 04:10:12 +01:00
|
|
|
|
for (x = TYPE_FIELDS (t); x; x = TREE_CHAIN (x))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
|
|
|
|
if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x)
|
|
|
|
|
&& TREE_TYPE (x) == t)
|
|
|
|
|
{
|
|
|
|
|
DECL_MODE (x) = TYPE_MODE (t);
|
|
|
|
|
make_decl_rtl (x, NULL, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-07-09 18:15:04 +02:00
|
|
|
|
/* Done with FIELDS...now decide whether to sort these for
|
1999-12-16 04:10:12 +01:00
|
|
|
|
faster lookups later.
|
1999-07-09 18:15:04 +02:00
|
|
|
|
|
|
|
|
|
The C front-end only does this when n_fields > 15. We use
|
|
|
|
|
a smaller number because most searches fail (succeeding
|
|
|
|
|
ultimately as the search bores through the inheritance
|
|
|
|
|
hierarchy), and we want this failure to occur quickly. */
|
|
|
|
|
|
1999-12-16 04:10:12 +01:00
|
|
|
|
n_fields = count_fields (TYPE_FIELDS (t));
|
|
|
|
|
if (n_fields > 7)
|
1999-07-09 18:15:04 +02:00
|
|
|
|
{
|
|
|
|
|
tree field_vec = make_tree_vec (n_fields);
|
1999-12-16 04:10:12 +01:00
|
|
|
|
add_fields_to_vec (TYPE_FIELDS (t), field_vec, 0);
|
1999-07-09 18:15:04 +02:00
|
|
|
|
qsort (&TREE_VEC_ELT (field_vec, 0), n_fields, sizeof (tree),
|
|
|
|
|
(int (*)(const void *, const void *))field_decl_cmp);
|
|
|
|
|
if (! DECL_LANG_SPECIFIC (TYPE_MAIN_DECL (t)))
|
|
|
|
|
retrofit_lang_decl (TYPE_MAIN_DECL (t));
|
|
|
|
|
DECL_SORTED_FIELDS (TYPE_MAIN_DECL (t)) = field_vec;
|
|
|
|
|
}
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (TYPE_HAS_CONSTRUCTOR (t))
|
|
|
|
|
{
|
|
|
|
|
tree vfields = CLASSTYPE_VFIELDS (t);
|
|
|
|
|
|
|
|
|
|
while (vfields)
|
|
|
|
|
{
|
|
|
|
|
/* Mark the fact that constructor for T
|
|
|
|
|
could affect anybody inheriting from T
|
|
|
|
|
who wants to initialize vtables for VFIELDS's type. */
|
|
|
|
|
if (VF_DERIVED_VALUE (vfields))
|
|
|
|
|
TREE_ADDRESSABLE (vfields) = 1;
|
|
|
|
|
vfields = TREE_CHAIN (vfields);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-21 05:19:12 +01:00
|
|
|
|
/* Make the rtl for any new vtables we have created, and unmark
|
|
|
|
|
the base types we marked. */
|
|
|
|
|
finish_vtbls (t);
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (CLASSTYPE_VSIZE (t) != 0)
|
|
|
|
|
{
|
1996-07-11 03:13:25 +02:00
|
|
|
|
/* In addition to this one, all the other vfields should be listed. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
/* Before that can be done, we have to have FIELD_DECLs for them, and
|
|
|
|
|
a place to find them. */
|
1999-05-17 09:42:26 +02:00
|
|
|
|
TYPE_NONCOPIED_PARTS (t)
|
|
|
|
|
= tree_cons (default_conversion (TYPE_BINFO_VTABLE (t)),
|
1999-12-21 03:11:10 +01:00
|
|
|
|
TYPE_VFIELD (t), TYPE_NONCOPIED_PARTS (t));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (t)
|
1999-12-16 04:10:12 +01:00
|
|
|
|
&& DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1)) == NULL_TREE)
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_warning ("`%#T' has virtual functions but non-virtual destructor",
|
1994-02-24 02:02:37 +01:00
|
|
|
|
t);
|
|
|
|
|
}
|
|
|
|
|
|
1994-12-30 22:03:40 +01:00
|
|
|
|
hack_incomplete_structures (t);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1996-02-01 20:32:00 +01:00
|
|
|
|
if (warn_overloaded_virtual)
|
|
|
|
|
warn_hidden (t);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-11-16 02:37:39 +01:00
|
|
|
|
maybe_suppress_debug_info (t);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1996-12-18 03:46:25 +01:00
|
|
|
|
/* Finish debugging output for this type. */
|
|
|
|
|
rest_of_type_compilation (t, toplevel_bindings_p ());
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
1995-10-12 03:33:51 +01:00
|
|
|
|
|
1998-10-06 16:20:30 +02:00
|
|
|
|
/* When T was built up, the member declarations were added in reverse
|
|
|
|
|
order. Rearrange them to declaration order. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
unreverse_member_declarations (t)
|
|
|
|
|
tree t;
|
|
|
|
|
{
|
|
|
|
|
tree next;
|
|
|
|
|
tree prev;
|
|
|
|
|
tree x;
|
|
|
|
|
|
|
|
|
|
/* The TYPE_FIELDS, TYPE_METHODS, and CLASSTYPE_TAGS are all in
|
|
|
|
|
reverse order. Put them in declaration order now. */
|
|
|
|
|
TYPE_METHODS (t) = nreverse (TYPE_METHODS (t));
|
|
|
|
|
CLASSTYPE_TAGS (t) = nreverse (CLASSTYPE_TAGS (t));
|
|
|
|
|
|
|
|
|
|
/* Actually, for the TYPE_FIELDS, only the non TYPE_DECLs are in
|
|
|
|
|
reverse order, so we can't just use nreverse. */
|
|
|
|
|
prev = NULL_TREE;
|
|
|
|
|
for (x = TYPE_FIELDS (t);
|
|
|
|
|
x && TREE_CODE (x) != TYPE_DECL;
|
|
|
|
|
x = next)
|
|
|
|
|
{
|
|
|
|
|
next = TREE_CHAIN (x);
|
|
|
|
|
TREE_CHAIN (x) = prev;
|
|
|
|
|
prev = x;
|
|
|
|
|
}
|
|
|
|
|
if (prev)
|
|
|
|
|
{
|
|
|
|
|
TREE_CHAIN (TYPE_FIELDS (t)) = x;
|
|
|
|
|
if (prev)
|
|
|
|
|
TYPE_FIELDS (t) = prev;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1995-10-12 03:33:51 +01:00
|
|
|
|
tree
|
1999-07-21 10:52:14 +02:00
|
|
|
|
finish_struct (t, attributes)
|
1998-10-06 16:20:30 +02:00
|
|
|
|
tree t, attributes;
|
1995-10-12 03:33:51 +01:00
|
|
|
|
{
|
1998-10-06 16:20:30 +02:00
|
|
|
|
/* Now that we've got all the field declarations, reverse everything
|
|
|
|
|
as necessary. */
|
|
|
|
|
unreverse_member_declarations (t);
|
1995-10-12 03:33:51 +01:00
|
|
|
|
|
1996-08-09 00:08:30 +02:00
|
|
|
|
cplus_decl_attributes (t, attributes, NULL_TREE);
|
|
|
|
|
|
1996-02-28 23:01:56 +01:00
|
|
|
|
if (processing_template_decl)
|
1995-10-12 03:33:51 +01:00
|
|
|
|
{
|
1998-09-15 13:43:54 +02:00
|
|
|
|
finish_struct_methods (t);
|
1996-02-28 23:01:56 +01:00
|
|
|
|
TYPE_SIZE (t) = integer_zero_node;
|
1999-07-09 13:05:23 +02:00
|
|
|
|
}
|
1995-10-12 03:33:51 +01:00
|
|
|
|
else
|
1999-07-21 10:52:14 +02:00
|
|
|
|
finish_struct_1 (t);
|
1996-02-28 23:01:56 +01:00
|
|
|
|
|
|
|
|
|
TYPE_BEING_DEFINED (t) = 0;
|
tinfo.h (__class_type_info): Fix illegal declaration.
1999-04-02 Mark Mitchell <mark@codesourcery.com>
* tinfo.h (__class_type_info): Fix illegal declaration.
* cp-tree.def (TEMPLATE_ID_EXPR): Update comment.
* cp-tree.h (INHERITED_VALUE_BINDING_P): New macro.
(IDENTIFIER_CLASS_VALUE): Improve documentation.
(is_properly_derived_from): Declare.
(invalidate_class_lookup_cache): Likewise.
(maybe_maybe_note_name_used_in_class): Likewise.
(note_name_declared_in_class): Likewise.
(push_using_decl): Remove duplicate declaration.
(id_in_current_class): Remove declaration.
(push_class_binding): Change prototype.
(clear_identitifer_class_values): Declare.
* call.c (is_properly_derived_from): Make it global.
(build_new_function_call): Be careful about updating candidates.
(build_new_method_call): Handle COMPONENT_REFs. Don't crash when
asked to make illegal calls.
* class.c: Include splay-tree.h.
(class_stack_node): Add names_used slot.
(check_member_decl_is_same_in_complete_scope): Remove.
(add_method): Fix comment. Push the declaration into class
scope.
(finish_struct_1): When popping the class, pop the bindings too.
Remove check for data member/function member conflict.
(finish_struct): Remove calls to
check_member_decl_is_same_in_complete_scope. Change calls to
popclass.
(pushclass): Clear names_used in the class stack entry.
Use invalidate_class_lookup_cache to remove cached entries, rather
than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE
before entering a new class. Remove dead code. Don't mess with
current_function_decl when pushing declarations.
(invalidate_class_lookup_cache): New function, split out from ...
(popclass): Here. Clean up names_used on our way out.
(instantiate_type): Adjust.
(build_self_reference): Don't push the declaration here.
(maybe_note_name_used_in_class): New function.
(note_name_declared_in_class): Likewise.
* decl.c (add_binding): Change prototype.
(find_class_binding_level): New function.
(innermost_nonclass_level): Likewise.
(current_binding_level): Update documentation.
(inner_binding_level): Remove. Replace with current_binding_level
throughout.
(push_binding_level): Remove special handling of
class_binding_level.
(pop_binding_level): Likewise. Use find_class_binding_level.
(suspend_binding_level): Likewise.
(global_bindings_p): Use innermost_nonclass_level.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(pseudo_global_level_p): Likewise.
(push_binding): Clear INHERITED_VALUE_BINDING_P.
(add_binding): Check for illegal multiple declarations. Return a
value indicating whether or not the new binding was legal.
(push_local_binding): Skip over class binding levels. Check
return value from add_binding.
(push_class_binding): Set INHERITED_VALUE_BINDING_P. Call
note_name_declared_in_class.
(pushlevel_class): Remove "fake out the rest of the compiler"
code.
(poplevel_class): Reset IDENTIFIER_CLASS_VALUEs.
(clear_identifier_class_values): New function.
(pop_from_top_level): Use it.
(pop_everything): Tweak.
(maybe_process_template_type_declaration): Don't push the
declaration for the template here.
(pushtag): Don't push tag declarations into class scope here.
(pushdecl): Apply DeMorgan's law for readability.
(pushdecl_class_level): Remove special-case code for
TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions.
(push_class_level_bindng): Deal with inherited bindings.
(lookup_name_real): Remove special-case code for
TYPE_BEING_DEFINED, and some implicit typename magic.
(grokdeclarator): Handle COMPONENT_REF for a template function.
(build_enumerator): Don't call pushdecl_class_level here.
(id_in_current_class): Remove.
* decl2.c (grokfield): Don't call pushdecl_class_level or
check_template_shadow.
* errfn.c (cp_file_of): Don't declare.
(cp_line_of): Likewise.
* error.c (dump_decl): Handle an OVERLOAD.
(cp_file_of): Likewise.
(cp_line_of): Likewise.
* init.c (build_member_call): Handle a COMPONENT_REF.
* lex.c (do_identifier): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* method.c (hack_identifier): Build COMPONENT_REFs for references
to member templates as well as member functions. Remove dead
code.
* parse.y (left_curly): Remove.
(nonnested_type): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* parse.c: Regenerated.
(nested_name_specifier_1): Likewise.
* pt.c (check_explicit_specialization): Adjust, for robustness.
(check_template_shadow): Handle OVERLOADs.
(build_template_decl): Set DECL_CONSTRUCTOR_P on the
TEMPLATE_DECL, if appropriate.
* search.c (envelope_add_decl): Remove.
(dfs_pushdecls): Likewise.
(dfs_compress_decls): Likewise.
(dfs_push_decls): New function.
(dfs_push_type_decls): Likewise.
(setup_class_bindings): Likewise.
(template_self_reference_p): Likewise.
(lookup_field_r): Use it.
(looup_member): Remove old comment. Deal with ambiguity.
(push_class_decls): Use dfs_push_decls and dfs_push_type_decls,
and remove envelope processing.
* semantics.c (begin_class_definition): Let pushclass push
declarations for base classes.
(finish_member_declaration): Push declarations into class scope.
* typeck.c (build_component_ref): Just put an OVERLOAD into the
COMPONENT_REF, not a TREE_LIST of an OVERLOAD.
(build_x_function_call): Deal with OVERLOAD. Handle template-ids.
* Makefile.in (class.o): Depend on splay-tree.h.
From-SVN: r26133
1999-04-02 17:36:57 +02:00
|
|
|
|
|
1996-02-28 23:01:56 +01:00
|
|
|
|
if (current_class_type)
|
1999-04-14 15:20:19 +02:00
|
|
|
|
popclass ();
|
1996-02-28 23:01:56 +01:00
|
|
|
|
else
|
1998-09-07 16:25:35 +02:00
|
|
|
|
error ("trying to finish struct, but kicked out due to previous parse errors.");
|
1996-02-28 23:01:56 +01:00
|
|
|
|
|
1999-11-16 02:37:39 +01:00
|
|
|
|
if (processing_template_decl)
|
|
|
|
|
{
|
|
|
|
|
tree scope = current_scope ();
|
|
|
|
|
if (scope && TREE_CODE (scope) == FUNCTION_DECL)
|
|
|
|
|
add_tree (build_min (TAG_DEFN, t));
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-28 23:01:56 +01:00
|
|
|
|
return t;
|
1995-10-12 03:33:51 +01:00
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1998-08-25 03:48:47 +02:00
|
|
|
|
/* Return the dynamic type of INSTANCE, if known.
|
1994-02-24 02:02:37 +01:00
|
|
|
|
Used to determine whether the virtual function table is needed
|
|
|
|
|
or not.
|
|
|
|
|
|
|
|
|
|
*NONNULL is set iff INSTANCE can be known to be nonnull, regardless
|
2000-01-18 05:52:50 +01:00
|
|
|
|
of our knowledge of its type. *NONNULL should be initialized
|
|
|
|
|
before this function is called. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
Warning fixes:
* call.c (op_error): Const-ify a char*.
(add_candidate, source_type, add_warning): Add static prototype.
(print_z_candidates): Const-ify a char*.
* class.c (resolve_address_of_overloaded_function,
fixed_type_or_null, build_vtable_entry_ref): Add static prototype.
(get_vtable_name, finish_struct_1): Const-ify a char*.
* cvt.c (convert_to_reference): Likewise.
* decl.c (redeclaration_error_message, record_builtin_type,
record_unknown_type, member_function_or_else, bad_specifiers):
Likewise.
(find_binding, select_decl, unqualified_namespace_lookup,
lookup_flags, qualify_lookup, record_builtin_java_type, tag_name):
Add static prototype.
(warn_extern_redeclared_static, duplicate_decls, pushdecl,
implicitly_declare, record_builtin_java_type, define_function,
grok_op_properties, tag_name): Const-ify a char*.
* cp-tree.h (FORMAT_VBASE_NAME): Allow parameter `BUF' to be const.
(define_function, finish_builtin_type): Const-ify a char*.
(cp_error, cp_error_at, cp_warning, cp_warning_at, cp_pedwarn,
cp_pedwarn_at, cp_compiler_error, cp_sprintf): Add prototype args.
(file_name_nondirectory): Const-ify a char*.
(init_filename_times): Don't prototype.
(compiler_error): Prototype.
(yyerror, init_repo): Const-ify a char*.
(build_srcloc): Don't prototype.
(build_x_indirect_ref, build_indirect_ref, build_component_addr):
Const-ify a char*.
(warn_for_assignment): Don't prototype.
(convert_for_initialization, readonly_error, check_for_new_type,
GNU_xref_begin, GNU_xref_file, GNU_xref_ref, GNU_xref_call):
Const-ify a char*.
* decl2.c (acceptable_java_type, output_vtable_inherit,
setup_initp, start_objects, finish_objects, do_dtors, do_ctors,
merge_functions, decl_namespace, validate_nonmember_using_decl,
do_nonmember_using_decl): Add static prototype.
(lang_f_options): Const-ify a char*.
(finish_builtin_type): Likewise.
(add_function, arg_assoc_namespace, arg_assoc_class): Add static
prototype.
* errfn.c: Include cp-tree.h.
(cp_thing): Add static prototype.
(compiler_error): Don't protoptype.
(cp_compiler_error): Cast `compiler_error' to `errorfn' before
passing it to `cp_thing'.
* error.c (interesting_scope_p): Add static prototype.
* except.c (build_eh_type_type, build_eh_type_type_ref): Const-ify
a char*.
* init.c (compiler_error): Don't prototype.
(member_init_ok_or_else): Const-ify a char*.
(build_java_class_ref): Add static prototype.
* lex.c (compiler_error): Don't prototype.
(get_time_identifier, interface_strcmp, extend_token_buffer,
handle_cp_pragma): Const-ify a char*.
(is_global, init_filename_times): Add static prototype.
(file_name_nondirectory, cplus_tree_code_name): Const-ify a char*.
(compiler_error): Change from fixed args to variable args.
(yyerror): Const-ify a char*.
* parse.y (cond_stmt_keyword): Const-ify a char*.
(parse_decl): Add static prototype.
* pt.c (template_args_equal, print_template_context): Likewise.
(print_candidates, check_default_tmpl_args): Const-ify a char*.
(instantiate_class_template): Likewise.
* repo.c (get_base_filename, open_repo_file, init_repo): Likewise.
* rtti.c (call_void_fn, expand_generic_desc, expand_si_desc,
expand_class_desc, expand_ptr_desc, expand_attr_desc): Likewise.
* search.c (lookup_field_info, lookup_member): Likewise.
(lookup_member): Cast the first argument of `bzero' to a PTR.
* sig.c (compiler_error): Don't prototype.
(build_signature_pointer_or_reference_nam): Const-ify a char*.
(get_sigtable_name, build_member_function_pointer): Likewise.
* tree.c (compiler_error): Don't prototype.
(no_linkage_helper, build_srcloc): Add static prototype.
(build_vbase_pointer_fields): Const-ify a char*.
(__eprintf): Don't unnecessarily handle `const' when !__STDC__.
* typeck.c (compiler_error): Don't prototype.
(convert_for_assignment): Const-ify a char*.
(comp_cv_target_types): Add static prototype.
(build_x_indirect_ref, build_indirect_ref, convert_arguments,
build_component_addr, build_unary_op, convert_for_initialization):
Const-ify a char*.
* typeck2.c (ack): Add static prototype and change from fixed args
to variable args.
(readonly_error, check_for_new_type): Const-ify a char*.
* xref.c (_XREF_FILE, find_file, filename, fctname, declname,
fixname, open_xref_file, classname, GNU_xref_begin): Likewise.
(GNU_xref_file): Likewise. Also use `xmalloc' instead of `malloc'.
(GNU_xref_end_scope, GNU_xref_ref, GNU_xref_decl, GNU_xref_call,
gen_assign, GNU_xref_member): Const-ify a char*.
From-SVN: r25994
1999-03-26 08:45:00 +01:00
|
|
|
|
static tree
|
1998-08-25 03:48:47 +02:00
|
|
|
|
fixed_type_or_null (instance, nonnull)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
tree instance;
|
|
|
|
|
int *nonnull;
|
|
|
|
|
{
|
|
|
|
|
switch (TREE_CODE (instance))
|
|
|
|
|
{
|
|
|
|
|
case INDIRECT_REF:
|
|
|
|
|
/* Check that we are not going through a cast of some sort. */
|
|
|
|
|
if (TREE_TYPE (instance)
|
|
|
|
|
== TREE_TYPE (TREE_TYPE (TREE_OPERAND (instance, 0))))
|
|
|
|
|
instance = TREE_OPERAND (instance, 0);
|
|
|
|
|
/* fall through... */
|
|
|
|
|
case CALL_EXPR:
|
|
|
|
|
/* This is a call to a constructor, hence it's never zero. */
|
|
|
|
|
if (TREE_HAS_CONSTRUCTOR (instance))
|
|
|
|
|
{
|
|
|
|
|
if (nonnull)
|
|
|
|
|
*nonnull = 1;
|
1998-08-25 03:48:47 +02:00
|
|
|
|
return TREE_TYPE (instance);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
1998-08-25 03:48:47 +02:00
|
|
|
|
return NULL_TREE;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
case SAVE_EXPR:
|
|
|
|
|
/* This is a call to a constructor, hence it's never zero. */
|
|
|
|
|
if (TREE_HAS_CONSTRUCTOR (instance))
|
|
|
|
|
{
|
|
|
|
|
if (nonnull)
|
|
|
|
|
*nonnull = 1;
|
1998-08-25 03:48:47 +02:00
|
|
|
|
return TREE_TYPE (instance);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
1998-08-25 03:48:47 +02:00
|
|
|
|
return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
case RTL_EXPR:
|
1998-08-25 03:48:47 +02:00
|
|
|
|
return NULL_TREE;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
case PLUS_EXPR:
|
|
|
|
|
case MINUS_EXPR:
|
|
|
|
|
if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
|
|
|
|
|
/* Propagate nonnull. */
|
1998-08-25 03:48:47 +02:00
|
|
|
|
fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
|
1998-08-25 03:48:47 +02:00
|
|
|
|
return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull);
|
|
|
|
|
return NULL_TREE;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
case NOP_EXPR:
|
|
|
|
|
case CONVERT_EXPR:
|
1998-08-25 03:48:47 +02:00
|
|
|
|
return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
case ADDR_EXPR:
|
|
|
|
|
if (nonnull)
|
|
|
|
|
*nonnull = 1;
|
1998-08-25 03:48:47 +02:00
|
|
|
|
return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
case COMPONENT_REF:
|
1998-08-25 03:48:47 +02:00
|
|
|
|
return fixed_type_or_null (TREE_OPERAND (instance, 1), nonnull);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
case VAR_DECL:
|
|
|
|
|
case FIELD_DECL:
|
|
|
|
|
if (TREE_CODE (TREE_TYPE (instance)) == ARRAY_TYPE
|
|
|
|
|
&& IS_AGGR_TYPE (TREE_TYPE (TREE_TYPE (instance))))
|
|
|
|
|
{
|
|
|
|
|
if (nonnull)
|
|
|
|
|
*nonnull = 1;
|
1998-08-25 03:48:47 +02:00
|
|
|
|
return TREE_TYPE (TREE_TYPE (instance));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
1996-07-11 03:13:25 +02:00
|
|
|
|
/* fall through... */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
case TARGET_EXPR:
|
|
|
|
|
case PARM_DECL:
|
|
|
|
|
if (IS_AGGR_TYPE (TREE_TYPE (instance)))
|
|
|
|
|
{
|
|
|
|
|
if (nonnull)
|
|
|
|
|
*nonnull = 1;
|
1998-08-25 03:48:47 +02:00
|
|
|
|
return TREE_TYPE (instance);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
else if (nonnull)
|
|
|
|
|
{
|
1996-05-16 20:43:00 +02:00
|
|
|
|
if (instance == current_class_ptr
|
1994-02-24 02:02:37 +01:00
|
|
|
|
&& flag_this_is_variable <= 0)
|
|
|
|
|
{
|
1998-08-25 03:48:47 +02:00
|
|
|
|
/* Normally, 'this' must be non-null. */
|
|
|
|
|
if (flag_this_is_variable == 0)
|
|
|
|
|
*nonnull = 1;
|
|
|
|
|
|
|
|
|
|
/* <0 means we're in a constructor and we know our type. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (flag_this_is_variable < 0)
|
1998-08-25 03:48:47 +02:00
|
|
|
|
return TREE_TYPE (TREE_TYPE (instance));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
|
|
|
|
|
/* Reference variables should be references to objects. */
|
|
|
|
|
*nonnull = 1;
|
|
|
|
|
}
|
1998-08-25 03:48:47 +02:00
|
|
|
|
return NULL_TREE;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
default:
|
1998-08-25 03:48:47 +02:00
|
|
|
|
return NULL_TREE;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
1998-08-25 03:48:47 +02:00
|
|
|
|
|
|
|
|
|
/* Return non-zero if the dynamic type of INSTANCE is known, and equivalent
|
|
|
|
|
to the static type. We also handle the case where INSTANCE is really
|
|
|
|
|
a pointer.
|
|
|
|
|
|
|
|
|
|
Used to determine whether the virtual function table is needed
|
|
|
|
|
or not.
|
|
|
|
|
|
|
|
|
|
*NONNULL is set iff INSTANCE can be known to be nonnull, regardless
|
2000-01-18 05:52:50 +01:00
|
|
|
|
of our knowledge of its type. *NONNULL should be initialized
|
|
|
|
|
before this function is called. */
|
1998-08-25 03:48:47 +02:00
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
resolves_to_fixed_type_p (instance, nonnull)
|
|
|
|
|
tree instance;
|
|
|
|
|
int *nonnull;
|
|
|
|
|
{
|
|
|
|
|
tree t = TREE_TYPE (instance);
|
|
|
|
|
tree fixed = fixed_type_or_null (instance, nonnull);
|
|
|
|
|
if (fixed == NULL_TREE)
|
|
|
|
|
return 0;
|
|
|
|
|
if (POINTER_TYPE_P (t))
|
|
|
|
|
t = TREE_TYPE (t);
|
1998-11-01 16:45:11 +01:00
|
|
|
|
return same_type_p (TYPE_MAIN_VARIANT (t), TYPE_MAIN_VARIANT (fixed));
|
1998-08-25 03:48:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
init_class_processing ()
|
|
|
|
|
{
|
|
|
|
|
current_class_depth = 0;
|
1998-10-06 16:20:30 +02:00
|
|
|
|
current_class_stack_size = 10;
|
|
|
|
|
current_class_stack
|
|
|
|
|
= (class_stack_node_t) xmalloc (current_class_stack_size
|
|
|
|
|
* sizeof (struct class_stack_node));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1996-01-17 19:57:55 +01:00
|
|
|
|
access_default_node = build_int_2 (0, 0);
|
|
|
|
|
access_public_node = build_int_2 (1, 0);
|
|
|
|
|
access_protected_node = build_int_2 (2, 0);
|
|
|
|
|
access_private_node = build_int_2 (3, 0);
|
|
|
|
|
access_default_virtual_node = build_int_2 (4, 0);
|
|
|
|
|
access_public_virtual_node = build_int_2 (5, 0);
|
1998-02-13 01:30:37 +01:00
|
|
|
|
access_protected_virtual_node = build_int_2 (6, 0);
|
|
|
|
|
access_private_virtual_node = build_int_2 (7, 0);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Set current scope to NAME. CODE tells us if this is a
|
|
|
|
|
STRUCT, UNION, or ENUM environment.
|
|
|
|
|
|
|
|
|
|
NAME may end up being NULL_TREE if this is an anonymous or
|
|
|
|
|
late-bound struct (as in "struct { ... } foo;") */
|
|
|
|
|
|
|
|
|
|
/* Set global variables CURRENT_CLASS_NAME and CURRENT_CLASS_TYPE to
|
|
|
|
|
appropriate values, found by looking up the type definition of
|
|
|
|
|
NAME (as a CODE).
|
|
|
|
|
|
|
|
|
|
If MODIFY is 1, we set IDENTIFIER_CLASS_VALUE's of names
|
|
|
|
|
which can be seen locally to the class. They are shadowed by
|
|
|
|
|
any subsequent local declaration (including parameter names).
|
|
|
|
|
|
|
|
|
|
If MODIFY is 2, we set IDENTIFIER_CLASS_VALUE's of names
|
|
|
|
|
which have static meaning (i.e., static members, static
|
|
|
|
|
member functions, enum declarations, etc).
|
|
|
|
|
|
|
|
|
|
If MODIFY is 3, we set IDENTIFIER_CLASS_VALUE of names
|
|
|
|
|
which can be seen locally to the class (as in 1), but
|
|
|
|
|
know that we are doing this for declaration purposes
|
|
|
|
|
(i.e. friend foo::bar (int)).
|
|
|
|
|
|
|
|
|
|
So that we may avoid calls to lookup_name, we cache the _TYPE
|
|
|
|
|
nodes of local TYPE_DECLs in the TREE_TYPE field of the name.
|
|
|
|
|
|
|
|
|
|
For multiple inheritance, we perform a two-pass depth-first search
|
|
|
|
|
of the type lattice. The first pass performs a pre-order search,
|
|
|
|
|
marking types after the type has had its fields installed in
|
|
|
|
|
the appropriate IDENTIFIER_CLASS_VALUE slot. The second pass merely
|
|
|
|
|
unmarks the marked types. If a field or member function name
|
|
|
|
|
appears in an ambiguous way, the IDENTIFIER_CLASS_VALUE of
|
|
|
|
|
that name becomes `error_mark_node'. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
pushclass (type, modify)
|
|
|
|
|
tree type;
|
|
|
|
|
int modify;
|
|
|
|
|
{
|
1998-05-26 13:43:52 +02:00
|
|
|
|
type = TYPE_MAIN_VARIANT (type);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1998-10-06 16:20:30 +02:00
|
|
|
|
/* Make sure there is enough room for the new entry on the stack. */
|
|
|
|
|
if (current_class_depth + 1 >= current_class_stack_size)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1998-10-06 16:20:30 +02:00
|
|
|
|
current_class_stack_size *= 2;
|
|
|
|
|
current_class_stack
|
|
|
|
|
= (class_stack_node_t) xrealloc (current_class_stack,
|
|
|
|
|
current_class_stack_size
|
|
|
|
|
* sizeof (struct class_stack_node));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
1998-10-06 16:20:30 +02:00
|
|
|
|
/* Insert a new entry on the class stack. */
|
|
|
|
|
current_class_stack[current_class_depth].name = current_class_name;
|
|
|
|
|
current_class_stack[current_class_depth].type = current_class_type;
|
|
|
|
|
current_class_stack[current_class_depth].access = current_access_specifier;
|
tinfo.h (__class_type_info): Fix illegal declaration.
1999-04-02 Mark Mitchell <mark@codesourcery.com>
* tinfo.h (__class_type_info): Fix illegal declaration.
* cp-tree.def (TEMPLATE_ID_EXPR): Update comment.
* cp-tree.h (INHERITED_VALUE_BINDING_P): New macro.
(IDENTIFIER_CLASS_VALUE): Improve documentation.
(is_properly_derived_from): Declare.
(invalidate_class_lookup_cache): Likewise.
(maybe_maybe_note_name_used_in_class): Likewise.
(note_name_declared_in_class): Likewise.
(push_using_decl): Remove duplicate declaration.
(id_in_current_class): Remove declaration.
(push_class_binding): Change prototype.
(clear_identitifer_class_values): Declare.
* call.c (is_properly_derived_from): Make it global.
(build_new_function_call): Be careful about updating candidates.
(build_new_method_call): Handle COMPONENT_REFs. Don't crash when
asked to make illegal calls.
* class.c: Include splay-tree.h.
(class_stack_node): Add names_used slot.
(check_member_decl_is_same_in_complete_scope): Remove.
(add_method): Fix comment. Push the declaration into class
scope.
(finish_struct_1): When popping the class, pop the bindings too.
Remove check for data member/function member conflict.
(finish_struct): Remove calls to
check_member_decl_is_same_in_complete_scope. Change calls to
popclass.
(pushclass): Clear names_used in the class stack entry.
Use invalidate_class_lookup_cache to remove cached entries, rather
than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE
before entering a new class. Remove dead code. Don't mess with
current_function_decl when pushing declarations.
(invalidate_class_lookup_cache): New function, split out from ...
(popclass): Here. Clean up names_used on our way out.
(instantiate_type): Adjust.
(build_self_reference): Don't push the declaration here.
(maybe_note_name_used_in_class): New function.
(note_name_declared_in_class): Likewise.
* decl.c (add_binding): Change prototype.
(find_class_binding_level): New function.
(innermost_nonclass_level): Likewise.
(current_binding_level): Update documentation.
(inner_binding_level): Remove. Replace with current_binding_level
throughout.
(push_binding_level): Remove special handling of
class_binding_level.
(pop_binding_level): Likewise. Use find_class_binding_level.
(suspend_binding_level): Likewise.
(global_bindings_p): Use innermost_nonclass_level.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(pseudo_global_level_p): Likewise.
(push_binding): Clear INHERITED_VALUE_BINDING_P.
(add_binding): Check for illegal multiple declarations. Return a
value indicating whether or not the new binding was legal.
(push_local_binding): Skip over class binding levels. Check
return value from add_binding.
(push_class_binding): Set INHERITED_VALUE_BINDING_P. Call
note_name_declared_in_class.
(pushlevel_class): Remove "fake out the rest of the compiler"
code.
(poplevel_class): Reset IDENTIFIER_CLASS_VALUEs.
(clear_identifier_class_values): New function.
(pop_from_top_level): Use it.
(pop_everything): Tweak.
(maybe_process_template_type_declaration): Don't push the
declaration for the template here.
(pushtag): Don't push tag declarations into class scope here.
(pushdecl): Apply DeMorgan's law for readability.
(pushdecl_class_level): Remove special-case code for
TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions.
(push_class_level_bindng): Deal with inherited bindings.
(lookup_name_real): Remove special-case code for
TYPE_BEING_DEFINED, and some implicit typename magic.
(grokdeclarator): Handle COMPONENT_REF for a template function.
(build_enumerator): Don't call pushdecl_class_level here.
(id_in_current_class): Remove.
* decl2.c (grokfield): Don't call pushdecl_class_level or
check_template_shadow.
* errfn.c (cp_file_of): Don't declare.
(cp_line_of): Likewise.
* error.c (dump_decl): Handle an OVERLOAD.
(cp_file_of): Likewise.
(cp_line_of): Likewise.
* init.c (build_member_call): Handle a COMPONENT_REF.
* lex.c (do_identifier): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* method.c (hack_identifier): Build COMPONENT_REFs for references
to member templates as well as member functions. Remove dead
code.
* parse.y (left_curly): Remove.
(nonnested_type): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* parse.c: Regenerated.
(nested_name_specifier_1): Likewise.
* pt.c (check_explicit_specialization): Adjust, for robustness.
(check_template_shadow): Handle OVERLOADs.
(build_template_decl): Set DECL_CONSTRUCTOR_P on the
TEMPLATE_DECL, if appropriate.
* search.c (envelope_add_decl): Remove.
(dfs_pushdecls): Likewise.
(dfs_compress_decls): Likewise.
(dfs_push_decls): New function.
(dfs_push_type_decls): Likewise.
(setup_class_bindings): Likewise.
(template_self_reference_p): Likewise.
(lookup_field_r): Use it.
(looup_member): Remove old comment. Deal with ambiguity.
(push_class_decls): Use dfs_push_decls and dfs_push_type_decls,
and remove envelope processing.
* semantics.c (begin_class_definition): Let pushclass push
declarations for base classes.
(finish_member_declaration): Push declarations into class scope.
* typeck.c (build_component_ref): Just put an OVERLOAD into the
COMPONENT_REF, not a TREE_LIST of an OVERLOAD.
(build_x_function_call): Deal with OVERLOAD. Handle template-ids.
* Makefile.in (class.o): Depend on splay-tree.h.
From-SVN: r26133
1999-04-02 17:36:57 +02:00
|
|
|
|
current_class_stack[current_class_depth].names_used = 0;
|
1998-10-06 16:20:30 +02:00
|
|
|
|
current_class_depth++;
|
|
|
|
|
|
|
|
|
|
/* Now set up the new type. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
current_class_name = TYPE_NAME (type);
|
|
|
|
|
if (TREE_CODE (current_class_name) == TYPE_DECL)
|
|
|
|
|
current_class_name = DECL_NAME (current_class_name);
|
|
|
|
|
current_class_type = type;
|
|
|
|
|
|
1998-10-06 16:20:30 +02:00
|
|
|
|
/* By default, things in classes are private, while things in
|
|
|
|
|
structures or unions are public. */
|
|
|
|
|
current_access_specifier = (CLASSTYPE_DECLARED_CLASS (type)
|
|
|
|
|
? access_private_node
|
|
|
|
|
: access_public_node);
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (previous_class_type != NULL_TREE
|
tinfo.h (__class_type_info): Fix illegal declaration.
1999-04-02 Mark Mitchell <mark@codesourcery.com>
* tinfo.h (__class_type_info): Fix illegal declaration.
* cp-tree.def (TEMPLATE_ID_EXPR): Update comment.
* cp-tree.h (INHERITED_VALUE_BINDING_P): New macro.
(IDENTIFIER_CLASS_VALUE): Improve documentation.
(is_properly_derived_from): Declare.
(invalidate_class_lookup_cache): Likewise.
(maybe_maybe_note_name_used_in_class): Likewise.
(note_name_declared_in_class): Likewise.
(push_using_decl): Remove duplicate declaration.
(id_in_current_class): Remove declaration.
(push_class_binding): Change prototype.
(clear_identitifer_class_values): Declare.
* call.c (is_properly_derived_from): Make it global.
(build_new_function_call): Be careful about updating candidates.
(build_new_method_call): Handle COMPONENT_REFs. Don't crash when
asked to make illegal calls.
* class.c: Include splay-tree.h.
(class_stack_node): Add names_used slot.
(check_member_decl_is_same_in_complete_scope): Remove.
(add_method): Fix comment. Push the declaration into class
scope.
(finish_struct_1): When popping the class, pop the bindings too.
Remove check for data member/function member conflict.
(finish_struct): Remove calls to
check_member_decl_is_same_in_complete_scope. Change calls to
popclass.
(pushclass): Clear names_used in the class stack entry.
Use invalidate_class_lookup_cache to remove cached entries, rather
than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE
before entering a new class. Remove dead code. Don't mess with
current_function_decl when pushing declarations.
(invalidate_class_lookup_cache): New function, split out from ...
(popclass): Here. Clean up names_used on our way out.
(instantiate_type): Adjust.
(build_self_reference): Don't push the declaration here.
(maybe_note_name_used_in_class): New function.
(note_name_declared_in_class): Likewise.
* decl.c (add_binding): Change prototype.
(find_class_binding_level): New function.
(innermost_nonclass_level): Likewise.
(current_binding_level): Update documentation.
(inner_binding_level): Remove. Replace with current_binding_level
throughout.
(push_binding_level): Remove special handling of
class_binding_level.
(pop_binding_level): Likewise. Use find_class_binding_level.
(suspend_binding_level): Likewise.
(global_bindings_p): Use innermost_nonclass_level.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(pseudo_global_level_p): Likewise.
(push_binding): Clear INHERITED_VALUE_BINDING_P.
(add_binding): Check for illegal multiple declarations. Return a
value indicating whether or not the new binding was legal.
(push_local_binding): Skip over class binding levels. Check
return value from add_binding.
(push_class_binding): Set INHERITED_VALUE_BINDING_P. Call
note_name_declared_in_class.
(pushlevel_class): Remove "fake out the rest of the compiler"
code.
(poplevel_class): Reset IDENTIFIER_CLASS_VALUEs.
(clear_identifier_class_values): New function.
(pop_from_top_level): Use it.
(pop_everything): Tweak.
(maybe_process_template_type_declaration): Don't push the
declaration for the template here.
(pushtag): Don't push tag declarations into class scope here.
(pushdecl): Apply DeMorgan's law for readability.
(pushdecl_class_level): Remove special-case code for
TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions.
(push_class_level_bindng): Deal with inherited bindings.
(lookup_name_real): Remove special-case code for
TYPE_BEING_DEFINED, and some implicit typename magic.
(grokdeclarator): Handle COMPONENT_REF for a template function.
(build_enumerator): Don't call pushdecl_class_level here.
(id_in_current_class): Remove.
* decl2.c (grokfield): Don't call pushdecl_class_level or
check_template_shadow.
* errfn.c (cp_file_of): Don't declare.
(cp_line_of): Likewise.
* error.c (dump_decl): Handle an OVERLOAD.
(cp_file_of): Likewise.
(cp_line_of): Likewise.
* init.c (build_member_call): Handle a COMPONENT_REF.
* lex.c (do_identifier): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* method.c (hack_identifier): Build COMPONENT_REFs for references
to member templates as well as member functions. Remove dead
code.
* parse.y (left_curly): Remove.
(nonnested_type): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* parse.c: Regenerated.
(nested_name_specifier_1): Likewise.
* pt.c (check_explicit_specialization): Adjust, for robustness.
(check_template_shadow): Handle OVERLOADs.
(build_template_decl): Set DECL_CONSTRUCTOR_P on the
TEMPLATE_DECL, if appropriate.
* search.c (envelope_add_decl): Remove.
(dfs_pushdecls): Likewise.
(dfs_compress_decls): Likewise.
(dfs_push_decls): New function.
(dfs_push_type_decls): Likewise.
(setup_class_bindings): Likewise.
(template_self_reference_p): Likewise.
(lookup_field_r): Use it.
(looup_member): Remove old comment. Deal with ambiguity.
(push_class_decls): Use dfs_push_decls and dfs_push_type_decls,
and remove envelope processing.
* semantics.c (begin_class_definition): Let pushclass push
declarations for base classes.
(finish_member_declaration): Push declarations into class scope.
* typeck.c (build_component_ref): Just put an OVERLOAD into the
COMPONENT_REF, not a TREE_LIST of an OVERLOAD.
(build_x_function_call): Deal with OVERLOAD. Handle template-ids.
* Makefile.in (class.o): Depend on splay-tree.h.
From-SVN: r26133
1999-04-02 17:36:57 +02:00
|
|
|
|
&& (type != previous_class_type
|
|
|
|
|
|| TYPE_SIZE (previous_class_type) == NULL_TREE)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
&& current_class_depth == 1)
|
|
|
|
|
{
|
|
|
|
|
/* Forcibly remove any old class remnants. */
|
tinfo.h (__class_type_info): Fix illegal declaration.
1999-04-02 Mark Mitchell <mark@codesourcery.com>
* tinfo.h (__class_type_info): Fix illegal declaration.
* cp-tree.def (TEMPLATE_ID_EXPR): Update comment.
* cp-tree.h (INHERITED_VALUE_BINDING_P): New macro.
(IDENTIFIER_CLASS_VALUE): Improve documentation.
(is_properly_derived_from): Declare.
(invalidate_class_lookup_cache): Likewise.
(maybe_maybe_note_name_used_in_class): Likewise.
(note_name_declared_in_class): Likewise.
(push_using_decl): Remove duplicate declaration.
(id_in_current_class): Remove declaration.
(push_class_binding): Change prototype.
(clear_identitifer_class_values): Declare.
* call.c (is_properly_derived_from): Make it global.
(build_new_function_call): Be careful about updating candidates.
(build_new_method_call): Handle COMPONENT_REFs. Don't crash when
asked to make illegal calls.
* class.c: Include splay-tree.h.
(class_stack_node): Add names_used slot.
(check_member_decl_is_same_in_complete_scope): Remove.
(add_method): Fix comment. Push the declaration into class
scope.
(finish_struct_1): When popping the class, pop the bindings too.
Remove check for data member/function member conflict.
(finish_struct): Remove calls to
check_member_decl_is_same_in_complete_scope. Change calls to
popclass.
(pushclass): Clear names_used in the class stack entry.
Use invalidate_class_lookup_cache to remove cached entries, rather
than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE
before entering a new class. Remove dead code. Don't mess with
current_function_decl when pushing declarations.
(invalidate_class_lookup_cache): New function, split out from ...
(popclass): Here. Clean up names_used on our way out.
(instantiate_type): Adjust.
(build_self_reference): Don't push the declaration here.
(maybe_note_name_used_in_class): New function.
(note_name_declared_in_class): Likewise.
* decl.c (add_binding): Change prototype.
(find_class_binding_level): New function.
(innermost_nonclass_level): Likewise.
(current_binding_level): Update documentation.
(inner_binding_level): Remove. Replace with current_binding_level
throughout.
(push_binding_level): Remove special handling of
class_binding_level.
(pop_binding_level): Likewise. Use find_class_binding_level.
(suspend_binding_level): Likewise.
(global_bindings_p): Use innermost_nonclass_level.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(pseudo_global_level_p): Likewise.
(push_binding): Clear INHERITED_VALUE_BINDING_P.
(add_binding): Check for illegal multiple declarations. Return a
value indicating whether or not the new binding was legal.
(push_local_binding): Skip over class binding levels. Check
return value from add_binding.
(push_class_binding): Set INHERITED_VALUE_BINDING_P. Call
note_name_declared_in_class.
(pushlevel_class): Remove "fake out the rest of the compiler"
code.
(poplevel_class): Reset IDENTIFIER_CLASS_VALUEs.
(clear_identifier_class_values): New function.
(pop_from_top_level): Use it.
(pop_everything): Tweak.
(maybe_process_template_type_declaration): Don't push the
declaration for the template here.
(pushtag): Don't push tag declarations into class scope here.
(pushdecl): Apply DeMorgan's law for readability.
(pushdecl_class_level): Remove special-case code for
TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions.
(push_class_level_bindng): Deal with inherited bindings.
(lookup_name_real): Remove special-case code for
TYPE_BEING_DEFINED, and some implicit typename magic.
(grokdeclarator): Handle COMPONENT_REF for a template function.
(build_enumerator): Don't call pushdecl_class_level here.
(id_in_current_class): Remove.
* decl2.c (grokfield): Don't call pushdecl_class_level or
check_template_shadow.
* errfn.c (cp_file_of): Don't declare.
(cp_line_of): Likewise.
* error.c (dump_decl): Handle an OVERLOAD.
(cp_file_of): Likewise.
(cp_line_of): Likewise.
* init.c (build_member_call): Handle a COMPONENT_REF.
* lex.c (do_identifier): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* method.c (hack_identifier): Build COMPONENT_REFs for references
to member templates as well as member functions. Remove dead
code.
* parse.y (left_curly): Remove.
(nonnested_type): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* parse.c: Regenerated.
(nested_name_specifier_1): Likewise.
* pt.c (check_explicit_specialization): Adjust, for robustness.
(check_template_shadow): Handle OVERLOADs.
(build_template_decl): Set DECL_CONSTRUCTOR_P on the
TEMPLATE_DECL, if appropriate.
* search.c (envelope_add_decl): Remove.
(dfs_pushdecls): Likewise.
(dfs_compress_decls): Likewise.
(dfs_push_decls): New function.
(dfs_push_type_decls): Likewise.
(setup_class_bindings): Likewise.
(template_self_reference_p): Likewise.
(lookup_field_r): Use it.
(looup_member): Remove old comment. Deal with ambiguity.
(push_class_decls): Use dfs_push_decls and dfs_push_type_decls,
and remove envelope processing.
* semantics.c (begin_class_definition): Let pushclass push
declarations for base classes.
(finish_member_declaration): Push declarations into class scope.
* typeck.c (build_component_ref): Just put an OVERLOAD into the
COMPONENT_REF, not a TREE_LIST of an OVERLOAD.
(build_x_function_call): Deal with OVERLOAD. Handle template-ids.
* Makefile.in (class.o): Depend on splay-tree.h.
From-SVN: r26133
1999-04-02 17:36:57 +02:00
|
|
|
|
invalidate_class_lookup_cache ();
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
tinfo.h (__class_type_info): Fix illegal declaration.
1999-04-02 Mark Mitchell <mark@codesourcery.com>
* tinfo.h (__class_type_info): Fix illegal declaration.
* cp-tree.def (TEMPLATE_ID_EXPR): Update comment.
* cp-tree.h (INHERITED_VALUE_BINDING_P): New macro.
(IDENTIFIER_CLASS_VALUE): Improve documentation.
(is_properly_derived_from): Declare.
(invalidate_class_lookup_cache): Likewise.
(maybe_maybe_note_name_used_in_class): Likewise.
(note_name_declared_in_class): Likewise.
(push_using_decl): Remove duplicate declaration.
(id_in_current_class): Remove declaration.
(push_class_binding): Change prototype.
(clear_identitifer_class_values): Declare.
* call.c (is_properly_derived_from): Make it global.
(build_new_function_call): Be careful about updating candidates.
(build_new_method_call): Handle COMPONENT_REFs. Don't crash when
asked to make illegal calls.
* class.c: Include splay-tree.h.
(class_stack_node): Add names_used slot.
(check_member_decl_is_same_in_complete_scope): Remove.
(add_method): Fix comment. Push the declaration into class
scope.
(finish_struct_1): When popping the class, pop the bindings too.
Remove check for data member/function member conflict.
(finish_struct): Remove calls to
check_member_decl_is_same_in_complete_scope. Change calls to
popclass.
(pushclass): Clear names_used in the class stack entry.
Use invalidate_class_lookup_cache to remove cached entries, rather
than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE
before entering a new class. Remove dead code. Don't mess with
current_function_decl when pushing declarations.
(invalidate_class_lookup_cache): New function, split out from ...
(popclass): Here. Clean up names_used on our way out.
(instantiate_type): Adjust.
(build_self_reference): Don't push the declaration here.
(maybe_note_name_used_in_class): New function.
(note_name_declared_in_class): Likewise.
* decl.c (add_binding): Change prototype.
(find_class_binding_level): New function.
(innermost_nonclass_level): Likewise.
(current_binding_level): Update documentation.
(inner_binding_level): Remove. Replace with current_binding_level
throughout.
(push_binding_level): Remove special handling of
class_binding_level.
(pop_binding_level): Likewise. Use find_class_binding_level.
(suspend_binding_level): Likewise.
(global_bindings_p): Use innermost_nonclass_level.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(pseudo_global_level_p): Likewise.
(push_binding): Clear INHERITED_VALUE_BINDING_P.
(add_binding): Check for illegal multiple declarations. Return a
value indicating whether or not the new binding was legal.
(push_local_binding): Skip over class binding levels. Check
return value from add_binding.
(push_class_binding): Set INHERITED_VALUE_BINDING_P. Call
note_name_declared_in_class.
(pushlevel_class): Remove "fake out the rest of the compiler"
code.
(poplevel_class): Reset IDENTIFIER_CLASS_VALUEs.
(clear_identifier_class_values): New function.
(pop_from_top_level): Use it.
(pop_everything): Tweak.
(maybe_process_template_type_declaration): Don't push the
declaration for the template here.
(pushtag): Don't push tag declarations into class scope here.
(pushdecl): Apply DeMorgan's law for readability.
(pushdecl_class_level): Remove special-case code for
TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions.
(push_class_level_bindng): Deal with inherited bindings.
(lookup_name_real): Remove special-case code for
TYPE_BEING_DEFINED, and some implicit typename magic.
(grokdeclarator): Handle COMPONENT_REF for a template function.
(build_enumerator): Don't call pushdecl_class_level here.
(id_in_current_class): Remove.
* decl2.c (grokfield): Don't call pushdecl_class_level or
check_template_shadow.
* errfn.c (cp_file_of): Don't declare.
(cp_line_of): Likewise.
* error.c (dump_decl): Handle an OVERLOAD.
(cp_file_of): Likewise.
(cp_line_of): Likewise.
* init.c (build_member_call): Handle a COMPONENT_REF.
* lex.c (do_identifier): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* method.c (hack_identifier): Build COMPONENT_REFs for references
to member templates as well as member functions. Remove dead
code.
* parse.y (left_curly): Remove.
(nonnested_type): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* parse.c: Regenerated.
(nested_name_specifier_1): Likewise.
* pt.c (check_explicit_specialization): Adjust, for robustness.
(check_template_shadow): Handle OVERLOADs.
(build_template_decl): Set DECL_CONSTRUCTOR_P on the
TEMPLATE_DECL, if appropriate.
* search.c (envelope_add_decl): Remove.
(dfs_pushdecls): Likewise.
(dfs_compress_decls): Likewise.
(dfs_push_decls): New function.
(dfs_push_type_decls): Likewise.
(setup_class_bindings): Likewise.
(template_self_reference_p): Likewise.
(lookup_field_r): Use it.
(looup_member): Remove old comment. Deal with ambiguity.
(push_class_decls): Use dfs_push_decls and dfs_push_type_decls,
and remove envelope processing.
* semantics.c (begin_class_definition): Let pushclass push
declarations for base classes.
(finish_member_declaration): Push declarations into class scope.
* typeck.c (build_component_ref): Just put an OVERLOAD into the
COMPONENT_REF, not a TREE_LIST of an OVERLOAD.
(build_x_function_call): Deal with OVERLOAD. Handle template-ids.
* Makefile.in (class.o): Depend on splay-tree.h.
From-SVN: r26133
1999-04-02 17:36:57 +02:00
|
|
|
|
/* If we're about to enter a nested class, clear
|
|
|
|
|
IDENTIFIER_CLASS_VALUE for the enclosing classes. */
|
|
|
|
|
if (modify && current_class_depth > 1)
|
|
|
|
|
clear_identifier_class_values ();
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
pushlevel_class ();
|
|
|
|
|
|
1997-05-29 01:20:02 +02:00
|
|
|
|
#if 0
|
1996-02-28 23:01:56 +01:00
|
|
|
|
if (CLASSTYPE_TEMPLATE_INFO (type))
|
|
|
|
|
overload_template_name (type);
|
1997-05-29 01:20:02 +02:00
|
|
|
|
#endif
|
1996-02-28 23:01:56 +01:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (modify)
|
|
|
|
|
{
|
1996-02-28 23:01:56 +01:00
|
|
|
|
if (type != previous_class_type || current_class_depth > 1)
|
tinfo.h (__class_type_info): Fix illegal declaration.
1999-04-02 Mark Mitchell <mark@codesourcery.com>
* tinfo.h (__class_type_info): Fix illegal declaration.
* cp-tree.def (TEMPLATE_ID_EXPR): Update comment.
* cp-tree.h (INHERITED_VALUE_BINDING_P): New macro.
(IDENTIFIER_CLASS_VALUE): Improve documentation.
(is_properly_derived_from): Declare.
(invalidate_class_lookup_cache): Likewise.
(maybe_maybe_note_name_used_in_class): Likewise.
(note_name_declared_in_class): Likewise.
(push_using_decl): Remove duplicate declaration.
(id_in_current_class): Remove declaration.
(push_class_binding): Change prototype.
(clear_identitifer_class_values): Declare.
* call.c (is_properly_derived_from): Make it global.
(build_new_function_call): Be careful about updating candidates.
(build_new_method_call): Handle COMPONENT_REFs. Don't crash when
asked to make illegal calls.
* class.c: Include splay-tree.h.
(class_stack_node): Add names_used slot.
(check_member_decl_is_same_in_complete_scope): Remove.
(add_method): Fix comment. Push the declaration into class
scope.
(finish_struct_1): When popping the class, pop the bindings too.
Remove check for data member/function member conflict.
(finish_struct): Remove calls to
check_member_decl_is_same_in_complete_scope. Change calls to
popclass.
(pushclass): Clear names_used in the class stack entry.
Use invalidate_class_lookup_cache to remove cached entries, rather
than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE
before entering a new class. Remove dead code. Don't mess with
current_function_decl when pushing declarations.
(invalidate_class_lookup_cache): New function, split out from ...
(popclass): Here. Clean up names_used on our way out.
(instantiate_type): Adjust.
(build_self_reference): Don't push the declaration here.
(maybe_note_name_used_in_class): New function.
(note_name_declared_in_class): Likewise.
* decl.c (add_binding): Change prototype.
(find_class_binding_level): New function.
(innermost_nonclass_level): Likewise.
(current_binding_level): Update documentation.
(inner_binding_level): Remove. Replace with current_binding_level
throughout.
(push_binding_level): Remove special handling of
class_binding_level.
(pop_binding_level): Likewise. Use find_class_binding_level.
(suspend_binding_level): Likewise.
(global_bindings_p): Use innermost_nonclass_level.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(pseudo_global_level_p): Likewise.
(push_binding): Clear INHERITED_VALUE_BINDING_P.
(add_binding): Check for illegal multiple declarations. Return a
value indicating whether or not the new binding was legal.
(push_local_binding): Skip over class binding levels. Check
return value from add_binding.
(push_class_binding): Set INHERITED_VALUE_BINDING_P. Call
note_name_declared_in_class.
(pushlevel_class): Remove "fake out the rest of the compiler"
code.
(poplevel_class): Reset IDENTIFIER_CLASS_VALUEs.
(clear_identifier_class_values): New function.
(pop_from_top_level): Use it.
(pop_everything): Tweak.
(maybe_process_template_type_declaration): Don't push the
declaration for the template here.
(pushtag): Don't push tag declarations into class scope here.
(pushdecl): Apply DeMorgan's law for readability.
(pushdecl_class_level): Remove special-case code for
TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions.
(push_class_level_bindng): Deal with inherited bindings.
(lookup_name_real): Remove special-case code for
TYPE_BEING_DEFINED, and some implicit typename magic.
(grokdeclarator): Handle COMPONENT_REF for a template function.
(build_enumerator): Don't call pushdecl_class_level here.
(id_in_current_class): Remove.
* decl2.c (grokfield): Don't call pushdecl_class_level or
check_template_shadow.
* errfn.c (cp_file_of): Don't declare.
(cp_line_of): Likewise.
* error.c (dump_decl): Handle an OVERLOAD.
(cp_file_of): Likewise.
(cp_line_of): Likewise.
* init.c (build_member_call): Handle a COMPONENT_REF.
* lex.c (do_identifier): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* method.c (hack_identifier): Build COMPONENT_REFs for references
to member templates as well as member functions. Remove dead
code.
* parse.y (left_curly): Remove.
(nonnested_type): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* parse.c: Regenerated.
(nested_name_specifier_1): Likewise.
* pt.c (check_explicit_specialization): Adjust, for robustness.
(check_template_shadow): Handle OVERLOADs.
(build_template_decl): Set DECL_CONSTRUCTOR_P on the
TEMPLATE_DECL, if appropriate.
* search.c (envelope_add_decl): Remove.
(dfs_pushdecls): Likewise.
(dfs_compress_decls): Likewise.
(dfs_push_decls): New function.
(dfs_push_type_decls): Likewise.
(setup_class_bindings): Likewise.
(template_self_reference_p): Likewise.
(lookup_field_r): Use it.
(looup_member): Remove old comment. Deal with ambiguity.
(push_class_decls): Use dfs_push_decls and dfs_push_type_decls,
and remove envelope processing.
* semantics.c (begin_class_definition): Let pushclass push
declarations for base classes.
(finish_member_declaration): Push declarations into class scope.
* typeck.c (build_component_ref): Just put an OVERLOAD into the
COMPONENT_REF, not a TREE_LIST of an OVERLOAD.
(build_x_function_call): Deal with OVERLOAD. Handle template-ids.
* Makefile.in (class.o): Depend on splay-tree.h.
From-SVN: r26133
1999-04-02 17:36:57 +02:00
|
|
|
|
push_class_decls (type);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tree item;
|
|
|
|
|
|
1998-12-13 15:46:07 +01:00
|
|
|
|
/* We are re-entering the same class we just left, so we
|
|
|
|
|
don't have to search the whole inheritance matrix to find
|
|
|
|
|
all the decls to bind again. Instead, we install the
|
|
|
|
|
cached class_shadowed list, and walk through it binding
|
|
|
|
|
names and setting up IDENTIFIER_TYPE_VALUEs. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
set_class_shadows (previous_class_values);
|
|
|
|
|
for (item = previous_class_values; item; item = TREE_CHAIN (item))
|
|
|
|
|
{
|
|
|
|
|
tree id = TREE_PURPOSE (item);
|
1998-12-14 16:35:40 +01:00
|
|
|
|
tree decl = TREE_TYPE (item);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1998-12-13 15:46:07 +01:00
|
|
|
|
push_class_binding (id, decl);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (TREE_CODE (decl) == TYPE_DECL)
|
|
|
|
|
set_identifier_type_value (id, TREE_TYPE (decl));
|
|
|
|
|
}
|
|
|
|
|
unuse_fields (type);
|
|
|
|
|
}
|
|
|
|
|
|
1999-04-16 15:16:50 +02:00
|
|
|
|
storetags (CLASSTYPE_TAGS (type));
|
tinfo.h (__class_type_info): Fix illegal declaration.
1999-04-02 Mark Mitchell <mark@codesourcery.com>
* tinfo.h (__class_type_info): Fix illegal declaration.
* cp-tree.def (TEMPLATE_ID_EXPR): Update comment.
* cp-tree.h (INHERITED_VALUE_BINDING_P): New macro.
(IDENTIFIER_CLASS_VALUE): Improve documentation.
(is_properly_derived_from): Declare.
(invalidate_class_lookup_cache): Likewise.
(maybe_maybe_note_name_used_in_class): Likewise.
(note_name_declared_in_class): Likewise.
(push_using_decl): Remove duplicate declaration.
(id_in_current_class): Remove declaration.
(push_class_binding): Change prototype.
(clear_identitifer_class_values): Declare.
* call.c (is_properly_derived_from): Make it global.
(build_new_function_call): Be careful about updating candidates.
(build_new_method_call): Handle COMPONENT_REFs. Don't crash when
asked to make illegal calls.
* class.c: Include splay-tree.h.
(class_stack_node): Add names_used slot.
(check_member_decl_is_same_in_complete_scope): Remove.
(add_method): Fix comment. Push the declaration into class
scope.
(finish_struct_1): When popping the class, pop the bindings too.
Remove check for data member/function member conflict.
(finish_struct): Remove calls to
check_member_decl_is_same_in_complete_scope. Change calls to
popclass.
(pushclass): Clear names_used in the class stack entry.
Use invalidate_class_lookup_cache to remove cached entries, rather
than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE
before entering a new class. Remove dead code. Don't mess with
current_function_decl when pushing declarations.
(invalidate_class_lookup_cache): New function, split out from ...
(popclass): Here. Clean up names_used on our way out.
(instantiate_type): Adjust.
(build_self_reference): Don't push the declaration here.
(maybe_note_name_used_in_class): New function.
(note_name_declared_in_class): Likewise.
* decl.c (add_binding): Change prototype.
(find_class_binding_level): New function.
(innermost_nonclass_level): Likewise.
(current_binding_level): Update documentation.
(inner_binding_level): Remove. Replace with current_binding_level
throughout.
(push_binding_level): Remove special handling of
class_binding_level.
(pop_binding_level): Likewise. Use find_class_binding_level.
(suspend_binding_level): Likewise.
(global_bindings_p): Use innermost_nonclass_level.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(pseudo_global_level_p): Likewise.
(push_binding): Clear INHERITED_VALUE_BINDING_P.
(add_binding): Check for illegal multiple declarations. Return a
value indicating whether or not the new binding was legal.
(push_local_binding): Skip over class binding levels. Check
return value from add_binding.
(push_class_binding): Set INHERITED_VALUE_BINDING_P. Call
note_name_declared_in_class.
(pushlevel_class): Remove "fake out the rest of the compiler"
code.
(poplevel_class): Reset IDENTIFIER_CLASS_VALUEs.
(clear_identifier_class_values): New function.
(pop_from_top_level): Use it.
(pop_everything): Tweak.
(maybe_process_template_type_declaration): Don't push the
declaration for the template here.
(pushtag): Don't push tag declarations into class scope here.
(pushdecl): Apply DeMorgan's law for readability.
(pushdecl_class_level): Remove special-case code for
TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions.
(push_class_level_bindng): Deal with inherited bindings.
(lookup_name_real): Remove special-case code for
TYPE_BEING_DEFINED, and some implicit typename magic.
(grokdeclarator): Handle COMPONENT_REF for a template function.
(build_enumerator): Don't call pushdecl_class_level here.
(id_in_current_class): Remove.
* decl2.c (grokfield): Don't call pushdecl_class_level or
check_template_shadow.
* errfn.c (cp_file_of): Don't declare.
(cp_line_of): Likewise.
* error.c (dump_decl): Handle an OVERLOAD.
(cp_file_of): Likewise.
(cp_line_of): Likewise.
* init.c (build_member_call): Handle a COMPONENT_REF.
* lex.c (do_identifier): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* method.c (hack_identifier): Build COMPONENT_REFs for references
to member templates as well as member functions. Remove dead
code.
* parse.y (left_curly): Remove.
(nonnested_type): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* parse.c: Regenerated.
(nested_name_specifier_1): Likewise.
* pt.c (check_explicit_specialization): Adjust, for robustness.
(check_template_shadow): Handle OVERLOADs.
(build_template_decl): Set DECL_CONSTRUCTOR_P on the
TEMPLATE_DECL, if appropriate.
* search.c (envelope_add_decl): Remove.
(dfs_pushdecls): Likewise.
(dfs_compress_decls): Likewise.
(dfs_push_decls): New function.
(dfs_push_type_decls): Likewise.
(setup_class_bindings): Likewise.
(template_self_reference_p): Likewise.
(lookup_field_r): Use it.
(looup_member): Remove old comment. Deal with ambiguity.
(push_class_decls): Use dfs_push_decls and dfs_push_type_decls,
and remove envelope processing.
* semantics.c (begin_class_definition): Let pushclass push
declarations for base classes.
(finish_member_declaration): Push declarations into class scope.
* typeck.c (build_component_ref): Just put an OVERLOAD into the
COMPONENT_REF, not a TREE_LIST of an OVERLOAD.
(build_x_function_call): Deal with OVERLOAD. Handle template-ids.
* Makefile.in (class.o): Depend on splay-tree.h.
From-SVN: r26133
1999-04-02 17:36:57 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* When we exit a toplevel class scope, we save the
|
|
|
|
|
IDENTIFIER_CLASS_VALUEs so that we can restore them quickly if we
|
|
|
|
|
reenter the class. Here, we've entered some other class, so we
|
|
|
|
|
must invalidate our cache. */
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
tinfo.h (__class_type_info): Fix illegal declaration.
1999-04-02 Mark Mitchell <mark@codesourcery.com>
* tinfo.h (__class_type_info): Fix illegal declaration.
* cp-tree.def (TEMPLATE_ID_EXPR): Update comment.
* cp-tree.h (INHERITED_VALUE_BINDING_P): New macro.
(IDENTIFIER_CLASS_VALUE): Improve documentation.
(is_properly_derived_from): Declare.
(invalidate_class_lookup_cache): Likewise.
(maybe_maybe_note_name_used_in_class): Likewise.
(note_name_declared_in_class): Likewise.
(push_using_decl): Remove duplicate declaration.
(id_in_current_class): Remove declaration.
(push_class_binding): Change prototype.
(clear_identitifer_class_values): Declare.
* call.c (is_properly_derived_from): Make it global.
(build_new_function_call): Be careful about updating candidates.
(build_new_method_call): Handle COMPONENT_REFs. Don't crash when
asked to make illegal calls.
* class.c: Include splay-tree.h.
(class_stack_node): Add names_used slot.
(check_member_decl_is_same_in_complete_scope): Remove.
(add_method): Fix comment. Push the declaration into class
scope.
(finish_struct_1): When popping the class, pop the bindings too.
Remove check for data member/function member conflict.
(finish_struct): Remove calls to
check_member_decl_is_same_in_complete_scope. Change calls to
popclass.
(pushclass): Clear names_used in the class stack entry.
Use invalidate_class_lookup_cache to remove cached entries, rather
than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE
before entering a new class. Remove dead code. Don't mess with
current_function_decl when pushing declarations.
(invalidate_class_lookup_cache): New function, split out from ...
(popclass): Here. Clean up names_used on our way out.
(instantiate_type): Adjust.
(build_self_reference): Don't push the declaration here.
(maybe_note_name_used_in_class): New function.
(note_name_declared_in_class): Likewise.
* decl.c (add_binding): Change prototype.
(find_class_binding_level): New function.
(innermost_nonclass_level): Likewise.
(current_binding_level): Update documentation.
(inner_binding_level): Remove. Replace with current_binding_level
throughout.
(push_binding_level): Remove special handling of
class_binding_level.
(pop_binding_level): Likewise. Use find_class_binding_level.
(suspend_binding_level): Likewise.
(global_bindings_p): Use innermost_nonclass_level.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(pseudo_global_level_p): Likewise.
(push_binding): Clear INHERITED_VALUE_BINDING_P.
(add_binding): Check for illegal multiple declarations. Return a
value indicating whether or not the new binding was legal.
(push_local_binding): Skip over class binding levels. Check
return value from add_binding.
(push_class_binding): Set INHERITED_VALUE_BINDING_P. Call
note_name_declared_in_class.
(pushlevel_class): Remove "fake out the rest of the compiler"
code.
(poplevel_class): Reset IDENTIFIER_CLASS_VALUEs.
(clear_identifier_class_values): New function.
(pop_from_top_level): Use it.
(pop_everything): Tweak.
(maybe_process_template_type_declaration): Don't push the
declaration for the template here.
(pushtag): Don't push tag declarations into class scope here.
(pushdecl): Apply DeMorgan's law for readability.
(pushdecl_class_level): Remove special-case code for
TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions.
(push_class_level_bindng): Deal with inherited bindings.
(lookup_name_real): Remove special-case code for
TYPE_BEING_DEFINED, and some implicit typename magic.
(grokdeclarator): Handle COMPONENT_REF for a template function.
(build_enumerator): Don't call pushdecl_class_level here.
(id_in_current_class): Remove.
* decl2.c (grokfield): Don't call pushdecl_class_level or
check_template_shadow.
* errfn.c (cp_file_of): Don't declare.
(cp_line_of): Likewise.
* error.c (dump_decl): Handle an OVERLOAD.
(cp_file_of): Likewise.
(cp_line_of): Likewise.
* init.c (build_member_call): Handle a COMPONENT_REF.
* lex.c (do_identifier): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* method.c (hack_identifier): Build COMPONENT_REFs for references
to member templates as well as member functions. Remove dead
code.
* parse.y (left_curly): Remove.
(nonnested_type): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* parse.c: Regenerated.
(nested_name_specifier_1): Likewise.
* pt.c (check_explicit_specialization): Adjust, for robustness.
(check_template_shadow): Handle OVERLOADs.
(build_template_decl): Set DECL_CONSTRUCTOR_P on the
TEMPLATE_DECL, if appropriate.
* search.c (envelope_add_decl): Remove.
(dfs_pushdecls): Likewise.
(dfs_compress_decls): Likewise.
(dfs_push_decls): New function.
(dfs_push_type_decls): Likewise.
(setup_class_bindings): Likewise.
(template_self_reference_p): Likewise.
(lookup_field_r): Use it.
(looup_member): Remove old comment. Deal with ambiguity.
(push_class_decls): Use dfs_push_decls and dfs_push_type_decls,
and remove envelope processing.
* semantics.c (begin_class_definition): Let pushclass push
declarations for base classes.
(finish_member_declaration): Push declarations into class scope.
* typeck.c (build_component_ref): Just put an OVERLOAD into the
COMPONENT_REF, not a TREE_LIST of an OVERLOAD.
(build_x_function_call): Deal with OVERLOAD. Handle template-ids.
* Makefile.in (class.o): Depend on splay-tree.h.
From-SVN: r26133
1999-04-02 17:36:57 +02:00
|
|
|
|
void
|
|
|
|
|
invalidate_class_lookup_cache ()
|
|
|
|
|
{
|
|
|
|
|
tree t;
|
|
|
|
|
|
|
|
|
|
/* This code can be seen as a cache miss. When we've cached a
|
|
|
|
|
class' scope's bindings and we can't use them, we need to reset
|
|
|
|
|
them. This is it! */
|
|
|
|
|
for (t = previous_class_values; t; t = TREE_CHAIN (t))
|
|
|
|
|
IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
|
|
|
|
|
|
|
|
|
|
previous_class_type = NULL_TREE;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get out of the current class scope. If we were in a class scope
|
1999-04-14 15:20:19 +02:00
|
|
|
|
previously, that is the one popped to. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
void
|
1999-04-14 15:20:19 +02:00
|
|
|
|
popclass ()
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1999-09-17 09:35:07 +02:00
|
|
|
|
poplevel_class ();
|
1994-02-24 02:02:37 +01:00
|
|
|
|
/* Since poplevel_class does the popping of class decls nowadays,
|
1999-04-14 15:20:19 +02:00
|
|
|
|
this really only frees the obstack used for these decls. */
|
|
|
|
|
pop_class_decls ();
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
current_class_depth--;
|
1998-10-06 16:20:30 +02:00
|
|
|
|
current_class_name = current_class_stack[current_class_depth].name;
|
|
|
|
|
current_class_type = current_class_stack[current_class_depth].type;
|
|
|
|
|
current_access_specifier = current_class_stack[current_class_depth].access;
|
tinfo.h (__class_type_info): Fix illegal declaration.
1999-04-02 Mark Mitchell <mark@codesourcery.com>
* tinfo.h (__class_type_info): Fix illegal declaration.
* cp-tree.def (TEMPLATE_ID_EXPR): Update comment.
* cp-tree.h (INHERITED_VALUE_BINDING_P): New macro.
(IDENTIFIER_CLASS_VALUE): Improve documentation.
(is_properly_derived_from): Declare.
(invalidate_class_lookup_cache): Likewise.
(maybe_maybe_note_name_used_in_class): Likewise.
(note_name_declared_in_class): Likewise.
(push_using_decl): Remove duplicate declaration.
(id_in_current_class): Remove declaration.
(push_class_binding): Change prototype.
(clear_identitifer_class_values): Declare.
* call.c (is_properly_derived_from): Make it global.
(build_new_function_call): Be careful about updating candidates.
(build_new_method_call): Handle COMPONENT_REFs. Don't crash when
asked to make illegal calls.
* class.c: Include splay-tree.h.
(class_stack_node): Add names_used slot.
(check_member_decl_is_same_in_complete_scope): Remove.
(add_method): Fix comment. Push the declaration into class
scope.
(finish_struct_1): When popping the class, pop the bindings too.
Remove check for data member/function member conflict.
(finish_struct): Remove calls to
check_member_decl_is_same_in_complete_scope. Change calls to
popclass.
(pushclass): Clear names_used in the class stack entry.
Use invalidate_class_lookup_cache to remove cached entries, rather
than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE
before entering a new class. Remove dead code. Don't mess with
current_function_decl when pushing declarations.
(invalidate_class_lookup_cache): New function, split out from ...
(popclass): Here. Clean up names_used on our way out.
(instantiate_type): Adjust.
(build_self_reference): Don't push the declaration here.
(maybe_note_name_used_in_class): New function.
(note_name_declared_in_class): Likewise.
* decl.c (add_binding): Change prototype.
(find_class_binding_level): New function.
(innermost_nonclass_level): Likewise.
(current_binding_level): Update documentation.
(inner_binding_level): Remove. Replace with current_binding_level
throughout.
(push_binding_level): Remove special handling of
class_binding_level.
(pop_binding_level): Likewise. Use find_class_binding_level.
(suspend_binding_level): Likewise.
(global_bindings_p): Use innermost_nonclass_level.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(pseudo_global_level_p): Likewise.
(push_binding): Clear INHERITED_VALUE_BINDING_P.
(add_binding): Check for illegal multiple declarations. Return a
value indicating whether or not the new binding was legal.
(push_local_binding): Skip over class binding levels. Check
return value from add_binding.
(push_class_binding): Set INHERITED_VALUE_BINDING_P. Call
note_name_declared_in_class.
(pushlevel_class): Remove "fake out the rest of the compiler"
code.
(poplevel_class): Reset IDENTIFIER_CLASS_VALUEs.
(clear_identifier_class_values): New function.
(pop_from_top_level): Use it.
(pop_everything): Tweak.
(maybe_process_template_type_declaration): Don't push the
declaration for the template here.
(pushtag): Don't push tag declarations into class scope here.
(pushdecl): Apply DeMorgan's law for readability.
(pushdecl_class_level): Remove special-case code for
TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions.
(push_class_level_bindng): Deal with inherited bindings.
(lookup_name_real): Remove special-case code for
TYPE_BEING_DEFINED, and some implicit typename magic.
(grokdeclarator): Handle COMPONENT_REF for a template function.
(build_enumerator): Don't call pushdecl_class_level here.
(id_in_current_class): Remove.
* decl2.c (grokfield): Don't call pushdecl_class_level or
check_template_shadow.
* errfn.c (cp_file_of): Don't declare.
(cp_line_of): Likewise.
* error.c (dump_decl): Handle an OVERLOAD.
(cp_file_of): Likewise.
(cp_line_of): Likewise.
* init.c (build_member_call): Handle a COMPONENT_REF.
* lex.c (do_identifier): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* method.c (hack_identifier): Build COMPONENT_REFs for references
to member templates as well as member functions. Remove dead
code.
* parse.y (left_curly): Remove.
(nonnested_type): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* parse.c: Regenerated.
(nested_name_specifier_1): Likewise.
* pt.c (check_explicit_specialization): Adjust, for robustness.
(check_template_shadow): Handle OVERLOADs.
(build_template_decl): Set DECL_CONSTRUCTOR_P on the
TEMPLATE_DECL, if appropriate.
* search.c (envelope_add_decl): Remove.
(dfs_pushdecls): Likewise.
(dfs_compress_decls): Likewise.
(dfs_push_decls): New function.
(dfs_push_type_decls): Likewise.
(setup_class_bindings): Likewise.
(template_self_reference_p): Likewise.
(lookup_field_r): Use it.
(looup_member): Remove old comment. Deal with ambiguity.
(push_class_decls): Use dfs_push_decls and dfs_push_type_decls,
and remove envelope processing.
* semantics.c (begin_class_definition): Let pushclass push
declarations for base classes.
(finish_member_declaration): Push declarations into class scope.
* typeck.c (build_component_ref): Just put an OVERLOAD into the
COMPONENT_REF, not a TREE_LIST of an OVERLOAD.
(build_x_function_call): Deal with OVERLOAD. Handle template-ids.
* Makefile.in (class.o): Depend on splay-tree.h.
From-SVN: r26133
1999-04-02 17:36:57 +02:00
|
|
|
|
if (current_class_stack[current_class_depth].names_used)
|
|
|
|
|
splay_tree_delete (current_class_stack[current_class_depth].names_used);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
2000-02-07 21:36:36 +01:00
|
|
|
|
/* Returns 1 if current_class_type is either T or a nested type of T.
|
|
|
|
|
We start looking from 1 because entry 0 is from global scope, and has
|
|
|
|
|
no type. */
|
1998-05-09 20:10:28 +02:00
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
currently_open_class (t)
|
|
|
|
|
tree t;
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
if (t == current_class_type)
|
|
|
|
|
return 1;
|
2000-02-07 21:36:36 +01:00
|
|
|
|
for (i = 1; i < current_class_depth; ++i)
|
1998-10-06 16:20:30 +02:00
|
|
|
|
if (current_class_stack [i].type == t)
|
1998-05-09 20:10:28 +02:00
|
|
|
|
return 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-07 21:36:36 +01:00
|
|
|
|
/* If either current_class_type or one of its enclosing classes are derived
|
|
|
|
|
from T, return the appropriate type. Used to determine how we found
|
|
|
|
|
something via unqualified lookup. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
currently_open_derived_class (t)
|
|
|
|
|
tree t;
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (DERIVED_FROM_P (t, current_class_type))
|
|
|
|
|
return current_class_type;
|
|
|
|
|
|
|
|
|
|
for (i = current_class_depth - 1; i > 0; --i)
|
|
|
|
|
if (DERIVED_FROM_P (t, current_class_stack[i].type))
|
|
|
|
|
return current_class_stack[i].type;
|
|
|
|
|
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
/* When entering a class scope, all enclosing class scopes' names with
|
|
|
|
|
static meaning (static variables, static functions, types and enumerators)
|
|
|
|
|
have to be visible. This recursive function calls pushclass for all
|
|
|
|
|
enclosing class contexts until global or a local scope is reached.
|
|
|
|
|
TYPE is the enclosed class and MODIFY is equivalent with the pushclass
|
|
|
|
|
formal of the same name. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
push_nested_class (type, modify)
|
|
|
|
|
tree type;
|
|
|
|
|
int modify;
|
|
|
|
|
{
|
1994-04-15 03:44:15 +02:00
|
|
|
|
tree context;
|
|
|
|
|
|
1999-02-25 01:11:35 +01:00
|
|
|
|
/* A namespace might be passed in error cases, like A::B:C. */
|
2000-01-13 00:27:46 +01:00
|
|
|
|
if (type == NULL_TREE
|
|
|
|
|
|| type == error_mark_node
|
1999-02-25 01:11:35 +01:00
|
|
|
|
|| TREE_CODE (type) == NAMESPACE_DECL
|
2000-01-13 00:27:46 +01:00
|
|
|
|
|| ! IS_AGGR_TYPE (type)
|
pt.c (coerce_template_parms): Don't access elements of ARGLIST that is not really present.
Wed Jan 21 10:29:57 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
* pt.c (coerce_template_parms): Don't access elements of ARGLIST
that is not really present. Substitute default arguments in
template template arguments. Correctly convert TEMPLATE_DECL to
TEMPLATE_TEMPLATE_PARM.
(comp_template_args): TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM
are no longer treated specially here.
* parse.y (template_template_parm): Fix copy error.
* decl.c (grokdeclarator): Warn about missing `typename' for nested
type created from template template parameters.
* parse.y (bad_parm): Likewise
* class.c (finish_struct): Handle TEMPLATE_TEMPLATE_PARM.
(push_nested_class): Likewise.
* cp-tree.def (TEMPLATE_TEMPLATE_PARM): New tree code.
* cp-tree.h (DECL_TEMPLATE_TEMPLATE_PARM_P): New macro.
(copy_template_template_parm): Declare.
* decl.c (arg_looking_for_template): New variable.
(lookup_name_real): Handle TEMPLATE_TEMPLATE_PARM.
Try to return TEMPLATE_DECL or TEMPLATE_TEMPLATE_PARM
node if arg_looking_for_template is nonzero.
(pushdecl): Handle TEMPLATE_TEMPLATE_PARM.
(grok_op_properties, xref_tag, xref_basetypes): Likewise.
(grokdeclarator): Handle TEMPLATE_DECL.
* decl2.c (constructor_name_full): Handle TEMPLATE_TEMPLATE_PARM.
* error.c (dump_type): Add TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM.
(dump_type_prefix, dump_type_suffix) Handle TEMPLATE_TEMPLATE_PARM.
(dump_decl): Handle unnamed template type parameters.
Handle template template parameters.
(dump_function_name): Handle template template parameters.
* init.c (is_aggr_typedef, is_aggr_type, get_aggr_from_typedef):
Handle TEMPLATE_TEMPLATE_PARM.
* method.c (build_template_template_parm_names): New function.
(build_template_parm_names): Handle TEMPLATE_DECL.
(build_overload_nested_name, build_overload_name):
Handle TEMPLATE_TEMPLATE_PARM.
* parse.y (maybe_identifier): New nonterminal.
(template_type_parm): Use it.
(template_template_parm, template_arg1): New nonterminal.
(template_parm): Add template_template_parm rules.
(template_arg): Set processing_template_arg.
(template_arg1): Rules moved from template_arg.
(primary, nonnested_type): Set arg_looking_for_template if we are
processing template arguments.
* pt.c (begin_member_template_processing): Handle TEMPLATE_DECL.
(process_template_parm): Handle template template parameters.
(coerce_template_parms, comp_template_args): Likewise.
(mangle_class_name_for_template, lookup_template_class): Likewise.
(uses_template_parms): Handle TEMPLATE_DECL and
TEMPLATE_TEMPLATE_PARM.
(current_template_args): Handle TEMPLATE_DECL.
(tsubst, tsubst_copy, unify): Handle TEMPLATE_TEMPLATE_PARM.
* search.c (dfs_walk, dfs_record_inheritance):
Handle TEMPLATE_TEMPLATE_PARM.
* tree.c (copy_template_template_parm): New function.
(mapcar): Handle TEMPLATE_TEMPLATE_PARM.
* typeck.c (comptypes): Handle TEMPLATE_TEMPLATE_PARM.
From-SVN: r17441
1998-01-22 12:03:56 +01:00
|
|
|
|
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM
|
|
|
|
|
|| TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
|
1994-04-15 03:44:15 +02:00
|
|
|
|
return;
|
|
|
|
|
|
1996-12-18 03:46:25 +01:00
|
|
|
|
context = DECL_CONTEXT (TYPE_MAIN_DECL (type));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-04-15 21:21:21 +02:00
|
|
|
|
if (context && CLASS_TYPE_P (context))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
push_nested_class (context, 2);
|
|
|
|
|
pushclass (type, modify);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Undoes a push_nested_class call. MODIFY is passed on to popclass. */
|
|
|
|
|
|
|
|
|
|
void
|
1999-04-14 15:20:19 +02:00
|
|
|
|
pop_nested_class ()
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1996-12-18 03:46:25 +01:00
|
|
|
|
tree context = DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-04-14 15:20:19 +02:00
|
|
|
|
popclass ();
|
1999-04-15 21:21:21 +02:00
|
|
|
|
if (context && CLASS_TYPE_P (context))
|
1999-04-14 15:20:19 +02:00
|
|
|
|
pop_nested_class ();
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Set global variables CURRENT_LANG_NAME to appropriate value
|
|
|
|
|
so that behavior of name-mangling machinery is correct. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
push_lang_context (name)
|
|
|
|
|
tree name;
|
|
|
|
|
{
|
|
|
|
|
*current_lang_stack++ = current_lang_name;
|
Get ready for garbage collection.
* Makefile.in (CXX_TREE_H): Add varray.h
(lex.o): Depend on ggc.h.
(decl.o): Likewise.
(decl2.o): Likewise.
(method.o): Likewise.
(search.o): Likewise.
(pt.o): Likewise.
(repo.o): Likewise.
* class.c: Include ggc.h.
(current_class_name): Remove.
(current_class_type): Likewise.
(current_access_specifier): Likewise.
(previous_class_type): Likewise.
(previous_class_values): Likewise.
(class_cache_firstobj): Likewise.
(current_lang_base): Likewise.
(current_lang_stack): Likewise.
(current_lang_stacksize): Likewise.
(lang_name_c): Likewise.
(lang_name_cplusplus): Likewise.
(lang_name_java): Likewise.
(current_lang_name): Likewise.
(base_layout_decl): Likewise.
(access_default_node): Likewise.
(access_public_node): Likewise.
(access_protected_node): Likewise.
(access_private_node): Likewise.
(access_default_virtual_node): Likewise.
(access_public_virtual_node): Likewise.
(access_protected_virtual_node): Likewise.
(access_private_virtual_node): Likewise.
(signed_zero_node): Likewise.
(init_class_processing): Don't build base_layout_decl.
(push_lang_context): Adjust now that current_lang_base is a varray.
(pop_lang_context): Likewise.
* cp-tree.h: Include varray.h.
(cp_global_trees): Add access_default, access_public,
access_protected, access_private, access_default_virtual,
access_public_virtual, access_protected_virtual,
access_private_virtual, ctor_identifier, delta2_identifier,
delta_identifier, dtor_identifier, in_charge_identifier,
index_identifier, nelts_identifier, this_identifier,
pfn_identifier, pfn_or_delta2_identifier, vptr_identifier,
lang_name_c, lang_name_cplusplus, lang_name_java,
empty_except_spec, null, jclass, minus_one, terminate.
(saved_scope): Move here from decl.c. Define globals in terms of
saved_scope: current_namespace, current_class_name,
current_class_type, current_access_specifier, current_lang_stack,
current_lang_base, current_lang_name, current_function_parms,
current_template_parms, processing_template_decl,
processing_specialization, processing_explicit_instantiation,
previous_class_type, previous_class_values, class_cache_firstobj.
(scope_chain): New variable.
(init_pt): New function.
* decl.c (current_namespace): Remove.
(this_identifier, in_charge_identifier, ctor_identifier): Likewise.
(dtor_identifier, pfn_identifier, index_identifier): Likewise.
(delta_identifier, delta2_identifier): Likewise.
(pfn_or_delta2_identifier, tag_identifier): Likewise
(vt_off_identifier, empty_except_spec, null_node): Likewise.
(current_function_parms, current_lang_base): Remove.
(current_lang_stack, previous_class_values): Remove.
(class_binding_level): Macroize.
(saved_scope): Remove.
(current_saved_scope): Rename to scope_chain.
(mark_saved_scope): Adjust for new scope structure.
(maybe_push_to_top_level): Likewise.
(pop_from_top_level): Likewise.
(duplicate_decls): Adjust now that current_lang_base is a varray.
(build_typename_type): Call ggc_add_tree_hash_table_root.
(init_decl_processing): Call init_pt. Call push_to_top_level to
set up globals. Add GC roots.
(xref_basetypes): Adjust now that current_lang_base is a varray.
* decl.h (this_identifier): Remove.
(in_charge_identifier): Likewise.
* decl2.c: Don't include varray.h.
(current_namespace): Remove.
(init_decl2): Add GC roots.
* except.c (Terminate): Remove.
(init_exception_processing): Use terminate_node instead.
(build_terminate_handler): Likewise.
* init.c (nc_nelts_field_id): Remove.
(minus_one): Likewise.
(init_init_processing): Use minus_one_node and nelts_identifier
instead. Add GC roots.
(jclass_node): Remove.
(build_new_1): Use nelts_identifier.
(build_vec_init): Likewise.
(build_vec_delete): Likewise.
* lex.c: Include ggc.h.
(defarg_fn): Move declaration early.
(defarg_parms): Likewise.
(init_parse): Add GC roots.
(handle_cp_pragma): Remove redundant declaration of
pending_vtables.
* method.c: Include ggc.h.
(btypelist): Make it a varray. All uses changed.
(ktypelist): Likewise.
(init_method): Add GC roots.
* pt.c: Don't include varray.h. Include ggc.h.
(current_template_parms): Remove.
(processing_template_decl): Likewise.
(processing_specialization): Likewise.
(processing_explicit_instantiation): Likewise.
(init_pt): New function.
* repo.c: Include ggc.h.
(init_repo): Add GC roots.
* search.c: Don't include varray.h.
(_vptr_name): Remove.
(lookup_field_1): Use vtpr_identifier instead.
(expand_indirect_vtbls_init): Remove redundant declaration of
in_charge_identifier.
(init_search_processing): Use vptr_identifier.
From-SVN: r29135
1999-09-06 04:43:09 +02:00
|
|
|
|
if (current_lang_stack - &VARRAY_TREE (current_lang_base, 0)
|
|
|
|
|
>= (ptrdiff_t) VARRAY_SIZE (current_lang_base))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
Get ready for garbage collection.
* Makefile.in (CXX_TREE_H): Add varray.h
(lex.o): Depend on ggc.h.
(decl.o): Likewise.
(decl2.o): Likewise.
(method.o): Likewise.
(search.o): Likewise.
(pt.o): Likewise.
(repo.o): Likewise.
* class.c: Include ggc.h.
(current_class_name): Remove.
(current_class_type): Likewise.
(current_access_specifier): Likewise.
(previous_class_type): Likewise.
(previous_class_values): Likewise.
(class_cache_firstobj): Likewise.
(current_lang_base): Likewise.
(current_lang_stack): Likewise.
(current_lang_stacksize): Likewise.
(lang_name_c): Likewise.
(lang_name_cplusplus): Likewise.
(lang_name_java): Likewise.
(current_lang_name): Likewise.
(base_layout_decl): Likewise.
(access_default_node): Likewise.
(access_public_node): Likewise.
(access_protected_node): Likewise.
(access_private_node): Likewise.
(access_default_virtual_node): Likewise.
(access_public_virtual_node): Likewise.
(access_protected_virtual_node): Likewise.
(access_private_virtual_node): Likewise.
(signed_zero_node): Likewise.
(init_class_processing): Don't build base_layout_decl.
(push_lang_context): Adjust now that current_lang_base is a varray.
(pop_lang_context): Likewise.
* cp-tree.h: Include varray.h.
(cp_global_trees): Add access_default, access_public,
access_protected, access_private, access_default_virtual,
access_public_virtual, access_protected_virtual,
access_private_virtual, ctor_identifier, delta2_identifier,
delta_identifier, dtor_identifier, in_charge_identifier,
index_identifier, nelts_identifier, this_identifier,
pfn_identifier, pfn_or_delta2_identifier, vptr_identifier,
lang_name_c, lang_name_cplusplus, lang_name_java,
empty_except_spec, null, jclass, minus_one, terminate.
(saved_scope): Move here from decl.c. Define globals in terms of
saved_scope: current_namespace, current_class_name,
current_class_type, current_access_specifier, current_lang_stack,
current_lang_base, current_lang_name, current_function_parms,
current_template_parms, processing_template_decl,
processing_specialization, processing_explicit_instantiation,
previous_class_type, previous_class_values, class_cache_firstobj.
(scope_chain): New variable.
(init_pt): New function.
* decl.c (current_namespace): Remove.
(this_identifier, in_charge_identifier, ctor_identifier): Likewise.
(dtor_identifier, pfn_identifier, index_identifier): Likewise.
(delta_identifier, delta2_identifier): Likewise.
(pfn_or_delta2_identifier, tag_identifier): Likewise
(vt_off_identifier, empty_except_spec, null_node): Likewise.
(current_function_parms, current_lang_base): Remove.
(current_lang_stack, previous_class_values): Remove.
(class_binding_level): Macroize.
(saved_scope): Remove.
(current_saved_scope): Rename to scope_chain.
(mark_saved_scope): Adjust for new scope structure.
(maybe_push_to_top_level): Likewise.
(pop_from_top_level): Likewise.
(duplicate_decls): Adjust now that current_lang_base is a varray.
(build_typename_type): Call ggc_add_tree_hash_table_root.
(init_decl_processing): Call init_pt. Call push_to_top_level to
set up globals. Add GC roots.
(xref_basetypes): Adjust now that current_lang_base is a varray.
* decl.h (this_identifier): Remove.
(in_charge_identifier): Likewise.
* decl2.c: Don't include varray.h.
(current_namespace): Remove.
(init_decl2): Add GC roots.
* except.c (Terminate): Remove.
(init_exception_processing): Use terminate_node instead.
(build_terminate_handler): Likewise.
* init.c (nc_nelts_field_id): Remove.
(minus_one): Likewise.
(init_init_processing): Use minus_one_node and nelts_identifier
instead. Add GC roots.
(jclass_node): Remove.
(build_new_1): Use nelts_identifier.
(build_vec_init): Likewise.
(build_vec_delete): Likewise.
* lex.c: Include ggc.h.
(defarg_fn): Move declaration early.
(defarg_parms): Likewise.
(init_parse): Add GC roots.
(handle_cp_pragma): Remove redundant declaration of
pending_vtables.
* method.c: Include ggc.h.
(btypelist): Make it a varray. All uses changed.
(ktypelist): Likewise.
(init_method): Add GC roots.
* pt.c: Don't include varray.h. Include ggc.h.
(current_template_parms): Remove.
(processing_template_decl): Likewise.
(processing_specialization): Likewise.
(processing_explicit_instantiation): Likewise.
(init_pt): New function.
* repo.c: Include ggc.h.
(init_repo): Add GC roots.
* search.c: Don't include varray.h.
(_vptr_name): Remove.
(lookup_field_1): Use vtpr_identifier instead.
(expand_indirect_vtbls_init): Remove redundant declaration of
in_charge_identifier.
(init_search_processing): Use vptr_identifier.
From-SVN: r29135
1999-09-06 04:43:09 +02:00
|
|
|
|
size_t old_size = VARRAY_SIZE (current_lang_base);
|
|
|
|
|
|
|
|
|
|
VARRAY_GROW (current_lang_base, old_size + 10);
|
|
|
|
|
current_lang_stack = &VARRAY_TREE (current_lang_base, old_size);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
1999-05-13 17:42:53 +02:00
|
|
|
|
if (name == lang_name_cplusplus)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
|
|
|
|
strict_prototype = strict_prototypes_lang_cplusplus;
|
|
|
|
|
current_lang_name = name;
|
|
|
|
|
}
|
1999-05-13 17:42:53 +02:00
|
|
|
|
else if (name == lang_name_java)
|
|
|
|
|
{
|
|
|
|
|
strict_prototype = strict_prototypes_lang_cplusplus;
|
|
|
|
|
current_lang_name = name;
|
|
|
|
|
/* DECL_IGNORED_P is initially set for these types, to avoid clutter.
|
|
|
|
|
(See record_builtin_java_type in decl.c.) However, that causes
|
|
|
|
|
incorrect debug entries if these types are actually used.
|
|
|
|
|
So we re-enable debug output after extern "Java". */
|
|
|
|
|
DECL_IGNORED_P (java_byte_type_node) = 0;
|
|
|
|
|
DECL_IGNORED_P (java_short_type_node) = 0;
|
|
|
|
|
DECL_IGNORED_P (java_int_type_node) = 0;
|
|
|
|
|
DECL_IGNORED_P (java_long_type_node) = 0;
|
|
|
|
|
DECL_IGNORED_P (java_float_type_node) = 0;
|
|
|
|
|
DECL_IGNORED_P (java_double_type_node) = 0;
|
|
|
|
|
DECL_IGNORED_P (java_char_type_node) = 0;
|
|
|
|
|
DECL_IGNORED_P (java_boolean_type_node) = 0;
|
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
else if (name == lang_name_c)
|
|
|
|
|
{
|
|
|
|
|
strict_prototype = strict_prototypes_lang_c;
|
|
|
|
|
current_lang_name = name;
|
|
|
|
|
}
|
|
|
|
|
else
|
1998-09-07 16:25:35 +02:00
|
|
|
|
error ("language string `\"%s\"' not recognized", IDENTIFIER_POINTER (name));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get out of the current language scope. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
void
|
|
|
|
|
pop_lang_context ()
|
|
|
|
|
{
|
Get ready for garbage collection.
* Makefile.in (CXX_TREE_H): Add varray.h
(lex.o): Depend on ggc.h.
(decl.o): Likewise.
(decl2.o): Likewise.
(method.o): Likewise.
(search.o): Likewise.
(pt.o): Likewise.
(repo.o): Likewise.
* class.c: Include ggc.h.
(current_class_name): Remove.
(current_class_type): Likewise.
(current_access_specifier): Likewise.
(previous_class_type): Likewise.
(previous_class_values): Likewise.
(class_cache_firstobj): Likewise.
(current_lang_base): Likewise.
(current_lang_stack): Likewise.
(current_lang_stacksize): Likewise.
(lang_name_c): Likewise.
(lang_name_cplusplus): Likewise.
(lang_name_java): Likewise.
(current_lang_name): Likewise.
(base_layout_decl): Likewise.
(access_default_node): Likewise.
(access_public_node): Likewise.
(access_protected_node): Likewise.
(access_private_node): Likewise.
(access_default_virtual_node): Likewise.
(access_public_virtual_node): Likewise.
(access_protected_virtual_node): Likewise.
(access_private_virtual_node): Likewise.
(signed_zero_node): Likewise.
(init_class_processing): Don't build base_layout_decl.
(push_lang_context): Adjust now that current_lang_base is a varray.
(pop_lang_context): Likewise.
* cp-tree.h: Include varray.h.
(cp_global_trees): Add access_default, access_public,
access_protected, access_private, access_default_virtual,
access_public_virtual, access_protected_virtual,
access_private_virtual, ctor_identifier, delta2_identifier,
delta_identifier, dtor_identifier, in_charge_identifier,
index_identifier, nelts_identifier, this_identifier,
pfn_identifier, pfn_or_delta2_identifier, vptr_identifier,
lang_name_c, lang_name_cplusplus, lang_name_java,
empty_except_spec, null, jclass, minus_one, terminate.
(saved_scope): Move here from decl.c. Define globals in terms of
saved_scope: current_namespace, current_class_name,
current_class_type, current_access_specifier, current_lang_stack,
current_lang_base, current_lang_name, current_function_parms,
current_template_parms, processing_template_decl,
processing_specialization, processing_explicit_instantiation,
previous_class_type, previous_class_values, class_cache_firstobj.
(scope_chain): New variable.
(init_pt): New function.
* decl.c (current_namespace): Remove.
(this_identifier, in_charge_identifier, ctor_identifier): Likewise.
(dtor_identifier, pfn_identifier, index_identifier): Likewise.
(delta_identifier, delta2_identifier): Likewise.
(pfn_or_delta2_identifier, tag_identifier): Likewise
(vt_off_identifier, empty_except_spec, null_node): Likewise.
(current_function_parms, current_lang_base): Remove.
(current_lang_stack, previous_class_values): Remove.
(class_binding_level): Macroize.
(saved_scope): Remove.
(current_saved_scope): Rename to scope_chain.
(mark_saved_scope): Adjust for new scope structure.
(maybe_push_to_top_level): Likewise.
(pop_from_top_level): Likewise.
(duplicate_decls): Adjust now that current_lang_base is a varray.
(build_typename_type): Call ggc_add_tree_hash_table_root.
(init_decl_processing): Call init_pt. Call push_to_top_level to
set up globals. Add GC roots.
(xref_basetypes): Adjust now that current_lang_base is a varray.
* decl.h (this_identifier): Remove.
(in_charge_identifier): Likewise.
* decl2.c: Don't include varray.h.
(current_namespace): Remove.
(init_decl2): Add GC roots.
* except.c (Terminate): Remove.
(init_exception_processing): Use terminate_node instead.
(build_terminate_handler): Likewise.
* init.c (nc_nelts_field_id): Remove.
(minus_one): Likewise.
(init_init_processing): Use minus_one_node and nelts_identifier
instead. Add GC roots.
(jclass_node): Remove.
(build_new_1): Use nelts_identifier.
(build_vec_init): Likewise.
(build_vec_delete): Likewise.
* lex.c: Include ggc.h.
(defarg_fn): Move declaration early.
(defarg_parms): Likewise.
(init_parse): Add GC roots.
(handle_cp_pragma): Remove redundant declaration of
pending_vtables.
* method.c: Include ggc.h.
(btypelist): Make it a varray. All uses changed.
(ktypelist): Likewise.
(init_method): Add GC roots.
* pt.c: Don't include varray.h. Include ggc.h.
(current_template_parms): Remove.
(processing_template_decl): Likewise.
(processing_specialization): Likewise.
(processing_explicit_instantiation): Likewise.
(init_pt): New function.
* repo.c: Include ggc.h.
(init_repo): Add GC roots.
* search.c: Don't include varray.h.
(_vptr_name): Remove.
(lookup_field_1): Use vtpr_identifier instead.
(expand_indirect_vtbls_init): Remove redundant declaration of
in_charge_identifier.
(init_search_processing): Use vptr_identifier.
From-SVN: r29135
1999-09-06 04:43:09 +02:00
|
|
|
|
/* Clear the current entry so that garbage collector won't hold on
|
|
|
|
|
to it. */
|
|
|
|
|
*current_lang_stack = NULL_TREE;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
current_lang_name = *--current_lang_stack;
|
cp-tree.h (TYPE_FOR_JAVA): New macro.
d
* cp-tree.h (TYPE_FOR_JAVA): New macro.
* decl.c, cp-tree.h (java_byte_type_node, java_short_type_node,
java_int_type_node, java_long_type_node, java_float_type_node,
java_double_type_node, java_char_type_node, java_boolean_type_node):
New "primitive" types, with predefined names __java_byte etc.
(record_builtin_java_type): New function.
(init_decl_processing): Make Java types with record_builtin_java_type.
(pushtag, grokdeclarator): Set TYPE_FOR_JAVA if in extern "JAVA".
(xref_baseypes): If base class was TYPE_FOR_JAVA, so is this class.
(grokfndecl): Call check_java_method for Java classes.
* method.c (is_java_type): Removed. Replaced with TYPE_FOR_JAVA.
(process_overload_item): Match types against specific
java_XX_type_node types, rather than using is_java_type.
* class.c (finish_struct_1): Don't add default copy constructor
or operator= if TYPE_FOR_JAVA.
(pop_lang_conext): Restore strict_prototyp proper if Java.
* decl2.c (acceptable_java_type, check_java_method): New functions.
* pt.c (instantiate_class_template): Copy TYPE_FOR_JAVA from pattern.
(tsubst): Move common statement after if statement.
* typeck.c (comptypes): If strict, TYPE_FOR_JAVA must match.
From-SVN: r20174
1998-06-01 20:25:34 +02:00
|
|
|
|
if (current_lang_name == lang_name_cplusplus
|
|
|
|
|
|| current_lang_name == lang_name_java)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
strict_prototype = strict_prototypes_lang_cplusplus;
|
|
|
|
|
else if (current_lang_name == lang_name_c)
|
|
|
|
|
strict_prototype = strict_prototypes_lang_c;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Type instantiation routines. */
|
|
|
|
|
|
1998-12-09 17:20:05 +01:00
|
|
|
|
/* Given an OVERLOAD and a TARGET_TYPE, return the function that
|
|
|
|
|
matches the TARGET_TYPE. If there is no satisfactory match, return
|
|
|
|
|
error_mark_node, and issue an error message if COMPLAIN is
|
|
|
|
|
non-zero. If TEMPLATE_ONLY, the name of the overloaded function
|
|
|
|
|
was a template-id, and EXPLICIT_TARGS are the explicitly provided
|
|
|
|
|
template arguments. */
|
|
|
|
|
|
1998-05-08 04:06:26 +02:00
|
|
|
|
static tree
|
1998-12-09 17:20:05 +01:00
|
|
|
|
resolve_address_of_overloaded_function (target_type,
|
|
|
|
|
overload,
|
|
|
|
|
complain,
|
|
|
|
|
template_only,
|
|
|
|
|
explicit_targs)
|
|
|
|
|
tree target_type;
|
|
|
|
|
tree overload;
|
1998-05-08 04:06:26 +02:00
|
|
|
|
int complain;
|
1998-12-09 17:20:05 +01:00
|
|
|
|
int template_only;
|
|
|
|
|
tree explicit_targs;
|
1998-05-08 04:06:26 +02:00
|
|
|
|
{
|
1998-12-09 17:20:05 +01:00
|
|
|
|
/* Here's what the standard says:
|
|
|
|
|
|
|
|
|
|
[over.over]
|
|
|
|
|
|
|
|
|
|
If the name is a function template, template argument deduction
|
|
|
|
|
is done, and if the argument deduction succeeds, the deduced
|
|
|
|
|
arguments are used to generate a single template function, which
|
|
|
|
|
is added to the set of overloaded functions considered.
|
|
|
|
|
|
|
|
|
|
Non-member functions and static member functions match targets of
|
|
|
|
|
type "pointer-to-function" or "reference-to-function." Nonstatic
|
|
|
|
|
member functions match targets of type "pointer-to-member
|
|
|
|
|
function;" the function type of the pointer to member is used to
|
|
|
|
|
select the member function from the set of overloaded member
|
|
|
|
|
functions. If a nonstatic member function is selected, the
|
|
|
|
|
reference to the overloaded function name is required to have the
|
|
|
|
|
form of a pointer to member as described in 5.3.1.
|
|
|
|
|
|
|
|
|
|
If more than one function is selected, any template functions in
|
|
|
|
|
the set are eliminated if the set also contains a non-template
|
|
|
|
|
function, and any given template function is eliminated if the
|
|
|
|
|
set contains a second template function that is more specialized
|
|
|
|
|
than the first according to the partial ordering rules 14.5.5.2.
|
|
|
|
|
After such eliminations, if any, there shall remain exactly one
|
|
|
|
|
selected function. */
|
|
|
|
|
|
|
|
|
|
int is_ptrmem = 0;
|
|
|
|
|
int is_reference = 0;
|
|
|
|
|
/* We store the matches in a TREE_LIST rooted here. The functions
|
|
|
|
|
are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy
|
|
|
|
|
interoperability with most_specialized_instantiation. */
|
|
|
|
|
tree matches = NULL_TREE;
|
1998-12-16 16:51:21 +01:00
|
|
|
|
tree fn;
|
1998-12-09 17:20:05 +01:00
|
|
|
|
|
1998-12-14 16:35:40 +01:00
|
|
|
|
/* By the time we get here, we should be seeing only real
|
|
|
|
|
pointer-to-member types, not the internal POINTER_TYPE to
|
|
|
|
|
METHOD_TYPE representation. */
|
|
|
|
|
my_friendly_assert (!(TREE_CODE (target_type) == POINTER_TYPE
|
|
|
|
|
&& (TREE_CODE (TREE_TYPE (target_type))
|
|
|
|
|
== METHOD_TYPE)), 0);
|
1998-12-09 17:20:05 +01:00
|
|
|
|
|
|
|
|
|
/* Check that the TARGET_TYPE is reasonable. */
|
|
|
|
|
if (TYPE_PTRFN_P (target_type))
|
|
|
|
|
/* This is OK. */
|
|
|
|
|
;
|
|
|
|
|
else if (TYPE_PTRMEMFUNC_P (target_type))
|
|
|
|
|
/* This is OK, too. */
|
|
|
|
|
is_ptrmem = 1;
|
|
|
|
|
else if (TREE_CODE (target_type) == FUNCTION_TYPE)
|
|
|
|
|
{
|
|
|
|
|
/* This is OK, too. This comes from a conversion to reference
|
|
|
|
|
type. */
|
|
|
|
|
target_type = build_reference_type (target_type);
|
|
|
|
|
is_reference = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (complain)
|
|
|
|
|
cp_error("cannot resolve overloaded function `%D' based on conversion to type `%T'",
|
|
|
|
|
DECL_NAME (OVL_FUNCTION (overload)), target_type);
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If we can find a non-template function that matches, we can just
|
|
|
|
|
use it. There's no point in generating template instantiations
|
|
|
|
|
if we're just going to throw them out anyhow. But, of course, we
|
|
|
|
|
can only do this when we don't *need* a template function. */
|
|
|
|
|
if (!template_only)
|
|
|
|
|
{
|
|
|
|
|
tree fns;
|
|
|
|
|
|
|
|
|
|
for (fns = overload; fns; fns = OVL_CHAIN (fns))
|
|
|
|
|
{
|
|
|
|
|
tree fn = OVL_FUNCTION (fns);
|
|
|
|
|
tree fntype;
|
1998-05-08 04:06:26 +02:00
|
|
|
|
|
1998-12-09 17:20:05 +01:00
|
|
|
|
if (TREE_CODE (fn) == TEMPLATE_DECL)
|
|
|
|
|
/* We're not looking for templates just yet. */
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
|
|
|
|
|
!= is_ptrmem)
|
|
|
|
|
/* We're looking for a non-static member, and this isn't
|
|
|
|
|
one, or vice versa. */
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* See if there's a match. */
|
|
|
|
|
fntype = TREE_TYPE (fn);
|
|
|
|
|
if (is_ptrmem)
|
|
|
|
|
fntype = build_ptrmemfunc_type (build_pointer_type (fntype));
|
|
|
|
|
else if (!is_reference)
|
|
|
|
|
fntype = build_pointer_type (fntype);
|
|
|
|
|
|
|
|
|
|
if (can_convert_arg (target_type, fntype, fn))
|
1999-09-09 08:17:13 +02:00
|
|
|
|
matches = tree_cons (fn, NULL_TREE, matches);
|
1998-12-09 17:20:05 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now, if we've already got a match (or matches), there's no need
|
|
|
|
|
to proceed to the template functions. But, if we don't have a
|
|
|
|
|
match we need to look at them, too. */
|
|
|
|
|
if (!matches)
|
1998-05-08 04:06:26 +02:00
|
|
|
|
{
|
1998-12-09 17:20:05 +01:00
|
|
|
|
tree target_fn_type;
|
|
|
|
|
tree target_arg_types;
|
|
|
|
|
tree fns;
|
|
|
|
|
|
|
|
|
|
if (is_ptrmem)
|
1999-02-16 12:32:51 +01:00
|
|
|
|
target_fn_type
|
|
|
|
|
= TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (target_type));
|
1998-05-08 04:06:26 +02:00
|
|
|
|
else
|
1999-02-16 12:32:51 +01:00
|
|
|
|
target_fn_type = TREE_TYPE (target_type);
|
|
|
|
|
target_arg_types = TYPE_ARG_TYPES (target_fn_type);
|
|
|
|
|
|
1998-12-09 17:20:05 +01:00
|
|
|
|
for (fns = overload; fns; fns = OVL_CHAIN (fns))
|
|
|
|
|
{
|
|
|
|
|
tree fn = OVL_FUNCTION (fns);
|
|
|
|
|
tree instantiation;
|
|
|
|
|
tree instantiation_type;
|
|
|
|
|
tree targs;
|
|
|
|
|
|
|
|
|
|
if (TREE_CODE (fn) != TEMPLATE_DECL)
|
|
|
|
|
/* We're only looking for templates. */
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
|
|
|
|
|
!= is_ptrmem)
|
1999-02-16 12:32:51 +01:00
|
|
|
|
/* We're not looking for a non-static member, and this is
|
1998-12-09 17:20:05 +01:00
|
|
|
|
one, or vice versa. */
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Try to do argument deduction. */
|
1999-10-28 07:10:05 +02:00
|
|
|
|
targs = make_tree_vec (DECL_NTPARMS (fn));
|
1999-02-16 12:32:51 +01:00
|
|
|
|
if (fn_type_unification (fn, explicit_targs, targs,
|
|
|
|
|
target_arg_types, NULL_TREE,
|
1999-02-21 17:38:23 +01:00
|
|
|
|
DEDUCE_EXACT) != 0)
|
1998-12-09 17:20:05 +01:00
|
|
|
|
/* Argument deduction failed. */
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Instantiate the template. */
|
|
|
|
|
instantiation = instantiate_template (fn, targs);
|
|
|
|
|
if (instantiation == error_mark_node)
|
|
|
|
|
/* Instantiation failed. */
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* See if there's a match. */
|
|
|
|
|
instantiation_type = TREE_TYPE (instantiation);
|
|
|
|
|
if (is_ptrmem)
|
|
|
|
|
instantiation_type =
|
|
|
|
|
build_ptrmemfunc_type (build_pointer_type (instantiation_type));
|
|
|
|
|
else if (!is_reference)
|
|
|
|
|
instantiation_type = build_pointer_type (instantiation_type);
|
|
|
|
|
if (can_convert_arg (target_type, instantiation_type, instantiation))
|
1999-09-09 08:17:13 +02:00
|
|
|
|
matches = tree_cons (instantiation, fn, matches);
|
1998-12-09 17:20:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now, remove all but the most specialized of the matches. */
|
|
|
|
|
if (matches)
|
|
|
|
|
{
|
|
|
|
|
tree match = most_specialized_instantiation (matches,
|
|
|
|
|
explicit_targs);
|
|
|
|
|
|
|
|
|
|
if (match != error_mark_node)
|
1999-09-09 08:17:13 +02:00
|
|
|
|
matches = tree_cons (match, NULL_TREE, NULL_TREE);
|
1998-12-09 17:20:05 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Now we should have exactly one function in MATCHES. */
|
|
|
|
|
if (matches == NULL_TREE)
|
|
|
|
|
{
|
|
|
|
|
/* There were *no* matches. */
|
|
|
|
|
if (complain)
|
|
|
|
|
{
|
1999-01-18 14:32:57 +01:00
|
|
|
|
cp_error ("no matches converting function `%D' to type `%#T'",
|
1998-12-09 17:20:05 +01:00
|
|
|
|
DECL_NAME (OVL_FUNCTION (overload)),
|
|
|
|
|
target_type);
|
1999-01-18 14:32:57 +01:00
|
|
|
|
|
|
|
|
|
/* print_candidates expects a chain with the functions in
|
|
|
|
|
TREE_VALUE slots, so we cons one up here (we're losing anyway,
|
|
|
|
|
so why be clever?). */
|
|
|
|
|
for (; overload; overload = OVL_NEXT (overload))
|
1999-09-09 08:17:13 +02:00
|
|
|
|
matches = tree_cons (NULL_TREE, OVL_CURRENT (overload),
|
|
|
|
|
matches);
|
1999-01-18 14:32:57 +01:00
|
|
|
|
|
|
|
|
|
print_candidates (matches);
|
1998-12-09 17:20:05 +01:00
|
|
|
|
}
|
|
|
|
|
return error_mark_node;
|
1998-05-08 04:06:26 +02:00
|
|
|
|
}
|
1998-12-09 17:20:05 +01:00
|
|
|
|
else if (TREE_CHAIN (matches))
|
|
|
|
|
{
|
|
|
|
|
/* There were too many matches. */
|
|
|
|
|
|
|
|
|
|
if (complain)
|
|
|
|
|
{
|
|
|
|
|
tree match;
|
|
|
|
|
|
|
|
|
|
cp_error ("converting overloaded function `%D' to type `%#T' is ambiguous",
|
|
|
|
|
DECL_NAME (OVL_FUNCTION (overload)),
|
|
|
|
|
target_type);
|
|
|
|
|
|
|
|
|
|
/* Since print_candidates expects the functions in the
|
|
|
|
|
TREE_VALUE slot, we flip them here. */
|
|
|
|
|
for (match = matches; match; match = TREE_CHAIN (match))
|
|
|
|
|
TREE_VALUE (match) = TREE_PURPOSE (match);
|
|
|
|
|
|
|
|
|
|
print_candidates (matches);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
|
1998-12-16 16:51:21 +01:00
|
|
|
|
/* Good, exactly one match. Now, convert it to the correct type. */
|
|
|
|
|
fn = TREE_PURPOSE (matches);
|
|
|
|
|
|
class.c (resolve_address_of_overloaded_function): Mark the chosen function used.
* class.c (resolve_address_of_overloaded_function): Mark the
chosen function used.
* call.c (build_call): Make sure that a function coming in has
been marked used already.
* decl.c (expand_static_init): Call mark_used instead of
assemble_external.
* except.c (call_eh_info, do_pop_exception, expand_end_eh_spec,
alloc_eh_object, expand_throw): Likewise.
* init.c (build_builtin_delete_call): Likewise.
* rtti.c (call_void_fn, get_tinfo_fn, build_dynamic_cast_1,
expand_si_desc, expand_class_desc, expand_ptr_desc, expand_attr_desc,
expand_generic_desc): Likewise.
From-SVN: r24862
1999-01-25 21:43:21 +01:00
|
|
|
|
mark_used (fn);
|
|
|
|
|
|
1998-12-16 16:51:21 +01:00
|
|
|
|
if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
|
|
|
|
|
return build_unary_op (ADDR_EXPR, fn, 0);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* The target must be a REFERENCE_TYPE. Above, build_unary_op
|
|
|
|
|
will mark the function as addressed, but here we must do it
|
|
|
|
|
explicitly. */
|
|
|
|
|
mark_addressable (fn);
|
|
|
|
|
|
|
|
|
|
return fn;
|
|
|
|
|
}
|
1998-05-08 04:06:26 +02:00
|
|
|
|
}
|
|
|
|
|
|
1996-03-02 02:49:15 +01:00
|
|
|
|
/* This function will instantiate the type of the expression given in
|
|
|
|
|
RHS to match the type of LHSTYPE. If errors exist, then return
|
1998-12-03 17:58:03 +01:00
|
|
|
|
error_mark_node. We only complain is COMPLAIN is set. If we are
|
1996-03-02 02:49:15 +01:00
|
|
|
|
not complaining, never modify rhs, as overload resolution wants to
|
|
|
|
|
try many possible instantiations, in hopes that at least one will
|
|
|
|
|
work.
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1999-04-13 02:20:42 +02:00
|
|
|
|
FLAGS is a bitmask, as we see at the top of the function.
|
|
|
|
|
|
1998-10-27 23:33:40 +01:00
|
|
|
|
For non-recursive calls, LHSTYPE should be a function, pointer to
|
|
|
|
|
function, or a pointer to member function. */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
tree
|
1999-04-13 02:20:42 +02:00
|
|
|
|
instantiate_type (lhstype, rhs, flags)
|
1994-02-24 02:02:37 +01:00
|
|
|
|
tree lhstype, rhs;
|
1999-04-13 02:20:42 +02:00
|
|
|
|
int flags;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
{
|
1999-04-13 02:20:42 +02:00
|
|
|
|
int complain = (flags & 1);
|
|
|
|
|
int strict = (flags & 2) ? COMPARE_NO_ATTRIBUTES : COMPARE_STRICT;
|
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
|
|
|
|
|
{
|
|
|
|
|
if (complain)
|
1998-09-07 16:25:35 +02:00
|
|
|
|
error ("not enough type information");
|
1994-02-24 02:02:37 +01:00
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs)))
|
1998-01-29 01:08:53 +01:00
|
|
|
|
{
|
1999-04-13 02:20:42 +02:00
|
|
|
|
if (comptypes (lhstype, TREE_TYPE (rhs), strict))
|
1998-01-29 01:08:53 +01:00
|
|
|
|
return rhs;
|
|
|
|
|
if (complain)
|
1998-09-07 16:25:35 +02:00
|
|
|
|
cp_error ("argument of type `%T' does not match `%T'",
|
1998-01-29 01:08:53 +01:00
|
|
|
|
TREE_TYPE (rhs), lhstype);
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1998-05-08 04:06:26 +02:00
|
|
|
|
/* We don't overwrite rhs if it is an overloaded function.
|
|
|
|
|
Copying it would destroy the tree link. */
|
|
|
|
|
if (TREE_CODE (rhs) != OVERLOAD)
|
|
|
|
|
rhs = copy_node (rhs);
|
1996-08-09 00:54:56 +02:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
/* This should really only be used when attempting to distinguish
|
|
|
|
|
what sort of a pointer to function we have. For now, any
|
|
|
|
|
arithmetic operation which is not supported on pointers
|
|
|
|
|
is rejected as an error. */
|
|
|
|
|
|
|
|
|
|
switch (TREE_CODE (rhs))
|
|
|
|
|
{
|
|
|
|
|
case TYPE_EXPR:
|
|
|
|
|
case CONVERT_EXPR:
|
|
|
|
|
case SAVE_EXPR:
|
|
|
|
|
case CONSTRUCTOR:
|
|
|
|
|
case BUFFER_REF:
|
|
|
|
|
my_friendly_abort (177);
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
|
|
|
|
|
case INDIRECT_REF:
|
|
|
|
|
case ARRAY_REF:
|
1996-03-02 02:49:15 +01:00
|
|
|
|
{
|
|
|
|
|
tree new_rhs;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
1996-03-02 02:49:15 +01:00
|
|
|
|
new_rhs = instantiate_type (build_pointer_type (lhstype),
|
1999-04-13 02:20:42 +02:00
|
|
|
|
TREE_OPERAND (rhs, 0), flags);
|
1996-03-02 02:49:15 +01:00
|
|
|
|
if (new_rhs == error_mark_node)
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
|
|
|
|
|
TREE_TYPE (rhs) = lhstype;
|
|
|
|
|
TREE_OPERAND (rhs, 0) = new_rhs;
|
|
|
|
|
return rhs;
|
|
|
|
|
}
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
case NOP_EXPR:
|
|
|
|
|
rhs = copy_node (TREE_OPERAND (rhs, 0));
|
|
|
|
|
TREE_TYPE (rhs) = unknown_type_node;
|
1999-04-13 02:20:42 +02:00
|
|
|
|
return instantiate_type (lhstype, rhs, flags);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
case COMPONENT_REF:
|
|
|
|
|
{
|
1999-08-12 08:52:30 +02:00
|
|
|
|
tree r = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
|
1998-12-16 16:51:21 +01:00
|
|
|
|
|
1999-08-12 08:52:30 +02:00
|
|
|
|
if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype)
|
|
|
|
|
&& complain && !flag_ms_extensions)
|
1998-12-16 16:51:21 +01:00
|
|
|
|
{
|
1999-08-12 08:52:30 +02:00
|
|
|
|
/* Note: we check this after the recursive call to avoid
|
|
|
|
|
complaining about cases where overload resolution fails. */
|
|
|
|
|
|
|
|
|
|
tree t = TREE_TYPE (TREE_OPERAND (rhs, 0));
|
|
|
|
|
tree fn = PTRMEM_CST_MEMBER (r);
|
|
|
|
|
|
|
|
|
|
my_friendly_assert (TREE_CODE (r) == PTRMEM_CST, 990811);
|
|
|
|
|
|
|
|
|
|
cp_pedwarn
|
|
|
|
|
("object-dependent reference to `%E' can only be used in a call",
|
|
|
|
|
DECL_NAME (fn));
|
|
|
|
|
cp_pedwarn
|
|
|
|
|
(" to form a pointer to member function, say `&%T::%E'",
|
|
|
|
|
t, DECL_NAME (fn));
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
1999-08-12 08:52:30 +02:00
|
|
|
|
|
1998-12-16 16:51:21 +01:00
|
|
|
|
return r;
|
1994-02-24 02:02:37 +01:00
|
|
|
|
}
|
|
|
|
|
|
1998-06-12 11:47:04 +02:00
|
|
|
|
case OFFSET_REF:
|
1999-05-10 14:12:58 +02:00
|
|
|
|
rhs = TREE_OPERAND (rhs, 1);
|
|
|
|
|
if (BASELINK_P (rhs))
|
|
|
|
|
return instantiate_type (lhstype, TREE_VALUE (rhs), flags);
|
|
|
|
|
|
1998-06-12 11:47:04 +02:00
|
|
|
|
/* This can happen if we are forming a pointer-to-member for a
|
|
|
|
|
member template. */
|
|
|
|
|
my_friendly_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR, 0);
|
1999-05-10 14:12:58 +02:00
|
|
|
|
|
1998-06-12 11:47:04 +02:00
|
|
|
|
/* Fall through. */
|
1998-06-07 14:13:54 +02:00
|
|
|
|
|
1997-09-28 21:16:59 +02:00
|
|
|
|
case TEMPLATE_ID_EXPR:
|
1998-12-09 17:20:05 +01:00
|
|
|
|
return
|
|
|
|
|
resolve_address_of_overloaded_function (lhstype,
|
|
|
|
|
TREE_OPERAND (rhs, 0),
|
|
|
|
|
complain,
|
|
|
|
|
/*template_only=*/1,
|
|
|
|
|
TREE_OPERAND (rhs, 1));
|
1997-09-28 21:16:59 +02:00
|
|
|
|
|
1998-05-08 04:06:26 +02:00
|
|
|
|
case OVERLOAD:
|
1998-12-09 17:20:05 +01:00
|
|
|
|
return
|
|
|
|
|
resolve_address_of_overloaded_function (lhstype,
|
|
|
|
|
rhs,
|
|
|
|
|
complain,
|
|
|
|
|
/*template_only=*/0,
|
|
|
|
|
/*explicit_targs=*/NULL_TREE);
|
1998-05-08 04:06:26 +02:00
|
|
|
|
|
|
|
|
|
case TREE_LIST:
|
1999-04-13 02:20:42 +02:00
|
|
|
|
/* Now we should have a baselink. */
|
|
|
|
|
my_friendly_assert (BASELINK_P (rhs), 990412);
|
1998-05-18 05:03:44 +02:00
|
|
|
|
|
1999-04-13 02:20:42 +02:00
|
|
|
|
return instantiate_type (lhstype, TREE_VALUE (rhs), flags);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
case CALL_EXPR:
|
|
|
|
|
/* This is too hard for now. */
|
|
|
|
|
my_friendly_abort (183);
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
|
|
|
|
|
case PLUS_EXPR:
|
|
|
|
|
case MINUS_EXPR:
|
|
|
|
|
case COMPOUND_EXPR:
|
1994-06-03 23:42:31 +02:00
|
|
|
|
TREE_OPERAND (rhs, 0)
|
1999-04-13 02:20:42 +02:00
|
|
|
|
= instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (TREE_OPERAND (rhs, 0) == error_mark_node)
|
|
|
|
|
return error_mark_node;
|
1994-06-03 23:42:31 +02:00
|
|
|
|
TREE_OPERAND (rhs, 1)
|
1999-04-13 02:20:42 +02:00
|
|
|
|
= instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (TREE_OPERAND (rhs, 1) == error_mark_node)
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
|
|
|
|
|
TREE_TYPE (rhs) = lhstype;
|
|
|
|
|
return rhs;
|
|
|
|
|
|
|
|
|
|
case MULT_EXPR:
|
|
|
|
|
case TRUNC_DIV_EXPR:
|
|
|
|
|
case FLOOR_DIV_EXPR:
|
|
|
|
|
case CEIL_DIV_EXPR:
|
|
|
|
|
case ROUND_DIV_EXPR:
|
|
|
|
|
case RDIV_EXPR:
|
|
|
|
|
case TRUNC_MOD_EXPR:
|
|
|
|
|
case FLOOR_MOD_EXPR:
|
|
|
|
|
case CEIL_MOD_EXPR:
|
|
|
|
|
case ROUND_MOD_EXPR:
|
|
|
|
|
case FIX_ROUND_EXPR:
|
|
|
|
|
case FIX_FLOOR_EXPR:
|
|
|
|
|
case FIX_CEIL_EXPR:
|
|
|
|
|
case FIX_TRUNC_EXPR:
|
|
|
|
|
case FLOAT_EXPR:
|
|
|
|
|
case NEGATE_EXPR:
|
|
|
|
|
case ABS_EXPR:
|
|
|
|
|
case MAX_EXPR:
|
|
|
|
|
case MIN_EXPR:
|
|
|
|
|
case FFS_EXPR:
|
|
|
|
|
|
|
|
|
|
case BIT_AND_EXPR:
|
|
|
|
|
case BIT_IOR_EXPR:
|
|
|
|
|
case BIT_XOR_EXPR:
|
|
|
|
|
case LSHIFT_EXPR:
|
|
|
|
|
case RSHIFT_EXPR:
|
|
|
|
|
case LROTATE_EXPR:
|
|
|
|
|
case RROTATE_EXPR:
|
|
|
|
|
|
|
|
|
|
case PREINCREMENT_EXPR:
|
|
|
|
|
case PREDECREMENT_EXPR:
|
|
|
|
|
case POSTINCREMENT_EXPR:
|
|
|
|
|
case POSTDECREMENT_EXPR:
|
|
|
|
|
if (complain)
|
1998-09-07 16:25:35 +02:00
|
|
|
|
error ("invalid operation on uninstantiated type");
|
1994-02-24 02:02:37 +01:00
|
|
|
|
return error_mark_node;
|
|
|
|
|
|
|
|
|
|
case TRUTH_AND_EXPR:
|
|
|
|
|
case TRUTH_OR_EXPR:
|
|
|
|
|
case TRUTH_XOR_EXPR:
|
|
|
|
|
case LT_EXPR:
|
|
|
|
|
case LE_EXPR:
|
|
|
|
|
case GT_EXPR:
|
|
|
|
|
case GE_EXPR:
|
|
|
|
|
case EQ_EXPR:
|
|
|
|
|
case NE_EXPR:
|
|
|
|
|
case TRUTH_ANDIF_EXPR:
|
|
|
|
|
case TRUTH_ORIF_EXPR:
|
|
|
|
|
case TRUTH_NOT_EXPR:
|
|
|
|
|
if (complain)
|
1998-09-07 16:25:35 +02:00
|
|
|
|
error ("not enough type information");
|
1994-02-24 02:02:37 +01:00
|
|
|
|
return error_mark_node;
|
|
|
|
|
|
|
|
|
|
case COND_EXPR:
|
|
|
|
|
if (type_unknown_p (TREE_OPERAND (rhs, 0)))
|
|
|
|
|
{
|
|
|
|
|
if (complain)
|
1998-09-07 16:25:35 +02:00
|
|
|
|
error ("not enough type information");
|
1994-02-24 02:02:37 +01:00
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
1994-06-03 23:42:31 +02:00
|
|
|
|
TREE_OPERAND (rhs, 1)
|
1999-04-13 02:20:42 +02:00
|
|
|
|
= instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (TREE_OPERAND (rhs, 1) == error_mark_node)
|
|
|
|
|
return error_mark_node;
|
1994-06-03 23:42:31 +02:00
|
|
|
|
TREE_OPERAND (rhs, 2)
|
1999-04-13 02:20:42 +02:00
|
|
|
|
= instantiate_type (lhstype, TREE_OPERAND (rhs, 2), flags);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (TREE_OPERAND (rhs, 2) == error_mark_node)
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
|
|
|
|
|
TREE_TYPE (rhs) = lhstype;
|
|
|
|
|
return rhs;
|
|
|
|
|
|
|
|
|
|
case MODIFY_EXPR:
|
1994-06-03 23:42:31 +02:00
|
|
|
|
TREE_OPERAND (rhs, 1)
|
1999-04-13 02:20:42 +02:00
|
|
|
|
= instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
if (TREE_OPERAND (rhs, 1) == error_mark_node)
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
|
|
|
|
|
TREE_TYPE (rhs) = lhstype;
|
|
|
|
|
return rhs;
|
|
|
|
|
|
|
|
|
|
case ADDR_EXPR:
|
1999-04-13 02:20:42 +02:00
|
|
|
|
return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
|
|
|
|
|
case ENTRY_VALUE_EXPR:
|
|
|
|
|
my_friendly_abort (184);
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
|
|
|
|
|
case ERROR_MARK:
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
my_friendly_abort (185);
|
|
|
|
|
return error_mark_node;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return the name of the virtual function pointer field
|
|
|
|
|
(as an IDENTIFIER_NODE) for the given TYPE. Note that
|
|
|
|
|
this may have to look back through base types to find the
|
|
|
|
|
ultimate field name. (For single inheritance, these could
|
|
|
|
|
all be the same name. Who knows for multiple inheritance). */
|
1996-07-11 03:13:25 +02:00
|
|
|
|
|
1994-02-24 02:02:37 +01:00
|
|
|
|
static tree
|
|
|
|
|
get_vfield_name (type)
|
|
|
|
|
tree type;
|
|
|
|
|
{
|
|
|
|
|
tree binfo = TYPE_BINFO (type);
|
|
|
|
|
char *buf;
|
|
|
|
|
|
|
|
|
|
while (BINFO_BASETYPES (binfo)
|
2000-01-17 05:08:01 +01:00
|
|
|
|
&& TYPE_CONTAINS_VPTR_P (BINFO_TYPE (BINFO_BASETYPE (binfo, 0)))
|
1994-02-24 02:02:37 +01:00
|
|
|
|
&& ! TREE_VIA_VIRTUAL (BINFO_BASETYPE (binfo, 0)))
|
|
|
|
|
binfo = BINFO_BASETYPE (binfo, 0);
|
|
|
|
|
|
|
|
|
|
type = BINFO_TYPE (binfo);
|
1997-10-16 09:20:46 +02:00
|
|
|
|
buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT)
|
|
|
|
|
+ TYPE_NAME_LENGTH (type) + 2);
|
1994-02-24 02:02:37 +01:00
|
|
|
|
sprintf (buf, VFIELD_NAME_FORMAT, TYPE_NAME_STRING (type));
|
|
|
|
|
return get_identifier (buf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
print_class_statistics ()
|
|
|
|
|
{
|
|
|
|
|
#ifdef GATHER_STATISTICS
|
|
|
|
|
fprintf (stderr, "convert_harshness = %d\n", n_convert_harshness);
|
|
|
|
|
fprintf (stderr, "compute_conversion_costs = %d\n", n_compute_conversion_costs);
|
|
|
|
|
fprintf (stderr, "build_method_call = %d (inner = %d)\n",
|
|
|
|
|
n_build_method_call, n_inner_fields_searched);
|
|
|
|
|
if (n_vtables)
|
|
|
|
|
{
|
|
|
|
|
fprintf (stderr, "vtables = %d; vtable searches = %d\n",
|
|
|
|
|
n_vtables, n_vtable_searches);
|
|
|
|
|
fprintf (stderr, "vtable entries = %d; vtable elems = %d\n",
|
|
|
|
|
n_vtable_entries, n_vtable_elems);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
1996-04-02 23:44:27 +02:00
|
|
|
|
/* Build a dummy reference to ourselves so Derived::Base (and A::A) works,
|
|
|
|
|
according to [class]:
|
|
|
|
|
The class-name is also inserted
|
|
|
|
|
into the scope of the class itself. For purposes of access checking,
|
|
|
|
|
the inserted class name is treated as if it were a public member name. */
|
|
|
|
|
|
1999-03-10 00:02:42 +01:00
|
|
|
|
void
|
1996-04-02 23:44:27 +02:00
|
|
|
|
build_self_reference ()
|
|
|
|
|
{
|
|
|
|
|
tree name = constructor_name (current_class_type);
|
|
|
|
|
tree value = build_lang_decl (TYPE_DECL, name, current_class_type);
|
1999-03-10 00:02:42 +01:00
|
|
|
|
tree saved_cas;
|
|
|
|
|
|
1996-04-02 23:44:27 +02:00
|
|
|
|
DECL_NONLOCAL (value) = 1;
|
|
|
|
|
DECL_CONTEXT (value) = current_class_type;
|
|
|
|
|
DECL_ARTIFICIAL (value) = 1;
|
|
|
|
|
|
1999-08-14 11:23:49 +02:00
|
|
|
|
if (processing_template_decl)
|
|
|
|
|
value = push_template_decl (value);
|
|
|
|
|
|
1999-03-10 00:02:42 +01:00
|
|
|
|
saved_cas = current_access_specifier;
|
|
|
|
|
current_access_specifier = access_public_node;
|
|
|
|
|
finish_member_declaration (value);
|
|
|
|
|
current_access_specifier = saved_cas;
|
1996-04-02 23:44:27 +02:00
|
|
|
|
}
|
1998-04-01 19:05:25 +02:00
|
|
|
|
|
|
|
|
|
/* Returns 1 if TYPE contains only padding bytes. */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
is_empty_class (type)
|
|
|
|
|
tree type;
|
|
|
|
|
{
|
|
|
|
|
tree t;
|
|
|
|
|
|
1998-05-19 20:16:49 +02:00
|
|
|
|
if (type == error_mark_node)
|
|
|
|
|
return 0;
|
|
|
|
|
|
1998-04-07 05:48:22 +02:00
|
|
|
|
if (! IS_AGGR_TYPE (type))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (flag_new_abi)
|
c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-common.c (decl_attributes): Set DECL_SIZE_UNIT.
* c-decl.c (duplicate_decls, finish_enum): Likewise.
(finish_decl): Remove -Wlarger-than code from here.
* flags.h (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
* fold-const.c (size_int_wide): No more HIGH parm; NUMBER is signed.
Clean up checking to see if in table.
(make_bit_field_ref): Remove extra parm to bitsize_int.
* ggc-common.c (ggc_mark_tree_children): Mark DECL_SIZE_UNIT.
* print-tree.c (print_node): Print DECL_SIZE_UNIT and TYPE_SIZE_UNIT.
* stmt.c (expand_decl): Use DECL_SIZE_UNIT for stack checking size
and for computing size of decl.
* stor-layout.c (layout_decl): Set DECL_SIZE_UNIT.
Move -Wlarger-than code to here.
(layout_record): Remove extra arg to bitsize_int.
Set TYPE_BINFO_SIZE_UNIT.
(layout_union): Remove extra arg to bitsize_int.
Use proper type for size of QUAL_UNION.
(layout_type): Remove extra arg to bitsize_int.
* toplev.c (id_clash_len): Now int.
(larger_than_size): Now HOST_WIDE_INT.
(decode_W_option): Clean up id-clash and larger-than- cases.
* tree.c (get_identifier, maybe_get_identifier): Remove unneeded casts.
(expr_align, case FUNCTION_DECL): DECL_ALIGN is not defined.
* tree.h (BINFO_SIZE_UNIT, TYPE_BINFO_SIZE_UNIT, DECL_SIZE_UNIT): New.
(struct tree_decl): New field size_unit.
(size_int_wide): No HIGH operand; NUMBER is now signed.
(size_int_2): Deleted.
(size_int, bitsize_int): Don't use it and rework args.
* varasm.c (assemble_variable, output_constructor): Use DECL_SIZE_UNIT.
* ch/decl.c (layout_enum): Set DECL_SIZE_UNIT.
* ch/satisfy.c (safe_satisfy_decl): Likewise.
* cp/class.c (build_primary_vtable, layout_vtable_decl): Likewise.
(avoid_overlap, build_base_field): Likewise.
(build_base_field, build_base_fields, is_empty_class):
Test DECL_SIZE with integer_zero.
(layout_class_type): Set CLASSTYPE_SIZE_UNIT.
* cp/cp-tree.h (struct lang_type): New field size_unit.
(CLASSTYPE_SIZE_UNIT): New macro.
* cp/decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
(cp_finish_decl): Delete -Wlarger-than processing.
* cp/optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
* cp/pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
* cp/tree.c (make_binfo): binfo vector is one entry longer.
(walk_tree): Walk DECL_SIZE_UNIT.
* f/com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
(ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
(duplicate_decls): Likewise.
(ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
(finish_decl): Delete -Wlarger-than processing.
* java/class.c (build_class_ref, push_super_field): Set DECL_SIZE_UNIT.
* java/constants.c (build_constants_constructor): Likewise.
From-SVN: r32068
2000-02-20 02:11:00 +01:00
|
|
|
|
return integer_zerop (CLASSTYPE_SIZE (type));
|
1998-04-07 05:48:22 +02:00
|
|
|
|
|
|
|
|
|
if (TYPE_BINFO_BASETYPES (type))
|
1998-04-01 19:05:25 +02:00
|
|
|
|
return 0;
|
|
|
|
|
t = TYPE_FIELDS (type);
|
|
|
|
|
while (t && TREE_CODE (t) != FIELD_DECL)
|
|
|
|
|
t = TREE_CHAIN (t);
|
|
|
|
|
return (t == NULL_TREE);
|
|
|
|
|
}
|
1998-09-09 04:14:55 +02:00
|
|
|
|
|
|
|
|
|
/* Find the enclosing class of the given NODE. NODE can be a *_DECL or
|
|
|
|
|
a *_TYPE node. NODE can also be a local class. */
|
|
|
|
|
|
|
|
|
|
tree
|
|
|
|
|
get_enclosing_class (type)
|
|
|
|
|
tree type;
|
|
|
|
|
{
|
|
|
|
|
tree node = type;
|
|
|
|
|
|
|
|
|
|
while (node && TREE_CODE (node) != NAMESPACE_DECL)
|
|
|
|
|
{
|
|
|
|
|
switch (TREE_CODE_CLASS (TREE_CODE (node)))
|
|
|
|
|
{
|
|
|
|
|
case 'd':
|
|
|
|
|
node = DECL_CONTEXT (node);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 't':
|
|
|
|
|
if (node != type)
|
|
|
|
|
return node;
|
|
|
|
|
node = TYPE_CONTEXT (node);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
my_friendly_abort (0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL_TREE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return 1 if TYPE or one of its enclosing classes is derived from BASE. */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
is_base_of_enclosing_class (base, type)
|
|
|
|
|
tree base, type;
|
|
|
|
|
{
|
|
|
|
|
while (type)
|
|
|
|
|
{
|
|
|
|
|
if (get_binfo (base, type, 0))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
type = get_enclosing_class (type);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
tinfo.h (__class_type_info): Fix illegal declaration.
1999-04-02 Mark Mitchell <mark@codesourcery.com>
* tinfo.h (__class_type_info): Fix illegal declaration.
* cp-tree.def (TEMPLATE_ID_EXPR): Update comment.
* cp-tree.h (INHERITED_VALUE_BINDING_P): New macro.
(IDENTIFIER_CLASS_VALUE): Improve documentation.
(is_properly_derived_from): Declare.
(invalidate_class_lookup_cache): Likewise.
(maybe_maybe_note_name_used_in_class): Likewise.
(note_name_declared_in_class): Likewise.
(push_using_decl): Remove duplicate declaration.
(id_in_current_class): Remove declaration.
(push_class_binding): Change prototype.
(clear_identitifer_class_values): Declare.
* call.c (is_properly_derived_from): Make it global.
(build_new_function_call): Be careful about updating candidates.
(build_new_method_call): Handle COMPONENT_REFs. Don't crash when
asked to make illegal calls.
* class.c: Include splay-tree.h.
(class_stack_node): Add names_used slot.
(check_member_decl_is_same_in_complete_scope): Remove.
(add_method): Fix comment. Push the declaration into class
scope.
(finish_struct_1): When popping the class, pop the bindings too.
Remove check for data member/function member conflict.
(finish_struct): Remove calls to
check_member_decl_is_same_in_complete_scope. Change calls to
popclass.
(pushclass): Clear names_used in the class stack entry.
Use invalidate_class_lookup_cache to remove cached entries, rather
than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE
before entering a new class. Remove dead code. Don't mess with
current_function_decl when pushing declarations.
(invalidate_class_lookup_cache): New function, split out from ...
(popclass): Here. Clean up names_used on our way out.
(instantiate_type): Adjust.
(build_self_reference): Don't push the declaration here.
(maybe_note_name_used_in_class): New function.
(note_name_declared_in_class): Likewise.
* decl.c (add_binding): Change prototype.
(find_class_binding_level): New function.
(innermost_nonclass_level): Likewise.
(current_binding_level): Update documentation.
(inner_binding_level): Remove. Replace with current_binding_level
throughout.
(push_binding_level): Remove special handling of
class_binding_level.
(pop_binding_level): Likewise. Use find_class_binding_level.
(suspend_binding_level): Likewise.
(global_bindings_p): Use innermost_nonclass_level.
(toplevel_bindings_p): Likewise.
(namespace_bindings_p): Likewise.
(pseudo_global_level_p): Likewise.
(push_binding): Clear INHERITED_VALUE_BINDING_P.
(add_binding): Check for illegal multiple declarations. Return a
value indicating whether or not the new binding was legal.
(push_local_binding): Skip over class binding levels. Check
return value from add_binding.
(push_class_binding): Set INHERITED_VALUE_BINDING_P. Call
note_name_declared_in_class.
(pushlevel_class): Remove "fake out the rest of the compiler"
code.
(poplevel_class): Reset IDENTIFIER_CLASS_VALUEs.
(clear_identifier_class_values): New function.
(pop_from_top_level): Use it.
(pop_everything): Tweak.
(maybe_process_template_type_declaration): Don't push the
declaration for the template here.
(pushtag): Don't push tag declarations into class scope here.
(pushdecl): Apply DeMorgan's law for readability.
(pushdecl_class_level): Remove special-case code for
TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions.
(push_class_level_bindng): Deal with inherited bindings.
(lookup_name_real): Remove special-case code for
TYPE_BEING_DEFINED, and some implicit typename magic.
(grokdeclarator): Handle COMPONENT_REF for a template function.
(build_enumerator): Don't call pushdecl_class_level here.
(id_in_current_class): Remove.
* decl2.c (grokfield): Don't call pushdecl_class_level or
check_template_shadow.
* errfn.c (cp_file_of): Don't declare.
(cp_line_of): Likewise.
* error.c (dump_decl): Handle an OVERLOAD.
(cp_file_of): Likewise.
(cp_line_of): Likewise.
* init.c (build_member_call): Handle a COMPONENT_REF.
* lex.c (do_identifier): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* method.c (hack_identifier): Build COMPONENT_REFs for references
to member templates as well as member functions. Remove dead
code.
* parse.y (left_curly): Remove.
(nonnested_type): Call maybe_note_name_used_in_class, not
pushdecl_class_level.
* parse.c: Regenerated.
(nested_name_specifier_1): Likewise.
* pt.c (check_explicit_specialization): Adjust, for robustness.
(check_template_shadow): Handle OVERLOADs.
(build_template_decl): Set DECL_CONSTRUCTOR_P on the
TEMPLATE_DECL, if appropriate.
* search.c (envelope_add_decl): Remove.
(dfs_pushdecls): Likewise.
(dfs_compress_decls): Likewise.
(dfs_push_decls): New function.
(dfs_push_type_decls): Likewise.
(setup_class_bindings): Likewise.
(template_self_reference_p): Likewise.
(lookup_field_r): Use it.
(looup_member): Remove old comment. Deal with ambiguity.
(push_class_decls): Use dfs_push_decls and dfs_push_type_decls,
and remove envelope processing.
* semantics.c (begin_class_definition): Let pushclass push
declarations for base classes.
(finish_member_declaration): Push declarations into class scope.
* typeck.c (build_component_ref): Just put an OVERLOAD into the
COMPONENT_REF, not a TREE_LIST of an OVERLOAD.
(build_x_function_call): Deal with OVERLOAD. Handle template-ids.
* Makefile.in (class.o): Depend on splay-tree.h.
From-SVN: r26133
1999-04-02 17:36:57 +02:00
|
|
|
|
|
|
|
|
|
/* Note that NAME was looked up while the current class was being
|
|
|
|
|
defined and that the result of that lookup was DECL. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
maybe_note_name_used_in_class (name, decl)
|
|
|
|
|
tree name;
|
|
|
|
|
tree decl;
|
|
|
|
|
{
|
|
|
|
|
splay_tree names_used;
|
|
|
|
|
|
|
|
|
|
/* If we're not defining a class, there's nothing to do. */
|
|
|
|
|
if (!current_class_type || !TYPE_BEING_DEFINED (current_class_type))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* If there's already a binding for this NAME, then we don't have
|
|
|
|
|
anything to worry about. */
|
|
|
|
|
if (IDENTIFIER_CLASS_VALUE (name))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!current_class_stack[current_class_depth - 1].names_used)
|
|
|
|
|
current_class_stack[current_class_depth - 1].names_used
|
|
|
|
|
= splay_tree_new (splay_tree_compare_pointers, 0, 0);
|
|
|
|
|
names_used = current_class_stack[current_class_depth - 1].names_used;
|
|
|
|
|
|
|
|
|
|
splay_tree_insert (names_used,
|
|
|
|
|
(splay_tree_key) name,
|
|
|
|
|
(splay_tree_value) decl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Note that NAME was declared (as DECL) in the current class. Check
|
|
|
|
|
to see that the declaration is legal. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
note_name_declared_in_class (name, decl)
|
|
|
|
|
tree name;
|
|
|
|
|
tree decl;
|
|
|
|
|
{
|
|
|
|
|
splay_tree names_used;
|
|
|
|
|
splay_tree_node n;
|
|
|
|
|
|
|
|
|
|
/* Look to see if we ever used this name. */
|
|
|
|
|
names_used
|
|
|
|
|
= current_class_stack[current_class_depth - 1].names_used;
|
|
|
|
|
if (!names_used)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
n = splay_tree_lookup (names_used, (splay_tree_key) name);
|
|
|
|
|
if (n)
|
|
|
|
|
{
|
|
|
|
|
/* [basic.scope.class]
|
|
|
|
|
|
|
|
|
|
A name N used in a class S shall refer to the same declaration
|
|
|
|
|
in its context and when re-evaluated in the completed scope of
|
|
|
|
|
S. */
|
|
|
|
|
cp_error ("declaration of `%#D'", decl);
|
|
|
|
|
cp_error_at ("changes meaning of `%s' from `%+#D'",
|
|
|
|
|
IDENTIFIER_POINTER (DECL_NAME (decl)),
|
|
|
|
|
(tree) n->value);
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-01-11 03:28:01 +01:00
|
|
|
|
|
|
|
|
|
/* Dump the offsets of all the bases rooted at BINFO to stderr.
|
|
|
|
|
INDENT should be zero when called from the top level; it is
|
|
|
|
|
incremented recursively. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
dump_class_hierarchy (binfo, indent)
|
|
|
|
|
tree binfo;
|
|
|
|
|
int indent;
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
2000-01-23 19:58:54 +01:00
|
|
|
|
fprintf (stderr, "%*s0x%lx (%s) ", indent, "",
|
2000-01-20 09:12:26 +01:00
|
|
|
|
(unsigned long) binfo,
|
2000-01-23 19:58:54 +01:00
|
|
|
|
type_as_string (binfo, TS_PLAIN));
|
|
|
|
|
fprintf (stderr, HOST_WIDE_INT_PRINT_DEC,
|
|
|
|
|
TREE_INT_CST_LOW (BINFO_OFFSET (binfo)));
|
|
|
|
|
fprintf (stderr, " %s\n",
|
2000-01-12 21:56:15 +01:00
|
|
|
|
BINFO_PRIMARY_MARKED_P (binfo) ? "primary" : "");
|
2000-01-11 03:28:01 +01:00
|
|
|
|
|
|
|
|
|
for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i)
|
|
|
|
|
dump_class_hierarchy (BINFO_BASETYPE (binfo, i), indent + 2);
|
|
|
|
|
}
|