libabigail/tests/data/test-diff-dwarf/test37-union-v1.cc
Dodji Seketeli e7c920edbc Support union types
This patch makes Libabigail understand C and C++ union types.  It
defines a new class abigail::ir::union_decl to represent the
declaration of a union type.  It also defines a new type
abigail::comparison::union_diff to represent the changes between two
union types.  The patch then adds facilities to read union types from
DWARF and abixml and also to write union types into the abixml format.

As union types and class types have a lot in common, the patch tries
very hard to share code between the abigail::ir::class_decl and
abigail::ir::union_decl.  To do so, a new class
abigail::ir::class_or_union is created.  It's the base class for both
abigai::ir::class_decl and abigail::ir::union_decl.  Its data members
and methods represent the set of data and behaviour that are common to
classes and unions.  A lot of code and data that were initially in
abigail::ir::class_decl got moved into the new
abigail::ir::class_or_union class.

Similary, the patch creates a new class
abigail::comparison::class_or_union_diff that is a base class for both
the existing class abigail::comparison::class_diff and the newly
created class abigail::comparison::union_diff.  The new class
abigail::comparison::class_or_union_diff contains data and behaviour
that are common to both union_diff and class_diff and that were
previously in class_diff.

The rest of the patch is mostly adjustment so that code that was
supposed to work with class class_decl only can now work with class
class_or_union when it makes sense.  Similarly for class_diff and
class_or_union_diff.

