This is the mail archive of the egcs-patches@egcs.cygnus.com mailing list for the EGCS project. See the EGCS home page for more information.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
This is the second release of the vtable thunks bug fix. It is functionally complete, with the following limitations: - There is no backwards compatibility with the current thunk in case of polymorphic vbases; I'm not sure whether I will provide one at in time for egcs 1.2. - The compiler currently emits vlists into all object files. This should work similar to the vtable export-import business, but I couldn't figure out how this really works. As it is, this patch can be used on the current egcs, and shows no regressions (tested in a slightly modified way on i586-pc-linux-gnu). If applied as-is, it changes the compiler behaviour only under -fnew-abi, even on Linux. An additional flag -fv1-thunks is provided to activate the current code; to test this patch, -fvtable-thunks -fno-v1-thunks is recommended. ABI issues (this eventually goes into gxxint.texi): For 'polymorphic virtual bases' (pvbases), an additional parameter __vlist is added after the in_chrg parameter to ctors and dtors; the parameter type is mangled as _Vlist. This parameter points to an array of vtables, which is consumed as initialization progresses. The ctors process it in forward direction, the dtors reverse. For each class with pvbases, a new vlist table is emitted, mangled as __vl.<class>. For the base classes, special vtables are emitted, which are named __vc.<path to base>_<path from base to vfield>. This is different from the vtable naming: it doesn't try to be smart about omitting path items during mangling, and therefore doesn't depend on the order in which vtables are created. ABI questions: 1) The callers of ctors and dtors always pass 0 as the vlist; the ctor/dtor then references the __vl variable in the if(__in_chrg) part. Alternatively, callers could be required to pass the real vlist pointer. Which is better? 2) If a dtor is called virtually, the caller is not guaranteed to pass any argument in place of the __vlist. Therefore, even storing into it is not safe. The dtor makes a local variable __vlist, and initializes it from __vlist1 (the parameter) if not in charge, or from the __vl variable otherwise. Is this safe on all platforms (i.e. invoking a function taking two parameters with only one argument, when the function then won't look at the second parameter) ? Alternatively, a wrapper must be put into the vtable in place of the dtor. 3) Is compatibility with the current thunks desirable? This would add wrappers for ctors and dtors which don't take the vlist parameter. They would always pass the __vl.class as vlist (even if not in charge), thus offering bug-compatibility with the current code. Those wrappers won't work for varargs constructors, in which case the compiler would be sorry. They will also copy all their arguments. Fortunately, non-POD types are passed by invisible reference, AFAIK. If the base class is not recompiled, the base constructor taking a vlist won't be available at link time. The compatibility code would try to generate a weak symbol, and generate code that tests the weak symbol, and calls the old ctor/dtor if the new one is not available. This approach would only work with weak symbols. Fortunately, it would work on Linux/ELF, where it would be primarily used. If you are still with me, I'd appreciate any comments on the approaches taken, and the implementation developed. I won't be looking at the code for a few days, which is why I'm releasing it now (release early, release often :-) Anybody interested in the backward compatibility: Please go ahead. Regards, Martin 1999-04-03 Martin von Löwis <loewis@informatik.hu-berlin.de> * class.c (prepare_ctor_vtable, finish_one_ctor_vtable, prepend_ctor_vfields_for_vbase, finish_ctor_vtables_for_vbases, finish_ctor_vtables_1, prepend_vbase_vfields, finish_ctor_vtables): New functions. (finish_struct_1): Call finish_ctor_vtables. * cp-tree.h (flag_v1_thunks): Declare. (TYPE_USES_PVBASES): New macro. (constructor_for_vbase_attr): Widen to two bits. (CONSTRUCTOR_FOR_VBASE, CONSTRUCTOR_FOR_PVBASE, DESTRUCTOR_FOR_PVBASE): New macros. (DECL_CONSTRUCTOR_FOR_VBASE_P): Adopt to new enumeration. (DECL_CONSTRUCTOR_FOR_VBASE): New macro. (DECL_CONSTRUCTOR_FOR_PVBASE_P, DECL_DESTRUCTOR_FOR_PVBASE_P): New macros. (vlist_identifier, vlist_type_node, vlist_zero_node): Declare. (VCTABLE_NAME, VLIST_NAME_FORMAT, VLIST_NAME, VLIST1_NAME, VLIST_TYPE_NAME): New macros. (LOOKUP_HAS_VLIST): New macro. (build_base_dtor_call, init_vlist): Declare. (build_destructor_name): Add int argument. * decl.c (vlist_identifier, vlist_type_node, vlist_zero_node): Define. (init_decl_processing): Initialize them. (grokdeclarator): Handle vlist argument. (copy_args_p): Likewise. (grok_ctor_properties): Don't try to skip initial int for templates. Skip vlist if available. (xref_basetypes): Set TYPE_USES_PVBASES. (finish_dtor, finish_ctor): New functions, moved out of ... (finish_function): ... here. * decl2.c (flag_v1_thunks): Define. (lang_f_options): Add v1-thunks. (lang_decode_option): Reset flag_v1_thunks for new-abi. (maybe_retrofit_in_chrg): Retrofit __vlist parameter. (grokclassfn): Pass pvbase flag into mangled name. * init.c (build_base_dtor_call): New function. (build_partial_cleanup_for): Call it. (pvbasecount, init_vlist, ): New functions. (emit_base_init): Process vlist argument. (expand_aggr_vbase_init_1): Likewise. (expand_aggr_vbase_init): Likewise. (expand_default_init): Likewise. (build_new_1): Pass null vlist argument. (build_delete): Likewise. Call build_base_dtor_call. * lang-options.h: New flag v1-thunks. * method.c (process_overload_item): Mangle _Vlist specially. (build_base_path, get_vlist_vtable_id): New functions. (build_destructor_name): Potentially mangle _Vlist into it. (do_build_copy_constructor): Skip vlist argument. (synthesize_method): Likewise. * pt.c (has_pvbases_p): New function. (instantiate_class_template): Call it. (tsubst_decl): Retrofit before mangling. Pass pvbase_p to destructor mangling. * search.c (expand_direct_vtbls_init_thunks): New function. (expand_indirect_vtbls_init_thunks): New function. (expand_indirect_vtbls_init): Call it. * call.c (add_function_candidate): Process vlist argument. (build_user_type_conversion_1): Add vlist argument. (convert_like): Likewise. (build_over_call): Likewise. (build_new_method_call): Likewise.