The patch adds regression tests into the test suite and adjust many
existing tests involving binaries that contain union types; the
reference output of those tests now take union types into account.

	* include/abg-fwd.h (class_or_union, union_decl): Forward-declare
	new types.
	(is_class_or_union_type, is_union_type): Declare new functions.
	* include/abg-ir.h (method_type::class_type_): Make this be of
	class_or_union_wptr type.
	(method_type::method_type): Make the class_type parameter be of
	class_or_union_wptr type.
	(method_type::{g,s}et_class_type): Take or return a
	class_or_union_sptr.
	(member_base, method_decl, member_function_template)
	(member_class_template, member_base::hash)
	(member_function_template::hash, member_class_template::hash):
	Take these class types out of the class_decl scope.
	(is_method_decl): Adjust.
	(operator==, opertor!=): Adjust overloads for
	member_function_template_sptr and member_class_template_sptr.
	(class class_or_union): Declare new type.
	(class class_decl): Make this class inherit class_or_union class.
	(class_decl::{add_member_decl, insert_member_decl,
	remove_member_decl, set_size_in_bits, get_size_in_bits,
	get_alignment_in_bits, set_alignment_in_bits,
	get_is_declaration_only, set_is_declaration_only,
	set_definition_of_declaration, get_definition_of_declaration,
	get_earlier_declaration, set_earlier_declaration,
	insert_member_type, add_member_type, remove_member_type,
	get_member_type, find_member_type, add_data_member,
	get_data_members, find_data_member, get_non_static_data_members,
	add_member_function, get_member_functions, find_member_function,
	add_member_function_template, get_member_function_templates,
	add_member_class_template, get_member_class_templates): Move these
	to the parent class class_or_union.
	(copy_member_function, equals): Add overloads for class_or_union.
	(struct class_or_union::hash): Declare new type.
	(class union_decl): Declare new type.
	(equals, copy_member_function): New overloads for class union_decl
	type.
	(ir_node_visitor::visit): Add new overloads for union_decl* and
	class_or_union*.
	* src/abg-ir.cc (get_member_function_is_ctor)
	(set_member_function_is_ctor, get_member_function_is_dtor)
	(set_member_function_is_dtor, get_member_function_is_const)
	(set_member_function_is_const, get_member_function_vtable_offset)
	(set_member_function_vtable_offset)
	(get_member_function_is_virtual, set_member_function_is_virtual)
	(maybe_update_types_lookup_map, get_location)
	(get_method_type_name, is_at_global_scope, is_at_class_scope):
	Adjust.
	(is_class_or_union_type, is_union_type): Define new functions.
	(type_base::get_canonical_type_for, maybe_adjust_canonical_type)
	(method_type::method_type, method_type::set_class_type)
	(function_decl::get_pretty_representation)
	(function_decl::get_first_non_implicit_parm)
	(function_decl::clone): Adjust.
	(equals): Adjust the overload for function_type.
	(struct class_or_union::priv): Define new type.
	(class::priv::{declaration_, definition_of_declaration_,
	member_types_, data_members_, non_static_data_members_,
	member_functions_, mem_fns_map_, member_function_templates_,
	member_class_templates_, is_declaration_only_}): Move these data
	member into class_or_union::priv.
	(class_priv::{mark_as_being_compared, unmark_as_being_compared,
	comparison_started}): Moved these member functions to
	class_or_union::priv.
	(class_or_union::{class_or_union, traverse, ~class_or_union,
	add_member_decl, remove_member_decl, insert_member_type,
	add_member_type, get_size_in_bits, remove_member_type,
	get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits,
	get_is_declaration_only, set_is_declaration_only,
	set_definition_of_declaration, get_definition_of_declaration,
	get_earlier_declaration, set_earlier_declaration,
	get_member_types, find_member_type, add_data_member,
	get_data_member, find_data_member, add_member_function,
	get_member_functions, find_member_function,
	add_member_function_template, get_member_function_templates,
	add_member_class_template, get_member_class_templates,
	has_no_member, insert_member_decl, operator==}): Define new member
	functions.
	(class_decl::{add_member_decl, remove_member_decl,
	insert_member_type, add_member_type, get_size_in_bits,
	remove_member_type, get_alignment_in_bits, set_alignment_in_bits,
	set_size_in_bits, get_is_declaration_only,
	set_is_declaration_only, set_definition_of_declaration,
	get_earlier_declaration, set_earlier_declaration,
	get_member_types, find_member_type, add_data_member,
	get_data_member, find_data_member, add_member_function,
	get_member_functions, find_member_function,
	add_member_function_template, get_member_function_templates,
	add_member_class_template, get_member_class_templates): Move these
	member functions into class_or_union.
	(class_decl::{class_decl, get_definition_of_declaration,
	insert_member_decl, add_member_function, has_no_base_nor_member}):
	Adjust.
	(equals, copy_member_function): Define new overloads for
	class_or_union.
	(equals): Adjust the overload for class_decl.
	(method_decl::{method_decl, set_linkage_name, ~method_decl,
	get_type, set_scope}): Remove from the class_decl scope.
	(member_base::operator==, member_function_template::operator==):
	Likewise.
	(member_function_template::traverse)
	(member_class_template::operator==)
	(member_class_template::traverse): Likewise.
	(operator==, operator!=): Adjust the overlod for
	member_function_template_sptr.
	(is_method_decl, fixup_virtual_member_function)
	(set_member_is_static): Adjust.
	(virtual_member_function_less_than::operator()): Likewise.
	(union_decl::{union_decl, get_pretty_representation, operator==,
	traverse}): Define new member functions.
	(equals, copy_member_function): Define new overloads for
	union_decl.
	(hash_type_or_decl): Adjust.
	(ir_node_visitor::visit_{begin, end}): Adjust. Add new overloads
	for class_or_union* and union_decl*.
	* include/abg-comparison.h (changed_member_function_sptr)
	(string_member_function_sptr_map): Adjust these typedefs.
	(class class_or_union_diff): Declare new type.
	(class_diff): Adjust to make this inherit the new
	class_or_union_diff type.
	(class_diff::{get_priv, member_types_changes,
	data_members_changes, inserted_data_members, deleted_data_members,
	member_fn_tmpls_changes, member_fn_tmpls_changes,
	member_class_tmpls_changes}): These member functions got moved
	into -- and shared with -- class_or_union_diff class.
	(class union_diff): Declare new type.
	(typedef union_diff_sptr): New typedef.
	(compute_diff): New overload for union_diff
	(is_class_diff, is_union_diff): Declare new functions.
	* src/abg-comparison.cc (is_class_diff, is_union_diff): Define new
	functions.
	(compute_diff_for_types): Support union_decl.
	(represent):  Adjust.
	(represent_data_member): Do not show offset information for data
	members of unions as all union data members are at offset 0.
	(struct class_or_union_diff::priv): New type.
	(class_or_union_diff::priv::{member_type_has_changed,
	subtype_changed_dm, member_class_tmpl_has_changed,
	get_deleted_non_static_data_members_number,
	get_inserted_non_static_data_members_number,
	count_filtered_subtype_changed_dm, count_filtered_changed_dm,
	count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns,
	count_filtered_deleted_mem_fns}): Define new member functions.
	(class_or_union_diff::{class_or_union_diff, finish_diff_type,
	lookup_tables_empty, lookup_tables_empty,
	ensure_lookup_tables_populated, allocate_priv_data, get_priv,
	~class_or_union_diff, first_class_or_union, second_class_or_union,
	member_types_changes, member_types_changes, data_members_changes,
	inserted_data_members, deleted_data_members, member_fns_changes,
	changed_member_fns, member_fns_changes, inserted_member_fns,
	member_fn_tmpls_changes, member_fn_tmpls_changes,
	member_class_tmpls_changes, member_class_tmpls_changes,
	has_changes, has_local_changes, report, chain_into_hierarchy}):
	Define new member functions.
	(class_diff::priv::{member_types_changes_, data_members_changes,
	member_fn_tmpls_changes_, member_class_tmpls_changes_,
	deleted_member_types_, inserted_member_types_,
	changed_member_types_, sorted_changed_member_types_,
	deleted_data_members_, deleted_dm_by_offset_,
	inserted_data_members_, inserted_dm_by_offset_,
	subtype_changed_dm_, sorted_subtype_changed_dm_, changed_dm_,
	sorted_changed_dm_, deleted_member_functions_,
	inserted_member_functions_, changed_member_functions_,
	sorted_changed_member_functions_, deleted_member_class_tmpls_,
	inserted_member_class_tmpls_, changed_member_class_tmpls_,
	sorted_changed_member_class_tmpls_}): Move these data members into
	class_or_union_diff::priv.
	(class_diff::{clear_lookup_tables, lookup_tables_empty,
	ensure_lookup_tables_populate}): Adjust.
	(class_diff::allocate_priv_data): Define new function.
	(class_diff::priv::{count_filtered_changed_mem_fns,
	count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns,
	chain_into_hierarchy, class_diff}): Likewise.
	(class_diff::{member_types_changes, data_members_changes,
	inserted_data_members, deleted_data_members,
	member_fn_tmpls_changes, member_fn_tmpls_changes,
	member_class_tmpls_changes}): These are deleted as they got moved
	to class_or_union_diff.
	(class_diff::report): Adjust.
	(union_diff::{clear_lookup_tables, lookup_tables_empty,
	ensure_lookup_tables_populated, allocate_priv_data, union_diff,
	finish_diff_type, first_union_decl, second_union_decl,
	get_pretty_representation, report}): Define new functions.
	(compute_diff): Define an overload for union_decl_sptr.
	(function_decl_diff::report): Adjust.
	(corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars):
	Adjust.
	(corpus_diff::report): Adjust.
	* src/abg-hash.cc (member_base:#️⃣:operator)
	(member_function_template:#️⃣:operator)
	(member_class_template:#️⃣:operator): Move these out of the
	class_decl scope.
	(class_or_union:#️⃣:operator): Define new member function.
	(class_decl:#️⃣:operator): Adjust.
	(type_base::dynamic_hash::operator): Support hashing of
	union_decl.  Adjust.
	* src/abg-suppression.cc (type_suppression::suppresses_diff):
	Adjust.
	* src/abg-dwarf-reader.cc (typedef die_class_or_union_map_type):
	Define new typedef.
	(read_context::{die_wip_classes_map_,
	alternate_die_wip_classes_map_, type_unit_die_wip_classes_map_):
	Make these data member have type die_class_or_union_map_type.
	(read_context::{lookup_type_from_die_offset, die_wip_classes_map,
	is_wip_class_die_offset, resolve_declaration_only_classes}):
	Adjust.
	(finish_member_function_reading, build_class_type_and_add_to_ir)
	(build_function_type, build_function_decl, build_reference_type)
	(type_is_suppressed, build_function_decl)
	(maybe_canonicalize_type, maybe_set_member_type_access_specifier):
	Adjust.
	(build_union_type_and_add_to_ir): Define new static function.
	(build_ir_node_from_die): Support DW_TAG_union_type DIE tag.
	* src/abg-reader.cc (handle_element_node): Handle union_decl.
	(build_function_decl, build_function_decl_if_not_suppressed):
	Adjust.
	(build_union_decl_if_not_suppressed, build_union_decl)
	(handle_union_decl): Define new functions.
	(build_class_decl): Adjust.
	* src/abg-writer.cc (record_decl_only_type_as_emitted): Adjust.
	(write_decl): Adjust. Support writting union_decl type.
p	(write_class_decl_opening_tag, write_class_decl): Adjust.  Call
	the new write_class_or_union_is_declaration_only.
	(write_union_decl_opening_tag, write_union_decl): Define new
	static functions.
	(write_member_tpe): Support writting union decl.
	* tests/test-diff-dwarf.cc (in_out_specs): Add new tests for this
	union type support.
	* tests/data/test-diff-dwarf/libtest37-union-v0.so: New test input.
	* tests/data/test-diff-dwarf/libtest37-union-v1.so: Likewise.
	* tests/data/test-diff-dwarf/libtest38-union-v0.so: Likewise.
	* tests/data/test-diff-dwarf/libtest38-union-v1.so: Likewise.
	* tests/data/test-diff-dwarf/libtest39-union-v0.so: Likewise.
	* tests/data/test-diff-dwarf/libtest39-union-v1.so: Likewise.
	* tests/data/test-diff-dwarf/test37-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test38-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test39-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test37-union-v0.cc: Source code for
	new test input.
	* tests/data/test-diff-dwarf/test37-union-v1.cc: Likewise.
	* tests/data/test-diff-dwarf/test38-union-v0.cc: Likewise.
	* tests/data/test-diff-dwarf/test38-union-v1.cc: Likewise.
	* tests/data/test-diff-dwarf/test39-union-v0.cc: Likewise.
	* tests/data/test-diff-dwarf/test39-union-v1.cc: Likewise.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Update test reference.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-22 16:22:25 +01:00

21 lines
229 B
C++

// Compile this with:
// g++ -g -Wall -shared -o libtest37-union-v1.so test37-union-v1.cc
struct S
{
int S_member0;
int S_member1;
};
union some_union_type
{
int m0;
char m1;
S m2;
};
void
foo(some_union_type*)
{
}