Commit Graph

255 Commits

Author SHA1 Message Date
Dodji Seketeli
2cf9a18e8c Better handle several anonymous types of the same kind
This is a follow-up patch for the commit:

   43d56de Handle several member anonymous types of the same kind

It allows support for severan anonymous types even when these are not
members of a class/unions.

The patch introduces the concept of a scoped name.  It's a qualified
name for a decl made of the name of the decl appended to the
*unqualified* name of its scope.  Unlike for qualified names, the
scoped name won't have a "__anonymous_*__" string in its name if its
directly containing scope is not anonymous; a qualified name might
still have that string in its name because the decl has a parent scope
(not necessarily its directly containing scope though) that is
anonymous.

The patch goes on to update the logic for comparison of decls that are
anonymous.  For a decl which direct scope is *NOT* anonymous, the
scoped name is what's used in the comparison.  Otherwise, only the
name of the decl is used.

The patch also updates how we detect changes in data members and
member types, in the comparison engine.  It now uses the names of the
data members, rather than their qualified name.  This is in the scope
of the current class/union anyway.  The improvement is that the fact
that the class/union itself is anonymous (even if its anonymous name
changes to another anonymous name) won't have any spurious impact on
the detection of name change of the members.

The patch considers the change of an anonymous decl name which
anonymous name changes to another anonymous name as being harmless.

The patch updates the logic of category propagation in the comparison
engine.  Although a public typedef to private underlying type needs to
stay public and thus not propagate the PRIVATE_TYPE_CATEGORY from its
child diff node to himself, it still needs to suppress the changes to
the private underlying diff node that were suppressed (because of the
private-ness), unless that typedef has local changes.

	* include/abg-ir.h (decl_base::get_scoped_name): Declare new
	member function.
	(scope_decl::get_num_anonymous_member_{classes, unions, enums}):
	Declare new virtual member functions.
	(class_decl::get_num_anonymous_member_{classes, unions, enums}):
	Adjust to make these virtual.  It's not necessary but I feel
	redundancy is a kind of self-documentation here.
	* src/abg-comp-filter.cc (has_harmless_name_change): Consider
	anonymous name changes as harmless.
	* src/abg-comparison.cc
	(class_or_union_diff::ensure_lookup_tables_populated): Consider
	the names of the members rather than their qualified names.
	(suppression_categorization_visitor::visit_end): Suppress the
	changes to the private underlying diff node that were suppressed
	because of the private-ness, unless that typedef has local
	changes.
	* src/abg-dwarf-reader.cc (build_enum_type)
	(add_or_update_class_type, add_or_update_union_type): Handle
	anonymous types in namespaces as well, not just in class/unions.
	* src/abg-ir.cc (decl_base::priv::scoped_name_): Define new data
	member.
	(decl_base::get_scoped_name): Define new member function.
	(equals): For the decl_base overload, use scoped name in the
	comparison, unless the decl belongs to an anonymous type.  For the
	class_or_union_diff, only consider scoped_name during comparison.
	Avoid name comparison between anonymous types.
	(scope_decl::get_num_anonymous_member_{classes, unions, enums}):
	Define new member functions.
	(types_have_similar_structure): Do not compare names between
	anonymous types.
	(qualified_name_setter::do_update): Update scoped names too.
	* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.
	* tests/data/test-annotate/libtest23.so.abi: Likewise.
	* tests/data/test-annotate/test13-pr18894.so.abi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-diff-dwarf/test43-PR22913-report-0.txt:
	Likewise.
	* tests/data/test-diff-dwarf/test46-rust-report-0.txt: Likewise.
	* 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-diff-filter/test30-pr18904-rvalueref-report2.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test33-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test44-anonymous-data-member-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-1.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt:
	Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest23.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/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>
2019-05-09 15:19:05 +02:00
Dodji Seketeli
43d56de89b Handle several member anonymous types of the same kind
When there are several anonymous types (e.g, anonymous classes, unions
or enums) in a given class or union, libabigail's internals do
struggle.

An anonymous class, for instance, is named __anonymous_struct__.  When
there are more than one of these inside a given class, then we can't
name and look them up, because they all have the same name.

Incidentally, when add_or_update_class_type completes a class type
that was initially constructed before, it fails to determine that an
anonymous member type of that class was already present in that
context.  It thus wrongly duplicates anonymous structs/unions/enums in
there and that leads to spurious textual (abixml) representation
differences later, where duplicated anonymous member types would
appear intermittently, depending on the order in which the class was
built.

This patch addresses this general issue by naming anonymous member
types in a way that allows several of them to exist. That is, if there
are two anonymous structs in a class, they are going to be named
__anonymous_struct__ and __anonymous_struct__1.  We do follow a
similar scheme for anonymous unions and enums. This is handled by the
DWARF reader that builds the internal representation.

While looking at this issue, I also fixed a tangent bug; some DWARF
emitters wrongly *define* types in the scope of a
DW_TAG_subroutine_type or DW_TAG_array_type.  We handle that by
actually defining those types in the scope of that subroutine or
array.  But then it appears that if that scope itself a class and if
the type defined is an anonymous type, then putting that anonymous
type in the class scope might interfere with the *naming* of the
existing legit anonymous types of that scope.  I decided to put those
anonymous types in the containing namespace instead.  We'll see how
that goes in real time use.

The patch also updates lots of existing tests and adds a new one.

	* include/abg-ir.h
	(class_or_union::get_num_anonymous_member_{classes, unions,
	enums}): Declare new member functions.
	* src/abg-dwarf-reader.cc (get_internal_anonynous_die_base_name)
	(build_internal_anonymous_die_name)
	(get_internal_anonymous_die_name, is_anonymous_type_die): Define
	new static functions.
	(die_qualified_type_name): Use the new
	get_internal_anonymous_die_name.
	(get_scope_for_die): Fix this to put anonymous types that were
	wrongly emitted into the scope of DW_TAG_subroutine_type or
	DW_TAG_array_type by buggy DWARF emitters into the enclosing
	namespace, rather than into the enclosing class/union.
	(build_enum_type): Take the scope of the enum to have a chance to
	properly name potential anonymous enums.
	(lookup_class_typedef_or_enum_type_from_corpus): Take an anonymous
	member type index for when the DIE we are lookup up represents an
	anonymous type.  Support proper building of the internal anonymous
	name of the anonymous type we are lookup up.
	(add_or_update_class_type): Use the new
	get_internal_anonynous_die_base_name and
	build_internal_anonymous_die_name functions.  Support making sure
	that the anonymous member type we are adding to the class wasn't
	already there, especially for cases where we are updating a class
	type.
	(add_or_update_union_type): Use the new
	get_internal_anonynous_die_base_name and
	build_internal_anonymous_die_name functions.
	(build_ir_node_from_die): Adjust the use of build_enum_type to
	pass it the scope of the enum type we are building.
	* src/abg-ir.cc	(lookup_union_type): Add a new overload.
	(lookup_class_or_typedef_type): Use the new overload of
	lookup_union_type above to support looking up union types too.
	(class_or_union::get_num_anonymous_member_{classes, unions,
	enums}): Define new member functions.
	* src/abg-reporter-priv.cc (represent): Detect when anonymous
	types of anonymous data members have their internal names change,
	probably because anonymous member types were inserted in the scope.
	* tests/data/Makefile.am: Add the new test-anonymous-members-0.*
	test input files to the source distribution.
	* tests/data/test-annotate/test-anonymous-members-0.cc: New test
	input file.
	* tests/data/test-annotate/test-anonymous-members-0.o: Likewise.
	* tests/data/test-annotate/test-anonymous-members-0.o.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Adjust.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt:
	Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.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/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/test-annotate.cc (int_out_specs): Add the new test inputs
	to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-05-07 14:31:16 +02:00
Dodji Seketeli
286cadf841 Bug 24430 - Fold away const for array types
In C and C++ the qualifiers of a qualified array type apply to the
element type of said array.

In this particular problem report, GCC and Clang emit DWARF that
represent the qualifiers either on the array type, or on the element
type.  Quoting the test of the bug:

    Given the following example:

	struct test {
	  const char asdf[4];
	};

	void func(struct test arg) {}

    abidiff says:

     1 function with some indirect sub-type change:

       [C]'function void func(test)' at test.c:5:1 has some indirect sub-type
     changes:
	 parameter 1 of type 'struct test' has sub-type changes:
	   type size hasn't changed
	   1 data member change:
	    type of 'const char test::asdf[4]' changed:
	      entity changed from 'const char[4]' to 'const char[4] const'

This is because GCC represents the array as const array of const
signed char, whereas clang represents it as an array of const signed
char.

In this patch, libabigail's DWARF reader detects qualified array types
and appropriately qualifies the array element type, instead of
qualifying the array type.  The patch accordingly adjusts the various
regression tests and adds a new test which comes from the problem
report.

	* include/abg-fwd.h (is_array_of_qualified_element): Declare 2
	overloads of this function.
	(re_canonicalize): Declare a new function.
	* include/abg-ir.h (class {decl_base, type_base}): Declare
	re_canonicalize as a friend of these classes.
	* src/abg-dwarf-reader.cc (maybe_strip_qualification): Detect
	qualified array types and appropriately qualifies the array
	element type, instead of qualifying the array type itself.
	Re-canonicalize the resulting type if necessary.
	* src/abg-ir.cc (is_array_of_qualified_element): Define 2
	overloads of this function.
	(re_canonicalize): Define new function.
	* tests/data/Makefile.am: The two new test binary input files
	PR24430-fold-qualified-array-clang and
	PR24430-fold-qualified-array-gcc to source distribution, as well
	as the expected reference output.
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-diff-filter/PR24430-fold-qualified-array-clang:
	New binary test input coming from the bug report.
	* tests/data/test-diff-filter/PR24430-fold-qualified-array-gcc:
	Likewise.
	* tests/data/test-diff-filter/PR24430-fold-qualified-array-report-0.txt:
	Expected reference abi difference.
	* tests/data/test-diff-filter/test33-report-0.txt: Adjust.
	* tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.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/test-diff-filter.cc: Add the new binary test input to this
	test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-10 13:02:36 +02:00
Dodji Seketeli
f85dd789c2 Add missing assignment operators
This was detected by compiling with GCC 9.0.1

	* include/abg-interned-str.h (interned_string::operator=): Define
	assignment operator.
	* include/abg-ir.h
	({location, enum_type_decl::enumerator}::operator=): Declare
	assignment operator.
	* src/abg-ir.cc (enum_type_decl::enumerator::operator=): Define
	assignment operator.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-03-27 15:24:21 +01:00
Dodji Seketeli
782c3d8c42 Add ir::{lookup_data_member, get_function_parameter}
While looking at something else, I figured it's useful, for debugging
purposes, to be able to lookup a given data member of a union/class by
name, as well as a function parameter by index.

This patch adds both.

	* include/abg-ir.h (lookup_data_member, get_function_parameter):
	Declare new functions.
	* src/abg-ir.cc (lookup_data_member, get_function_parameter):
	Define them.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-03-21 18:17:31 +01:00
Dodji Seketeli
0036d0448e Better detection of void* to something* change
Whenever a void* pointer changes to a T* pointer, we already consider
that change to be ABI-compatible.  The issue though is that we don't
detect the case of foo* changing into T* where foo is typedef void
foo.  This patch fixes that.

	* include/abg-ir.h (is_void_type): Add a new overload that takes
	type_base*.
	* src/abg-ir.cc (is_void_type): Define the new overload that takes
	type_base*.
	(is_void_pointer_type): Look through typedefs in
	the pointed-to type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-03-21 18:13:54 +01:00
Dodji Seketeli
84ec784743 Bug 24157 - Wrong support of Ada ranges
In this problem report, the DWARF reader comes across an ADA subrange
which lower bound is a negative signed integer.  The problem is that
the internal representation of libabigail expects the bounds of the
subrange to be unsigned integer.  This incompatibility leads to an
assertion failure.

Further down the road I realized that the function
types_have_similar_structure doesn't support subrange types.

This patch thus introduces a new
array_type_def::subrange_type::bound_value class that captures the
signedness of the bound value.  This allows the internal
representation to keep the sign information of the bound value, and
yet be able to treat the bound value as either a signed or unsigned
value depending on the contexts.

The patch also extends the function types_have_similar_structure to
make it support subrange types.

	* include/abg-ir.h (array_type_def::subrange_type::bound_value):
	Define new class.
	(array_type_def::subrange_type::subrange_type): Adjust to use the
	new bound_value type for bound values.
	(array_type_def::subrange_type::{get_upper_bound, get_lower_bound,
	set_upper_bound, set_lower_bound}): Return or take int64_t rather
	than size_t.
	(array_type_def::subrange_type::get_length): Return uint64_t
	rather than size_t.
	* src/abg-dwarf-reader.cc (die_signed_constant_attribute)
	(die_constant_attribute, die_attribute_has_form)
	(die_attribute_is_signed, die_attribute_is_unsigned)
	(die_attribute_has_no_signedness): Define new static functions.
	(get_default_array_lower_bound): Return uint64_t rather than int.
	(build_subrange_type): Use the new
	array_type_def::subrange_type::bound_value type for bound values.
	Use the new die_constant_attribute function, rather than
	die_unsigned_constant_attribute to fecth the bound values.
	* src/abg-ir.cc
	(array_type_def::subrange_type::bound_value::{bound_value,
	get_signedness, set_signedness, get_signed_value,
	get_unsigned_value, set_unsigned, set_signed}): Define new member
	functions.
	(array_type_def::subrange_type::priv::{lower_bound_,
	upper_bound}): Use the new class bound_value.
	(array_type_def::subrange_type::priv::priv): Adjust to use the new
	bound_value class to hold bound values.
	(array_type_def::subrange_type::subrange_type): Likewise.
	(array_type_def::subrange_type::{get_upper_bound, get_lower_bound,
	set_upper_bound, set_lower_bound}): Return or take int64_t rather
	than size_t.
	(array_type_def::subrange_type::get_length): Return uint64_t
	rather than size_t.
	(types_have_similar_structure): Handle array_type_def::subrange_type
	* src/abg-reader.cc (build_subrange_type): Use the new
	array_type_def::subrange_type::bound_value to hold bound values.
	* tests/data/test-diff-pkg/GtkAda-debuginfo-2.24.2-29.fc29.x86_64.rpm:
	New binary RPM as test input.
	* tests/data/test-diff-pkg/GtkAda-debuginfo-2.24.2-30.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/GtkAda-devel-2.24.2-29.fc29.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/GtkAda-devel-2.24.2-30.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64--2.24.2-30.fc30.x86_64-report-0.txt:
	New expected test output.
	* tests/data/test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64.rpm:
	New binary RPM as test input.
	* tests/data/test-diff-pkg/GtkAda-gl-2.24.2-30.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/GtkAda-gl-debuginfo-2.24.2-29.fc29.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/GtkAda-gl-debuginfo-2.24.2-30.fc30.x86_64.rpm:
	Likewise.
	* tests/data/Makefile.am: Add the new test material above to source
	distribution.
	* tests/test-diff-pkg.cc (in_out_specs): Add the new input testing
	RPMs in here.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-02-07 11:21:34 +01:00
Dodji Seketeli
7d639aef70 Bug 20175 - Classify CV qual changes in variable type as harmless
When the type of a variable changes and that change is only a CV qual
change, we want libabigail to automatically classify that change as
being harmless.

This patch thus introduces a new VAR_TYPE_CV_CHANGE_CATEGORY change
category (enumerator of the abigail::comparison::diff_category enum)
for this kind of changes and classifies that category as being
harmless.

The patch then detects diff nodes that carry CV qualifiers change on
variable types and flags them as belonging to the new
VAR_TYPE_CV_CHANGE_CATEGORY.

	* include/abg-comparison.h (VAR_TYPE_CV_CHANGE_CATEGORY): Add new
	enumerator to diff_category enum.
	(EVERYTHING_CATEGORY): Update this enumerator.
	* src/abg-comp-filter.cc (type_diff_has_cv_qual_change_only):
	Support array diff nodes carrying a cv qual change on the element
	type.
	(has_var_type_cv_qual_change): Define new static function.
	(categorize_harmless_diff_node): Use the new
	has_var_type_cv_qual_change to categorize variable diff node with
	cv qual change on its type as harmless.
	* src/abg-comparison.cc
	(get_default_harmless_categories_bitmap): Update this.
	(operator<<(ostream& o, diff_category c)): Likewise.
	* include/abg-ir.h (equals_modulo_cv_qualifier): Declare new ...
	* src/abg-ir.cc (equals_modulo_cv_qualifier): ... function.
	* tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt:
	Update expected test output.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise.
	* tests/data/Makefile.am: Add the new test material below to
	source distribution.
	* tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt:
	New expecte test output.
	* tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64.rpm: New
	test input.
	* tests/data/test-diff-pkg/nss-3.24.0-1.0.fc23.x86_64.rpm: Likewise.
	* tests/data/test-diff-pkg/nss-debuginfo-3.23.0-1.0.fc23.x86_64.rpm: Likewise.
	* tests/data/test-diff-pkg/nss-debuginfo-3.24.0-1.0.fc23.x86_64.rpm: Likewise.
	* tests/data/test-diff-pkg/nss-devel-3.23.0-1.0.fc23.x86_64.rpm: Likewise.
	* tests/data/test-diff-pkg/nss-devel-3.24.0-1.0.fc23.x86_64.rpm: Likewise.
	* tests/test-diff-pkg.cc (in_out_specs): Add the test input above
	to the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-01-25 11:54:29 +01:00
Mark Wielaard
2366dca947 Conditionalize the use of DW_LANG_C_plus_plus_03 and DW_LANG_Rust
Older elfutils (pre-0.170) don't define these constants in dwarf.h so
don't use them in that case.

	* include/abg-ir.h (LANG_C_plus_plus_03): Add this new language
	enum to "enum translation_unit::language".
	* src/abg-dwarf-reader.cc (dwarf_language_to_tu_language): Do not
	use DW_LANG_Rust or DW_LANG_C_plus_plus_03 if these are not
	defined.
	(get_default_array_lower_bound): Handle the new
	translation_unit::LANG_C_plus_plus_03 enumerator.

Signed-off-by: Mark Wielaard <mark@klomp.org>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-01-17 14:26:58 +01:00
Dodji Seketeli
70f7c63a76 Add (very) basic support for Rust
I tested this on the binaries generated from this project:
https://gitlab.gnome.org/federico/abi-rust and I got this:

    $ tools/abidiff libone.so libtwo.so
    Functions changes summary: 0 Removed, 1 Changed, 0 Added function
    Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

    1 function with some indirect sub-type change:

      [C]'function one::Foo one::foo(u32)' at lib.rs:8:1 has some indirect sub-type changes:
	'function one::Foo one::foo(u32) {foo}' now becomes 'function two::Foo two::foo(u32, u32) {foo}'
	return type changed:
	  type name changed from 'one::Foo' to 'two::Foo'
	  type size changed from 32 to 64 (in bits)
	  1 data member insertion:
	    'u32 two::Foo::b', at offset 32 (in bits)
	  no data member change (1 filtered);
	parameter 2 of type 'u32' was added

	* include/abg-ir.h (LANG_Rust): Add this new enumerator to the
	"enum language" enum.
	* src/abg-dwarf-reader.cc (dwarf_language_to_tu_language): Handle
	the Rust language.
	(get_default_array_lower_bound): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-01-17 09:58:36 +01:00
Dodji Seketeli
047342467c Update copyright for 2019
* include/abg-comp-filter.h: Update copyright for 2019
	* include/abg-comparison.h: Update copyright for 2019
	* include/abg-config.h: Update copyright for 2019
	* include/abg-corpus.h: Update copyright for 2019
	* include/abg-diff-utils.h: Update copyright for 2019
	* include/abg-dwarf-reader.h: Update copyright for 2019
	* include/abg-fwd.h: Update copyright for 2019
	* include/abg-hash.h: Update copyright for 2019
	* include/abg-ini.h: Update copyright for 2019
	* include/abg-interned-str.h: Update copyright for 2019
	* include/abg-ir.h: Update copyright for 2019
	* include/abg-libxml-utils.h: Update copyright for 2019
	* include/abg-libzip-utils.h: Update copyright for 2019
	* include/abg-reader.h: Update copyright for 2019
	* include/abg-reporter.h: Update copyright for 2019
	* include/abg-sptr-utils.h: Update copyright for 2019
	* include/abg-suppression.h: Update copyright for 2019
	* include/abg-tools-utils.h: Update copyright for 2019
	* include/abg-traverse.h: Update copyright for 2019
	* include/abg-viz-common.h: Update copyright for 2019
	* include/abg-viz-dot.h: Update copyright for 2019
	* include/abg-viz-svg.h: Update copyright for 2019
	* include/abg-workers.h: Update copyright for 2019
	* include/abg-writer.h: Update copyright for 2019
	* src/abg-comp-filter.cc: Update copyright for 2019
	* src/abg-comparison-priv.h: Update copyright for 2019
	* src/abg-comparison.cc: Update copyright for 2019
	* src/abg-config.cc: Update copyright for 2019
	* src/abg-corpus-priv.h: Update copyright for 2019
	* src/abg-corpus.cc: Update copyright for 2019
	* src/abg-default-reporter.cc: Update copyright for 2019
	* src/abg-diff-utils.cc: Update copyright for 2019
	* src/abg-dwarf-reader.cc: Update copyright for 2019
	* src/abg-hash.cc: Update copyright for 2019
	* src/abg-ini.cc: Update copyright for 2019
	* src/abg-internal.h: Update copyright for 2019
	* src/abg-ir-priv.h: Update copyright for 2019
	* src/abg-ir.cc: Update copyright for 2019
	* src/abg-leaf-reporter.cc: Update copyright for 2019
	* src/abg-libxml-utils.cc: Update copyright for 2019
	* src/abg-libzip-utils.cc: Update copyright for 2019
	* src/abg-reader.cc: Update copyright for 2019
	* src/abg-reporter-priv.cc: Update copyright for 2019
	* src/abg-reporter-priv.h: Update copyright for 2019
	* src/abg-sptr-utils.cc: Update copyright for 2019
	* src/abg-suppression-priv.h: Update copyright for 2019
	* src/abg-suppression.cc: Update copyright for 2019
	* src/abg-tools-utils.cc: Update copyright for 2019
	* src/abg-traverse.cc: Update copyright for 2019
	* src/abg-viz-common.cc: Update copyright for 2019
	* src/abg-viz-dot.cc: Update copyright for 2019
	* src/abg-viz-svg.cc: Update copyright for 2019
	* src/abg-workers.cc: Update copyright for 2019
	* src/abg-writer.cc: Update copyright for 2019
	* tests/print-diff-tree.cc: Update copyright for 2019
	* tests/test-abicompat.cc: Update copyright for 2019
	* tests/test-abidiff-exit.cc: Update copyright for 2019
	* tests/test-abidiff.cc: Update copyright for 2019
	* tests/test-alt-dwarf-file.cc: Update copyright for 2019
	* tests/test-core-diff.cc: Update copyright for 2019
	* tests/test-diff-dwarf-abixml.cc: Update copyright for 2019
	* tests/test-diff-dwarf.cc: Update copyright for 2019
	* tests/test-diff-filter.cc: Update copyright for 2019
	* tests/test-diff-pkg.cc: Update copyright for 2019
	* tests/test-diff-suppr.cc: Update copyright for 2019
	* tests/test-diff2.cc: Update copyright for 2019
	* tests/test-ini.cc: Update copyright for 2019
	* tests/test-ir-walker.cc: Update copyright for 2019
	* tests/test-lookup-syms.cc: Update copyright for 2019
	* tests/test-read-dwarf.cc: Update copyright for 2019
	* tests/test-read-write.cc: Update copyright for 2019
	* tests/test-types-stability.cc: Update copyright for 2019
	* tests/test-utils.cc: Update copyright for 2019
	* tests/test-utils.h: Update copyright for 2019
	* tests/test-write-read-archive.cc: Update copyright for 2019
	* tools/abiar.cc: Update copyright for 2019
	* tools/abicompat.cc: Update copyright for 2019
	* tools/abidiff.cc: Update copyright for 2019
	* tools/abidw.cc: Update copyright for 2019
	* tools/abilint.cc: Update copyright for 2019
	* tools/abipkgdiff.cc: Update copyright for 2019
	* tools/abisym.cc: Update copyright for 2019
	* tools/binilint.cc: Update copyright for 2019
	* tools/kmidiff.cc: Update copyright for 2019
	* update-copyright.sh: Update new year to 2019

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-01-07 14:54:47 +01:00
Dodji Seketeli
18e4697e05 Better support array with unknown upper bound
It can happen that arrays are described in DWARF with an unknown upper
bound.  In those cases, if the array is the type of a global variable,
the ELF object corresponding to that global variable should have a
size.  It's that ELF object size that should be taken into account
when comparing versions of that global variable and its type.

This patch fixes issues in the detection and representation of array
subranges with unknown size so that we behave like presented above.

	* include/abg-comparison.h
	(BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY): A new enumerator in the
	diff_category enum.
	(EVERYTHING_CATEGORY): Adjust.
	* src/abg-comparison.cc (get_default_harmless_categories_bitmap):
	Adjust.
	(operator<<(ostream& o, diff_category)): Likewise.
	* include/abg-ir.h (array_type_def::subrange_type::is_infinite):
	Declare new member function.
	* src/abg-ir.cc (array_type_def::subrange_type::priv::infinite_):
	New data member.
	(array_type_def::subrange_type::priv::priv): Initialize it.
	(array_type_def::subrange_type::get_length): Better support
	unknown sized subrange.
	(array_type_def::subrange_type::is_infinite): Define new member
	function.
	* src/abg-comp-filter.cc (has_benign_infinite_array_change):
	Define new static function.
	(categorize_harmless_diff_node): Use the new
	has_benign_infinite_array_change above.
	* src/abg-dwarf-reader.cc (build_subrange_type): Better recognize a
	subrange type with unknown upper bound.  Represent that with the
	new array_type_def::subrange_type::is_infinite member property.
	* src/abg-reader.cc (build_subrange_type): Likewise.
	* tests/data/test-abidiff/test-PR18166-libtirpc.so.abi: Adjust.
	* tests/data/test-annotate/libtest23.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-annotate/test7.so.abi: 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/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.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>
2018-10-16 18:00:22 +02:00
Dodji Seketeli
af73844b97 Add option to avoid walking abigail::ir nodes twice
When the ir_traversable_base::traverse() walks the IR graph, it
happens that it can visit a type node that was already visited before.
For instance, it visits the 'struct S' once and later, as part of its
visit of struct S*, it can visit struct S again.

There are use cases where we want the walker to avoid visiting a given
type node again.  This patch adds the option to do so.

Basically the ir_node_visitor class can now be configured to tell the
walker to avoid re-visiting a node.

The test-ir-walker.cc example is amended to avoid re-visiting type nodes
as well.

	* include/abg-ir.h (struct ir_node_visitor): Make this be a class.
	Add a private data member to it, following the 'pimpl' idiom.
	(ir_node_visitor::{allow_visiting_already_visited_type_node,
	mark_type_node_as_visited, forget_visited_type_nodes,
	type_node_has_been_visited}): Declare new member functions.
	* src/abg-ir.cc ({type_base, type_decl, scope_type_decl,
	qualified_type_decl, pointer_type_def, reference_type_def,
	array_type_def, enum_type_decl, typedef_decl, class_or_union,
	class_decl, union_decl}::traverse): Avoid re-visiting the type
	node if the visitor was configured as such.
	(struct ir_node_visitor::priv): Define new struct.
	(ir_node_visitor::{allow_visiting_already_visited_type_node,
	mark_type_node_as_visited, forget_visited_type_nodes,
	type_node_has_been_visited}): Define new member functions.
	* tests/test-ir-walker.cc
	(name_printing_visitor::name_printing_visitor): Avoid visiting a
	type node twice.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-09-03 13:32:06 +02:00
Dodji Seketeli
11c2437a19 Better detect when diff nodes only carry local type changes
For some fine grain redundancy filtering, we need to know when a diff
node carries *only* a basic type change.  This is because basic type
changes should not be marked as redundant; we want to see all of them
-- unlike for class or union (user defined) type changes.

And so to know if a diff node carries only a basic type change, we
need to know if a diff node only carries a local type change.  If it
carries only a type change, we can safely just look at that type
change and see if it's a basic type change or not.

So, we then need to know what kind of local changes a diff node
carries: type change or non-type change.  That way, we can analyze the
local changes a node carries and infer that it only carries a local
type change or if it also carries a non-type change.

This patch thus changes the diff::has_local_changes() pure virtual member
function to make it return the enum change_kind bitmask, which
describes the different kinds of local changes the diff node has.

Note that two new bit values were added to that enum:
LOCAL_TYPE_CHANGE_KIND and LOCAL_NON_TYPE_CHANGE_KIND.  The first one
says that the diff node carries a local type change, while the second
one says that the diff node carries a local non-type change kind.

The various implementations of that interface are thus amended to make
them return the right bitmask.  To do this, the patch updates the
various 'equals' overloads to make them return the proper enum
change_kind bitmap with the LOCAL_TYPE_CHANGE_KIND and
LOCAL_NON_TYPE_CHANGE_KIND set, if need be.

	* include/abg-comparison.h ({diff, type_diff_base, decl_diff_base,
	distinct_diff, var_diff, pointer_diff, reference_diff, array_diff,
	qualified_type, enum_diff, class_or_union_diff, class_diff,
	base_diff, scope_diff, fn_parm_diff, function_type_diff,
	function_decl_diff, typedef_diff,
	translation_unit_diff}::has_local_changes): Return an enum
	change_kind, rather than just a bool.
	(is_diff_of_basic_type): Declare an overload that takes a boolean
	flag.
	(is_qualified_type_diff, peel_pointer_diff, peel_reference_diff)
	(peel_qualified_type, peel_pointer_or_qualified_type): Declare new
	functions
	* include/abg-fwd.h (peel_qualified_type):
	* include/abg-ir.h (enum change_kind::{LOCAL_TYPE_CHANGE_KIND,
	LOCAL_NON_TYPE_CHANGE_KIND, ALL_LOCAL_CHANGES_MASK}): Add these
	three new enumerators.
	* src/abg-comparison.cc ({distinct_diff, var_diff, pointer_diff,
	array_diff, reference_diff, qualified_type_diff, enum_diff,
	class_or_union_diff, class_diff, base_diff, scope_diff,
	fn_parm_diff, function_type_diff, function_decl_diff,
	type_decl_diff, typedef_diff,
	translation_unit_diff}::has_local_changes): Adjust to return an
	enum change_kind, rather than just a bool.
	(has_local_type_change_only): Define new functions.
	(has_basic_type_change_only): Use the new
	has_local_type_change_only function and the new overload for
	is_diff_of_basic_type.
	(is_diff_of_basic_type): Define an overload that takes a boolean
	flag.
	(is_qualified_type_diff, peel_pointer_diff, peel_reference_diff)
	(peel_qualified_type, peel_pointer_or_qualified_type): Define new
	functions.
	* src/abg-ir.cc (equals): In the overloads for decl_base,
	scope_decl, type_base, qualified_type_diff, pointer_type_def,
	reference_type_def, array_type_def, enum_type_decl, typedef_decl,
	var_decl, function_type, function_decl, function_decl::parameter,
	class_or_union, class_decl::base_spec and class_decl, properly set
	the new abigail::ir::{LOCAL_CHANGE_KIND,
	LOCAL_NON_TYPE_CHANGE_KIND, LOCAL_TYPE_CHANGE_KIND} bits.
	(types_have_similar_structure): Peel qualified types and typedefs
	off, first thing.
	(peel_qualified_or_typedef_type): Define new function.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt:
	Adjust.
	* tests/data/test-diff-filter/libtest45-basic-type-change-report-{0,1}.txt:
	New reference test reports.
	* tests/data/test-diff-filter/libtest45-basic-type-change-v{0,1}.so:
	New input test binaries.
	* tests/data/test-diff-filter/test45-basic-type-change-v{0,1}.cc:
	Source code of the input test binaries above.
	* tests/data/Makefile.am: Add the new test file above to source
	distribution.
	* tests/test-diff-filter.cc: Add the test input above to the test
	harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-24 16:04:44 +02:00
Dodji Seketeli
ef7198310d Initial support of anonymous data members
An anonymous data member is a data member of a struct or a union which
has no name.  The type of such data member is either a struct or a
union.  For instance:

    struct foo {
      int a;
      struct { // <-- this is an anonymous data member
	char a;
	char b;
      };
      int c;
    };

In DWARF (as emitted by GCC at least), an anonymous data member is
represented as a data member with an empty name.  Libabigail sees it
just fine, but then when representing *changes* to that kind of data
member, it needs special treatment, otherwise users cannot make sense
of the reports.

This patch adds initial support to represent changes to anonymous data
members.

	* include/abg-comparison.h (is_class_or_union_diff)
	(is_anonymous_class_or_union_diff): Declare new functions.
	* include/abg-fwd.h (is_class_type): Declare new overload for
	type_or_decl_base&.
	(is_data_member): Declare new overload for decl_base*.
	(is_anonymous_data_member)
	(anonymous_data_member_to_class_or_union)
	(get_class_or_union_flat_representation)
	(data_member_has_anonymous_type): Declare new functions.
	(is_at_class_scope): Return the class or union scope.
	* include/abg-ir.h (var_decl::get_qualified_name): New virtual
	data member which overloads decl_base::get_qualified_name.
	* src/abg-comparison.cc (is_class_or_union_diff)
	(is_anonymous_class_or_union_diff): Define new functions
	(leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous
	class or union diff nodes as diff nodes.
	* src/abg-ir.cc (is_data_member): Define new overload for
	decl_base*.
	(is_class_type, is_union_type): Define new overload for type_or_decl_base&.
	(is_anonymous_data_member)
	(anonymous_data_member_to_class_or_union)
	(get_class_or_union_flat_representation)
	(data_member_has_anonymous_type): Define new function overloads.
	(var_decl::get_qualified_name): Define new virtual member
	function.
	(is_at_class_scope): Return the class or union scope.
	(var_decl::get_pretty_representation): Support anonymous data
	members.
	(equals): In the overload for class_or_union_diff, mark data
	member textual representation changes as local changes.
	* src/abg-reporter-priv.cc (represent): In the overload for
	var_diff, support changes to anonymous data members.
	* src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted
	-- by offset -- data member changes before the ones that are
	sorted by other things.
	* tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so:
	New binary test input
	* tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt:
	New reference test outputs.
	* tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c:
	Source code of the new binary test output above.
	* tests/data/Makefile.am: Add the new test files above to the
	source distribution.
	* tests/data/test-annotate/libtest23.so.abi: Adjust test reference
	output.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test13-pr18894.so.abi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise.
	* 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-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise.
	* tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise.
	* tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-14 06:41:38 +02:00
Dodji Seketeli
c998a818fc Fix meaning of "harmless name change" to avoid overfiltering
Whenever a typedef or enum changes its name, we seem to wrongly
qualify that chane as being "harmless" and thus, we tend to filter the
change out, by default.  We do this even when e.g, the enum change
also contain other changes that might be meaningful to show.

This commit fixes the issue by "tightening" the qualification of a
harmless name change for typedefs and enums.

For typedefs, a name change is harmless only if there is no change in
the textual representation of the underlying type.

For enums, a name change is harmless only if there is no other change
in the enum, like on the enumerators or on the underlying type of the
enum.

This patch is part of the set of patches whose titles are:

    Do not show decl-only-to-def changes in the leaf reporter
    Overhaul of the report diff stats summary
    Do not mark "distinct" diff nodes as being redundant
    Fix meaning of "harmless name change" to avoid overfiltering
    Better handle category propagation of pointer changes
    Improve function changes reporting in leaf and default mode
    Don't filter out typedef changes with redundant underlying type changes
    Only show leaf type changes in the leaf type changes section
    Fix leaf report of class data member changes
    Always show redundant changes in leaf mode
    Avoid reporting an enum change if it has already been reported
    When we say an a change was reported earlier give its source location
    [abipkgdiff]: in leaf mode we always show redundant changes
    Update tests for the "better leaf mode redundancy management" patchset

	* include/abg-ir.h (enum_has_non_name_change): Declare new
	* function.  Make it a friend of class enum_type_decl.
	* src/abg-comp-filter.cc (has_harmless_name_change): A typedef
	 name change cannot be harmless if the textual representation of
	the underlying type changes too.  Also, use the new
	enum_has_non_name_change to tighten the harmless name change
	definition for an enum.
	* src/abg-default-reporter.cc
	(default_reporter::report_local_typedef_changes): If the name of
	the typedef changed, report it no matter what.
	* src/abg-ir.cc (enum_has_non_name_change): Define new function.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-04-13 11:10:45 +02:00
Dodji Seketeli
59c0a2ac7c Initial support for Ada ranges
In order for abipkgdiff to handle the gnat sub-packages GCC,
Libabigail needs to understand some Ada-specific constructs.  So far,
the only unsupported construct that was problematic is the Ada Range
type.  This patch thus adds support for that Range type and so makes
it possible to handle the gnat sub-packages of GCC.

In Ada, the range type is emitted as a DW_TAG_subrange_type that is
not necessarily emitted as a property of an array type.  In C and C++
however, that DW_TAG_subrange_type is always a property of an array
type.  So the patch adds support for a so-called "free-form"
DW_TAG_subrange_type.

First, in the IR, the abigail::array_type_def::subrange_types is now a
real full blown type which can have a name and an underlying type.
That type can now be created by the both the DWARF and abixml readers.
It can also be serialized by the abixml writer.

Note that changes in the underlying type and on the name of the range
are not yet reported by the reporting engine.  That would have to be
added in a subsequent patch set.

	* include/abg-ir.h (type_maps::subrange_types): Declare new
	accessors.
	(is_ada_language, is_subrange_type): Declare new functions.
	(class array_type_def::subrange_type): Make this extend type_base
	and decl_base.
	(array_type_def::subrange_type::{get_language, operator==,
	get_pretty_representation, traverse}): Declare new member
	functions.
	(ir_node_visitor::visit_begin): Add new overloads for
	array_type::def::subrange_type.
	* src/abg-dwarf-reader.cc (build_subrange_type): Define new static
	function.
	(build_subranges_from_array_type_die): Cleanup the parameters of
	this function.
	(build_array_type): Adjust.
	(build_ir_node_from_die): Support free-form DW_TAG_subrange_type.
	(read_context::odr_is_relevant): Handle Ada.
	(die_qualified_type_name): Support DW_TAG_subrange_type.
	(die_pretty_print_type): Likewise.  Make the handling of
	DW_TAG_subrange_type use die_qualified_type_name.  Adjust the use
	of build_subranges_from_array_type_die.
	(get_scope_die): a DW_TAG_array_type cannot be a scope.  Rather,
	it's its scope that can be a scope.
	* src/abg-ir.cc (type_maps::priv::subrange_types_): New data
	member.
	(type_maps::empty): Adjust.
	(type_maps::subrange_types): Define new accessors.
	(is_ada_language, is_subrange_type): Define new functions.
	(odr_is_relevant): Support Ada.
	(maybe_update_types_lookup_map): Add an overload for
	array_type_def::subrange_type.  In the decl_base_sptr overload,
	add support for the array_type_def::subrange_type type.
	(struct array_type_def::subrange_type::priv::location_): Remove
	this as it's now carried by the parent decl_base type.
	(array_type_def::subrange_type::subrange_type): Adjust.  Take an
	environement pointer, a name, an underlying type and a language.
	(array_type_def::subrange_type::{g,s}et_underlying_type): Define
	new accessors.
	(array_type_def::subrange_type::{get_language,
	get_pretty_representation, traverse}): Define new member
	functions.
	(array_type_def::subrange_type::as_string): Add a representation
	for Ada.
	(equals): Define new overload for array_type_def::subrange_type.
	(array_type_def::subrange_type::operator==): Define three new
	overloads for decl_base, type_base and subrange_type.
	(array_type_def::subrange_type::operator!=): Define new operator.
	(get_type_representation): In the overload for array_type_def,
	support Ada.
	(array_type_def::get_language): Define new member function.
	(ir_node_visitor::visit_{begin,end}): Define new overloads for
	array_type_def::subrange_type.
	* src/abg-reader.cc (build_subrange_type): Adjust documentation.
	Support the new 'id', 'name', and 'type-id' properties.
	* src/abg-writer.cc (write_array_subrange_type): Define new static
	function.
	(write_array_type_def): Use the new write_array_subrange_type
	function.
	* tests/data/test-abidiff/test-PR18166-libtirpc.so.abi: Adjust.
	* tests/data/test-annotate/libtest23.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-annotate/test13-pr18894.so.abi: Likewise.
	* tests/data/test-annotate/test14-pr18893.so.abi: Likewise.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test17-pr19027.so.abi: Likewise.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-annotate/test7.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi: Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: 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/test7.so.abi: Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
	* tests/data/test-read-write/test25.xml: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-02-28 16:24:45 +01:00
Dodji Seketeli
6909dcb43c Bug 22692 - Consider Java as a language that supports the ODR
While comparing libgcj.so, it turned out that we are trying to
canonicalize a DW_TAG_class_type DIE expressing a Java type.

Right now, we don't canonicalize DW_TAG_class_type yet because
languages that emit those DIEs (like C++) do respect the One
Definition Rule.  So in theory, we do not need to canonicalize the
DW_TAG_class_type by using structural comparison.  We only perform DIE
canonicalization of DIEs originating from the C language as that
language does not respect the ODR.

We were assuming that only C++ actually respects the ODR.  In
practise, Java does also, so this patch now assumes that C++ and Java
respect the ODR.  So when facing DIEs originating from those
languages, we don't try (yet) to canonicalize their DIEs.

In the future though, we need to canonicalize all DIEs, irrespective
of the language they originated from.  And for that, we need to
support structural comparison of DW_TAG_class_type DIEs, among others.

	* include/abg-ir.h (is_java_language): Declare new function.
	* src/abg-dwarf-reader.cc (odr_is_relevant): Adjust to consider
	that Java also respects the ODR.
	* src/abg-ir.cc (is_java_language): Define new function.
	(odr_is_relevant): Adjust to consider that Java also respects the
	ODR.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-01-10 12:45:51 +01:00
Dodji Seketeli
b3c3049fdd Update copyright notice for all source files
Happy New Year 2018, I guess :-)

	* update-copyright.sh: New sed-based script to update the year
	in the copyright notice.
	* include/abg-comp-filter.h: Updated the year in the copyright
	notice.
	* include/abg-comparison.h: Likewise.
	* include/abg-config.h: Likewise.
	* include/abg-corpus.h: Likewise.
	* include/abg-diff-utils.h: Likewise.
	* include/abg-dwarf-reader.h: Likewise.
	* include/abg-fwd.h: Likewise.
	* include/abg-hash.h: Likewise.
	* include/abg-ini.h: Likewise.
	* include/abg-interned-str.h: Likewise.
	* include/abg-ir.h: Likewise.
	* include/abg-libxml-utils.h: Likewise.
	* include/abg-libzip-utils.h: Likewise.
	* include/abg-reader.h: Likewise.
	* include/abg-reporter.h: Likewise.
	* include/abg-sptr-utils.h: Likewise.
	* include/abg-suppression.h: Likewise.
	* include/abg-tools-utils.h: Likewise.
	* include/abg-traverse.h: Likewise.
	* include/abg-viz-common.h: Likewise.
	* include/abg-viz-dot.h: Likewise.
	* include/abg-viz-svg.h: Likewise.
	* include/abg-workers.h: Likewise.
	* include/abg-writer.h: Likewise.
	* src/abg-comp-filter.cc: Likewise.
	* src/abg-comparison-priv.h: Likewise.
	* src/abg-comparison.cc: Likewise.
	* src/abg-config.cc: Likewise.
	* src/abg-corpus-priv.h: Likewise.
	* src/abg-corpus.cc: Likewise.
	* src/abg-default-reporter.cc: Likewise.
	* src/abg-diff-utils.cc: Likewise.
	* src/abg-dwarf-reader.cc: Likewise.
	* src/abg-hash.cc: Likewise.
	* src/abg-ini.cc: Likewise.
	* src/abg-internal.h: Likewise.
	* src/abg-ir-priv.h: Likewise.
	* src/abg-ir.cc: Likewise.
	* src/abg-leaf-reporter.cc: Likewise.
	* src/abg-libxml-utils.cc: Likewise.
	* src/abg-libzip-utils.cc: Likewise.
	* src/abg-reader.cc: Likewise.
	* src/abg-reporter-priv.cc: Likewise.
	* src/abg-reporter-priv.h: Likewise.
	* src/abg-sptr-utils.cc: Likewise.
	* src/abg-suppression-priv.h: Likewise.
	* src/abg-suppression.cc: Likewise.
	* src/abg-tools-utils.cc: Likewise.
	* src/abg-traverse.cc: Likewise.
	* src/abg-viz-common.cc: Likewise.
	* src/abg-viz-dot.cc: Likewise.
	* src/abg-viz-svg.cc: Likewise.
	* src/abg-workers.cc: Likewise.
	* src/abg-writer.cc: Likewise.
	* tests/print-diff-tree.cc: Likewise.
	* tests/test-abicompat.cc: Likewise.
	* tests/test-abidiff-exit.cc: Likewise.
	* tests/test-abidiff.cc: Likewise.
	* tests/test-alt-dwarf-file.cc: Likewise.
	* tests/test-core-diff.cc: Likewise.
	* tests/test-diff-dwarf-abixml.cc: Likewise.
	* tests/test-diff-dwarf.cc: Likewise.
	* tests/test-diff-filter.cc: Likewise.
	* tests/test-diff-pkg.cc: Likewise.
	* tests/test-diff-suppr.cc: Likewise.
	* tests/test-diff2.cc: Likewise.
	* tests/test-ir-walker.cc: Likewise.
	* tests/test-lookup-syms.cc: Likewise.
	* tests/test-read-dwarf.cc: Likewise.
	* tests/test-read-write.cc: Likewise.
	* tests/test-types-stability.cc: Likewise.
	* tests/test-utils.cc: Likewise.
	* tests/test-utils.h: Likewise.
	* tests/test-write-read-archive.cc: Likewise.
	* tools/abiar.cc: Likewise.
	* tools/abicompat.cc: Likewise.
	* tools/abidiff.cc: Likewise.
	* tools/abidw.cc: Likewise.
	* tools/abilint.cc: Likewise.
	* tools/abipkgdiff.cc: Likewise.
	* tools/abisym.cc: Likewise.
	* tools/binilint.cc: Likewise.
	* tools/kmidiff.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-01-08 18:24:26 +01:00
Dodji Seketeli
108a6074a5 Initial implementation of a --leaf-changes-only option to abidiff
This patch allows abidiff to take the --leaf-changes-only option and
then to display only the changes that are local to any given type.
That means the reporting agent won't follow pointers when displaying
changes.  That gives less context to the ABI change reports but then
they are less cluttered.

To do this, the patch introduces a new reporting agent to libabigail:
abigail::comparison::leaf_reporter.  When given a graph of diff nodes,
this agent only reports about the leaf (local) changes.  That is, it
will *NOT* follow pointers, references, underlying types of qualified
and typedef types and things like that. It will just report about
changes that are local to a given type.

This reporting agent is then used (in lieu of the default
abigail::comparison::default_reporter agent) when the
--leaf-changes-only option is provided by the user on the command line
of abidiff.

Note that abidiff also takes the --impacted-interfaces option to so
that the leaf reporter shows the set of interfaces impacted
by each leaf change.

	* doc/manuals/abidiff.rst: Add documentation the new
	--leaf-changes-only and --impacted-interfaces options.
	* src/abg-leaf-reporter.cc: New file.
	* src/Makefile.am: Add the new src/abg-leaf-reporter.cc file to
	source distribution.
	* include/abg-fwd.h (get_var_size_in_bits)
	(function_decl_is_less_than): Declare new functions.
	(get_name): Add new overload for type_or_decl_base*.
	* include/abg-ir.h (struct type_or_decl_hash, type_or_decl_equal)
	(type_or_decl_base_comp): Define new types.
	(artifact_sptr_set_type, artifact_ptr_set_type): Define new
	typedefs.
	* include/abg-comp-filter.h: Update copyright year.
	(has_basic_type_name_change): Add new function declaration.
	* src/abg-comp-filter.cc (decl_name_changed): Take a
	type_or_decl_base rather than just a decl.  Add an overload for
	diff*.
	(has_basic_type_name_change): Define new function.
	* include/abg-comparison.h: Update copyright year.
	(string_diff_ptr_map): Define this new typedef.
	(class diff_maps): Define this new class.
	(diff_context::{set_corpora}): Remove this member function.
	(diff_context::{set_corpus_diff, get_corpus_diff,
	show_leaf_changes_only, show_impacted_interfaces,
	forbid_visiting_a_node_twice_per_interface}): Declare these new
	member functions.
	(diff_node_visitor::priv_): Add a new pimpl data member.
	(diff_node_visitor::{diff_node_visitor, get_visiting_kind,
	set_visiting_kind}): Turn these into out-of-line member functions.
	(diff_node_visitor::{set,get}_current_topmost_iface_diff): Add new
	member functions.
	(class {scope_diff, function_type_diff, corpus_diff}): Add class
	leaf_reporter as a friend.
	(corpus_diff::mark_leaf_diff_nodes, get_leaf_diffs): Declare new
	member functions.
	(diff::{visiting_a_node_twice_is_forbidden_per_interface,
	parent_interface_node}): Define new member functions.
	(is_diff_of_basic_type): Return a type_decl_diff* rather than just
	a bool.
	(is_enum_diff, is_array_diff, is_function_type, is_typedef_diff)
	(is_corpus_diff): Declare new functions.
	(corpus_diff::diff_stats::{num_leaf_changes,
	num_leaf_changes_filtered_out, net_num_leaf_changes}): Add new
	member functions.
	(is_distinct_diff): Declare new function.
	* include/abg-reporter.h: Forward-declare "class diff_maps".
	(reporter_base::diff_to_be_reported): Declare a new virtual member
	function.
	(reporter_base::{report_local_typedef_changes,
	report_local_reference_type_changes,
	report_local_function_type_changes}): Declare new member
	functions.
	(class leaf_reporter): Define new type.
	* src/abg-comparison-priv.h (struct diff_hash, diff_equal): Define
	new types.
	(diff_artifact_set_map_type): Define new typedef.
	(diff_context::priv::{first_corpus_, second_corpus_}): Remove
	these data members.
	(diff_context::priv::{corpus_diff_, leaf_changes_only_,
	reset_visited_diffs_for_each_interface_,
	show_impacted_interfaces_}): Add new data members.
	(diff_context::priv::priv): Adjust.
	(corpus_diff::priv::{leaf_diffs_, parent_interface_}): Add new
	data member.
	(corpus_diff::diff_stats::priv::{num_leaf_changes,
	num_leaf_changes_filtered_out}): Add new data members.
	(corpus_diff::priv::count_leaf_changes): Define new member
	function.
	(sort_artifacts_set, get_fn_decl_or_var_decl_diff_ancestor)
	(is_diff_of_global_decls): Declare new functions.
	(function_comp::operator()): Factorize this out into the new
	function abigail::ir::function_decl_is_less_than.
	* src/abg-ir.cc (get_var_size_in_bits)
	(function_decl_is_less_than): Define new functions.
	(get_name): Define new overload for type_or_decl_base*.
	* src/abg-comparison.cc (is_enum_diff, is_typedef_diff)
	(is_array_diff, is_function_type_diff, is_corpus_diff)
	(is_distinct_diff, sort_artifacts_set, is_diff_of_global_decls):
	Define new functions.
	(is_union_diff): Fix comment.
	(diff_context::forbid_visiting_a_node_twice_per_interface): Define
	new member functions.
	(diff_context::set_corpus_diff, get_corpus_diff)
	(diff_context::show_leaf_changes_only)
	(diff_context::visiting_a_node_twice_is_forbidden_per_interface)
	(diff_context::show_impacted_interfaces): Define new member
	functions.
	(diff_context::get_reporter): Create the reporter that matches
	what diff_context::show_leaf_changes_only says.
	(diff_node_visitor::priv): Define a new type.
	(diff_node_visitor::{diff_node_visitor, get_visiting_kind,
	set_visiting_kind, or_visiting_kind,
	set_current_topmost_iface_diff, get_current_topmost_iface_diff}):
	Define new out-of-line member functions.
	(struct diff_maps::priv): Define new type.
	(diff_maps::{diff_maps, get_type_decl_diff_map,
	get_type_decl_diff_map, get_enum_diff_map, get_class_diff_map,
	get_union_diff_map, get_typedef_diff_map, get_array_diff_map,
	get_function_type_diff_map, get_function_decl_diff_map,
	get_var_decl_diff_map, get_reference_diff_map,
	get_fn_parm_diff_map, get_distinct_diff_map, insert_diff_node,
	lookup_impacted_interfaces}): Define member functions.
	(corpus_diff::{mark_leaf_diff_nodes, get_leaf_diffs}): Define new
	member functions.
	(struct leaf_diff_node_marker_visitor): Define new type.
	(corpus_diff::apply_filters_and_suppressions_before_reporting):
	Mark diff nodes in here.
	(corpus_diff::traverse): Appropriately set the current topmost
	interface into the visitor before visiting a diff node.
	(compute_diff): In the overload for corpus_sptr, adjust to reflect
	that we are now storing the corpus_diff in the diff context.
	(is_diff_of_basic_type): Return a type_decl_diff*, not just a
	bool.
	(corpus_diff::priv::count_leaf_changes): Define a new member
	function.
	(corpus_diff::diff_stats::{num_leaf_changes,
	num_leaf_changes_filtered_out, net_num_leaf_changes}): Define new
	member functions.
	(corpus_diff::priv::apply_filters_and_compute_diff_stats): Use the
	new corpus_diff::priv::count_leaf_changes to compute the number of
	leaf changes.
	(corpus_diff::priv::emit_diff_stats): Emit the report about leaf
	type changes when necessary.
	* src/abg-reporter-priv.h (report_mem_header): Declare new
	overload.
	(maybe_show_relative_offset_change,): Pass the var_diff_sptr
	parameter by const reference.
	(represent): Pass the var_diff_sptr parameter by const reference
	and take a new "local-only" flag.
	(maybe_show_relative_size_change)
	(maybe_report_interfaces_impacted_by_diff): Declare new functions.
	* src/abg-default-reporter.cc: Adjust copyright year.
	(default_reporter::{report_local_typedef_changes,
	report_local_qualified_type_changes,
	report_local_reference_type_changes,
	report_local_function_type_changes}): Define new member functions.
	(default_reporter::report): Adjust.  Add an overload for
	function_type_diff&. In the overload for qualified_type_diff, if
	the name of the underlying type changed, do not detail the changes
	any further.  In the overload for function_decl_diff, Adjust to
	use the new diff_context::get_{first, second}_corpus member
	function.  In the overload for enum_diff, call the new
	maybe_report_interfaces_impacted_by_diff that is advertised below.
	* src/abg-reporter-priv.cc (represent): Adjust the overload for
	var_diff_sptr.
	(report_mem_header): Define new overload.
	(maybe_show_relative_size_change)
	(maybe_report_interfaces_impacted_by_diff): Define new functions.
	(reporter_base::diff_to_be_reported): Define new member function.
	(maybe_show_relative_offset_change): Pass the var_diff_sptr
	parameter by const reference.
	(represent): In the overload for var_diff_sptr, pass the
	var_diff_sptr parameter by reference.  Take a 'local_only' flag.
	Iisplay type changes only if we are not displaying "local changes
	only".  Display size changes of data members too, when in
	"local-only" mode.
	* src/abg-suppression.cc (sonames_of_binaries_match)
	(names_of_binaries_match): Adjust.
	* tools/abidiff.cc (options::{leaf_changes_only,
	show_impacted_interfaces}): Add new data members.
	(display_usage): Emit usage string for the new --leaf-changes-only
	and --impacted-interfaces options.
	(parse_command_line): Parse the new --leaf-changes-only and the
	--impacted-interfaces options.
	(set_diff_context_from_opts): Set the 'show-leaf-changes' and the
	'show-impacted-interfaces' flags.
	* tests/data/test-diff-filter/libtest42-leaf-report-v{0,1}.so: New
	test input.
	* tests/data/test-diff-filter/test42-leaf-report-output-0.txt: New
	test reference output.
	* tests/data/test-diff-filter/test42-leaf-report-v{0,1}.cc: Source
	code of the new test inputs.
	* tests/test-diff-filter.cc (in_out_specs): Use the new test
	inputs above in this harness.
	* tests/data/test-diff-suppr/libtest35-leaf-v0.so: New test input.
	* tests/data/test-diff-suppr/test35-leaf-report-0.txt: New test
	reference output.
	* tests/data/test-diff-suppr/test35-leaf-v{0,1}.cc: Source code of
	the new test inputs.
	* tests/data/test-diff-suppr/test35-leaf.suppr: Suppression
	specification to use for the test35 test.
	* tests/data/test-diff-suppr/libtest36-leaf-v0.so: New test input.
	* tests/data/test-diff-suppr/libtest36-leaf-v1.so: Likewise.
	* tests/data/test-diff-suppr/test36-leaf-report-0.txt: New
	reference test output.
	* tests/data/test-diff-suppr/test36-leaf-v0.cc: Source code of
	test input above.
	* tests/data/test-diff-suppr/test36-leaf-v1.cc: Likewise.
	* tests/test-diff-suppr.cc (in_out_specs): Use the new test inputs
	above in this harness.
	* tests/data/Makefile.am: Add the new test inputs above to source
	distribution.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-10-08 18:51:35 +02:00
Dodji Seketeli
90919fceeb Bug 21627 - Libabigail doesn't consider translation unit compile dir
The path of a translation unit is relative to the directory where that
translation unit was compiled.

So there can be several different translation units (in the same
binary) that have the same (relative) paths.  To tell them apart, one
needs to consider the compile directory of those translation units.

But then Libabigail ignores the compilation directory of translation
units.  It just considers their (relative) path.  That leads to
different translation units having the same path.

Furthermore, there can be a translation unit with full path (one that
takes into account the file name and its compile directory) named "P"
that contains function definitions f1 and f2, as described by the
debug info.  Further down the road, there can be *another* translation
unit which also has "P" as its full path, and that cotnains function
definitions f3 and f4.  A way to understand is to consider that the
translation unit of full path "P" contains f1, f2, f3 and f4.

This patch introduces the concept of the compile dir of a given
translation unit, and the concept of the absolute path of the
translation unit which would then be a concatenation of the compile
dir and relative paths of the translation unit.

The patch also tries to reuse a translation unit with a given path,
*if* that translation unit has already been seen in the current
binary, instead of creating a new one altogether.

This patch doesn't carry a regression test as the problem was found
while running the
https://pagure.io/libabigail-selfcheck/blob/master/f/selfcheck.py
script over the Fedora 25 critpath packages.

The patch does however update existing reference outputs of existings
tests where appropriate.

	* include/abg-ir.h (translation_unit::{get_compilation_dir_path,
	set_compilation_dir_path, get_absolute_path}):
	* src/abg-corpus.cc (corpus::add): Use the new
	translation_unit::get_absolute_path() as the key for the tu path
	-> tu map.
	* src/abg-dwarf-reader.cc
	(read_context::resolve_declaration_only_classes):  Use the new
	translation_unit::get_absolute_path().
	(build_translation_unit_and_add_to_ir): Set the compilation
	directory of the translation unit.
	* src/abg-ir-priv.h (translation_unit::priv::{comp_dir_path_,
	abs_path_}):
	* src/abg-ir.cc (translation_unit::set_path): Update comment.
	(translation_unit::{get_compilation_dir_path,
	set_compilation_dir_path, get_absolute_path}): Define new member
	functions.
	* src/abg-reader.cc (read_translation_unit): Take the new
	'comp-dir-path' attribute into account.
	* src/abg-writer.cc (write_translation_unit): Emit the new
	'comp-dir-path' attribute.
	* tests/data/test-annotate/libtest23.so.abi: Adjust.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Adjust.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Adjust.
	* tests/data/test-annotate/test0.abi: Adjust.
	* tests/data/test-annotate/test1.abi: Adjust.
	* tests/data/test-annotate/test13-pr18894.so.abi: Adjust.
	* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-annotate/test17-pr19027.so.abi: Adjust.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust.
	* tests/data/test-annotate/test2.so.abi: Adjust.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust.
	* tests/data/test-annotate/test21-pr19092.so.abi: Adjust.
	* tests/data/test-annotate/test3.so.abi: Adjust.
	* tests/data/test-annotate/test4.so.abi: Adjust.
	* tests/data/test-annotate/test5.o.abi: Adjust.
	* tests/data/test-annotate/test6.so.abi: Adjust.
	* tests/data/test-annotate/test7.so.abi: Adjust.
	* tests/data/test-annotate/test8-qualified-this-pointer.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Adjust.
	* tests/data/test-read-dwarf/test0.abi: Adjust.
	* tests/data/test-read-dwarf/test1.abi: Adjust.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Adjust.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust.
	* tests/data/test-read-dwarf/test2.so.abi: Adjust.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.
	* tests/data/test-read-dwarf/test3.so.abi: Adjust.
	* tests/data/test-read-dwarf/test4.so.abi: Adjust.
	* tests/data/test-read-dwarf/test5.o.abi: Adjust.
	* tests/data/test-read-dwarf/test6.so.abi: Adjust.
	* tests/data/test-read-dwarf/test7.so.abi: Adjust.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-04 16:35:35 +02:00
Dodji Seketeli
a7492fea56 Support ELF symbol visibility property
This patch models the ELF symbol visibility property and support
ignoring function and variable symbols that are HIDDEN and INTERNAL,
even if they have default binding.

	* include/abg-ir.h (enum elf_symbol::visibility): Define new enum.
	(elf_symbol::{elf_symbol, create}): Take a visibility parameter.
	(elf_symbol::{set, get}_visibility): Declare new accessors.
	(string_to_elf_symbol_binding): Declare new function.
	* src/abg-ir.cc (elf_symbol::priv::visibility_): New data member.
	(elf_symbol::priv::priv): Adjust.
	(elf_symbol::elf_symbol): Take a visibility parameter.
	(elf_symbol::create): Likewise
	(elf_symbol::{s,g}et_visibility): Define new accessors.
	(elf_symbol::is_public): Adjust.
	(operator<<(std::ostream&, elf_symbol::visibility)): Define new
	operator.
	(string_to_elf_symbol_visibility): Define new function.
	* src/abg-dwarf-reader.cc (stv_to_elf_symbol_visibility): Define
	new static function.
	(lookup_symbol_from_sysv_hash_tab)
	(lookup_symbol_from_gnu_hash_tab, lookup_symbol_from_symtab)
	(create_default_var_sym, create_default_fn_sym): Adjust.
	* src/abg-reader.cc (read_elf_symbol_binding): Define new
	function.
	(build_elf_symbol): Adjust.
	* src/abg-writer.cc (write_elf_symbol_visibility): Define new
	function.
	* tests/data/test-annotate/libtest23.so.abi: Adjust.
	* tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Adjust.
	* tests/data/test-annotate/libtest24-drop-fns.so.abi: Adjust.
	* tests/data/test-annotate/test0.abi: Adjust.
	* tests/data/test-annotate/test1.abi: Adjust.
	* tests/data/test-annotate/test13-pr18894.so.abi: Adjust.
	* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-annotate/test17-pr19027.so.abi: Adjust.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Adjust.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Adjust.
	* tests/data/test-annotate/test2.so.abi: Adjust.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Adjust.
	* tests/data/test-annotate/test21-pr19092.so.abi: Adjust.
	* tests/data/test-annotate/test3.so.abi: Adjust.
	* tests/data/test-annotate/test4.so.abi: Adjust.
	* tests/data/test-annotate/test5.o.abi: Adjust.
	* tests/data/test-annotate/test6.so.abi: Adjust.
	* tests/data/test-annotate/test7.so.abi: Adjust.
	* tests/data/test-annotate/test8-qualified-this-pointer.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Adjust.
	* tests/data/test-read-dwarf/test0.abi: Adjust.
	* tests/data/test-read-dwarf/test1.abi: Adjust.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Adjust.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test2.so.abi: Adjust.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test3.so.abi: Adjust.
	* tests/data/test-read-dwarf/test4.so.abi: Adjust.
	* tests/data/test-read-dwarf/test5.o.abi: Adjust.
	* tests/data/test-read-dwarf/test6.so.abi: Adjust.
	* tests/data/test-read-dwarf/test7.so.abi: Adjust.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.
	* tests/data/test-read-write/test26.xml: Adjust.
	* tests/data/test-read-write/test27.xml: Adjust.
	* tests/data/test-read-write/test28-without-std-fns-ref.xml:
	Adjust.
	* tests/data/test-read-write/test28-without-std-vars-ref.xml:
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:47 +02:00
Dodji Seketeli
5529a51a96 Do not report about voffset when it's not set in debug info
Sometimes some virtual member functions don't have any virtual offset
set in the debug info.  This happens for virtual destructors
sometimes.  In that case, the ABI change report should not refer to
that unset virtual offset as being '0'.  Rather, it shouldn't refer to
it at all.

This is what this patch does.

	* include/abg-ir.h (mem_fn_context_rel::mem_fn_context_rel):
	Initialize the virtual offset to -1.
	* src/abg-comparison.cc (represent): In the overload to represent
	a method_decl, do not represent the vofffset if it's not set.
	* src/abg-writer.cc (write_voffset): The virtual offset is signed
	because if it's -1, it means no offset is set.
	* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Adjust.
	* tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Adjust.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Adjust.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Adjust.
	* tests/data/test-diff-dwarf/test28-vtable-changes-report-0.txt: Adjust.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:44 +02:00
Dodji Seketeli
76d832115d Allow selective resolution of class declaration
When a class is forward-declared, resolving it to a definition that
appears later in the same translation unit or in another translation
is an interesting problem.

Until now, the declaration would be resolved to the definition of that
class found in the binary.  The problem is that there can be different
such definitions, especially in C where there is no "One Definition
Rule".  In that case, the definition chosen is random.

This patch resolves that randomness.

For a given class declaration, if there is just one possible
definition in the binary, then the declaration is resolved to that
definition.  If there is one definition for that declaration in the
same translation unit, then the declaration is resolved to that
definition.  If there are more than one definitions in translation
units that are not the one of the declaration, then the declaration is
left unresolved.  This is what I call "selective class declaration resolution".

Note that an unresolved class declaration now compares different to a
definition of a class of the same name.  This is so that we can have
an unresolved class be present in the resulting .abi file, alongside
an (incompatible) definition of the same class.  The change from a class
declaration to its definition is filtered out by default, though.

	* include/abg-fwd.h (type_base_wptrs_type)
	(istring_type_base_wptrs_map_type): Define new typedefs.
	(lookup_class_types): Declare new functions.
	* include/abg-ir.h
	(environment::decl_only_class_equals_definition): Declare new
	accessor.
	(type_maps::{*_types}): Make these accessors return
	istring_type_base_wptrs_map_type& instead of
	istring_type_base_wptr_map_type&.
	* src/abg-dwarf-reader.cc
	(read_context::resolve_declaration_only_classes): Implement the
	new selective declaration resolution scheme.
	* src/abg-ir.cc (type_maps::priv::{*_types_}): Change the type of
	these data members from istring_type_base_wptr_map_type to
	istring_type_base_wptrs_map_type.
	(type_maps::{*_types}): Make these accessors definitions return
	istring_type_base_wptrs_map_type& instead of
	istring_type_base_wptr_map_type&.
	(translation_unit::bind_function_type_life_time): Adjust.
	(environment::priv::decl_only_class_equals_definition_): New data
	member.
	(environment::priv::priv): Initialize it.  By default, a decl-only
	class is now considered different from its definition.
	(environment::decl_only_class_equals_definition): Define new
	accessor.
	(lookup_types_in_map, lookup_class_types): Define new functions.
	(lookup_type_in_map, lookup_union_type_per_location)
	(lookup_basic_type, lookup_basic_type_per_location)
	(lookup_class_type, lookup_class_type_per_location)
	(lookup_union_type, lookup_enum_type)
	(lookup_enum_type_per_location, lookup_typedef_type)
	(lookup_typedef_type_per_location, lookup_qualified_type)
	(lookup_pointer_type, lookup_reference_type, lookup_array_type)
	(lookup_function_type, maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map<class_decl>)
	(maybe_update_types_lookup_map<function_type>): Adjust.
	(type_base::get_canonical_type_for): When doing type comparison
	here, we can now consider that an unresolved class declaration
	compares different to an incompatible class definition of the same
	name.  So no need to look through decl-only classes in that case.
	(equals): In the overload for class_or_union, if
	environment::decl_only_class_equals_definition() is false, then an
	unresolved class declaration of name "N" compares different to a
	class definition named "N".
	* tests/data/test-annotate/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-diff-dwarf/test28-vtable-changes-report-0.txt:
	Adjust.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt:
	Adjust.
	* tests/data/test-diff-filter/test38/Makefile: New test material.
	* tests/data/test-diff-filter/test38/test38-a.c: Likewise.
	* tests/data/test-diff-filter/test38/test38-b.c: Likewise.
	* tests/data/test-diff-filter/test38/test38-c.c: Likewise.
	* tests/data/test-diff-filter/test38/test38-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test38/test38-v0: Likewise.
	* tests/data/test-diff-filter/test38/test38-v1: Likewise.
	* tests/data/test-diff-filter/test38/test38.h: Likewise.
	* tests/data/test-diff-filter/test39/Makefile: Likewise.
	* tests/data/test-diff-filter/test39/test39-a-v0.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-a-v1.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-b-v0.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-b-v1.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-c-v0.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-c-v1.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-main.c: Likewise.
	* tests/data/test-diff-filter/test39/test39-report-0.txt: Likewise.
	* tests/data/test-diff-filter/test39/test39-v0: Likewise.
	* tests/data/test-diff-filter/test39/test39-v1: Likewise.
	* tests/data/test-diff-filter/test39/test39.h: Likewise.
	* tests/data/Makefile.am: Add the new test material above to the
	source distribution.
	* tests/test-diff-filter.cc (in_out_specs): Add the new test
	inputs above to the test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:43 +02:00
Dodji Seketeli
c99addc245 Initial support to lookup types per location
This patch adds support to associate a type to its source location.
The location being a string of the form "filepath:line:column".  The
association is done by a per-translation unit map which associates a
location to a type.

For the moment this only associates one type to a given location.  For
the general case, though, we need to associate a vector or types to a
given location.  We'll add that support later.

The patch provides lookup functions, each of which looking up a
particular kind of type by its location.

	* include/abg-fwd.h (get_name_of_qualified_type)
	(get_name_of_reference_to_type, lookup_basic_type_per_location)
	(lookup_class_type_per_location, lookup_union_type_per_location)
	(lookup_enum_type_per_location, lookup_typedef_type)
	(lookup_typedef_type_per_location, lookup_pointer_type)
	(lookup_reference_type, lookup_type_per_location)
	(lookup_type_through_translation_units)
	(lookup_type_from_translation_unit, odr_is_relevant): Declare new
	functions or new function overloads.
	* include/abg-ir.h (location::expand): Declare new member
	function.
	(type_maps::empty): Likewise.
	(operator|=): Declare an overload for qualified_type_def::CV.
	(get_string_representation_of_cv_quals)
	(get_name_of_qualified_type, lookup_qualified_type): Declare new functions.
	* src/abg-ir.cc (location::expand): Define new member function.
	(type_maps::empty): Likewise.
	(odr_is_relevant): Likewise.
	(get_string_representation_of_cv_quals)
	(get_name_of_reference_to_type, get_name_of_qualified_type)
	(lookup_union_type_per_location): Define new functions or overloads.
	(lookup_basic_type, lookup_enum_type, lookup_typedef_type)
	(lookup_qualified_type, lookup_pointer_type)
	(lookup_reference_type, lookup_type_from_translation_unit)
	(lookup_basic_type_per_location, lookup_basic_type_per_location)
	(lookup_class_type_per_location, lookup_class_type_per_location)
	(lookup_enum_type_per_location, lookup_enum_type_per_location)
	(lookup_typedef_type_per_location)
	(lookup_typedef_type_per_location, lookup_type_per_location):
	Define new overloads.
	(maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map<class_decl>)
	(maybe_update_types_lookup_map<function_type>): Add a new
	use_type_name_as_key parameter.  If it's false, then associates
	the type to its location rather than to its name.
	(maybe_update_types_lookup_map): In the overloads for type_decl,
	class_decl, union_decl, enum_type, typedef_decl, array_type_def,
	record the type in the lookup map per location, in addition to the
	per-name recording.
	(qualified_type_def::build_name): Use the new
	get_name_of_qualified_type.
	(qualified_type_def::get_cv_quals_string_prefix): Use the new
	get_string_representation_of_cv_quals.
	(operator|=): Define a new overload for qualified_type_def::CV.
	(pointer_type_def::get_qualified_name): Use the new
	get_name_of_pointer_to_type.
	(reference_type_def::get_qualified_name): Use the new
	get_name_of_reference_to_type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-07-03 17:45:36 +02:00
Ben Woodard
b8a629f4a1 Fix some clang compile problems
* include/abg-comp-filter.h (class filter_base): Declare this as a
	struct.
	* include/abg-comparison.h (class filtering::filter_base):
	Likewise.
	(struct diff_traversable_base): Declare this as a class.
	* include/abg-ir.h (function_decl::parameter): Declare this before
	using it.
	* src/abg-corpus.cc
	(corpus::priv::build_unreferenced_symbols_tables): Add missing
	parenthesis around assignment expressions inside conditional
	expressions.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-06-02 22:50:06 +02:00
Dodji Seketeli
d8f09c9e89 Avoid building DIE -> parent DIE map when analyzing a C binary
The C language doesn't support namespaces.  So, in that language, the
context of a type is always the global scope.  Hence, the context of a
type DIE is always the global context associated to the current
translation unit.

Thus, when we are analyzing a C binary, we can do away with building
the DIE -> DIE parent map that we later use to get the parent of a
type DIE when we need to determine the context of a given type DIE.

This can save significant time and space.

This patch implements this optimization.

	* include/abg-ir.h (global_scope_sptr): Make this be a share_ptr
	of scope_decl, not of global_scope.
	(translation_unit::get_global_scope): Return a reference to
	scope_decl_sptr.
	* src/abg-ir.cc (translation_unit::get_global_scope): Return a
	scope_decl not a global_scope.
	* src/abg-dwarf-reader.cc (read_context::nil_scope_): Add new data
	member.
	(read_context::{global_scope, nil_scope}): Define new member functions.
	(read_context::build_die_parent_maps): Do not build the map if we
	are looking at a C (or asm) translation unit.
	(get_scope_die, get_scope_for_die): If we are looking at a C
	translation unit then do return the global scope.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-05-10 11:50:54 +02:00
Dodji Seketeli
12b80d0770 Speed up access to the definition of a class declaration-only type
While emitting an abixml output for a corpus_group representing the
KMI of a Linux kernel tree, profiling shows that during comparison of
class types, calling class_decl::get_definition_of_declaration is a
hotspot.  Especially, the fact the function returns a shared pointer
that has to be "handled" shows up in the profile.

This patch introduces a
class_decl::get_naked_definition_of_declaration that returns a
pointer.  Not a shared pointer.

The patch then uses that get_naked_definition_of_declaration function
in the comparison code for class_decl.

The patch also uses get_naked_canonical_type instead of
get_canonical_type when comparing a bunch of other types.

This makes things a little bit faster when compiled without
optimization between 2% and 5%.

	* include/abg-ir.h
	(class_or_union::get_naked_definition_of_declaration): Declare a
	new member function.
	(class_decl::get_naked_definition_of_declaration): Likewise.
	* src/abg-ir.cc ({type_decl, qualified_type_def,
	array_type_def, enum_type_decl}::operator==): Use the
	get_naked_canonical_type and get_naked.
	(class_or_union::priv::naked_definition_of_declaration_): Define
	new data member.
	(class_or_union::priv::priv): Adjust to initialize the new data
	member.
	(class_or_union::get_naked_definition_of_declaration): Define new
	member function.
	({class_or_union, class_decl}::operator==): Use the new
	get_naked_definition_of_declaration instead of
	get_definition_of_declaration.
	(equals): In the overload for class_or_union, do the same.
	(class_decl::get_naked_definition_of_declaration): Define new
	member function.
	(hash_type_or_decl): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-05-10 11:49:57 +02:00
Ondrej Oprala
0e88e12f05 cppcheck: mitigate performance warnings
* include/abg-diff-utils.h (print_snake): pass argument of type
	snake by const reference.
	* include/abg-ir.h (location::operator{==,<}): Likewise.
	* include/abg-viz-dot.h (node_base::{node_base,parent_node,child_node}):
	Likewise.
	* include/abg-viz-svg.h (svg::svg) Likewise.
	* src/abg-config.cc (config::config): Member initialization in ctor body.
	* src/abg-dwarf-reader.cc (class_decl_sptr::add_or_update_class_type):
	Initial value never used.
	* src/abg-ir.cc: (decl_base::priv::priv) Member initialization in ctor body,
	pass argument of type location by const reference.
	(equals): Variable initial value never used.
	* src/abg-reader.cc (read_corpus_from_input): Initial variable
	value never used.
	(build_elf_symbol_db): Use pre-increment.
	* src/abg-suppression-priv.h
	(suppression_matches_type_location): Pass argument of type
	location by const reference.
	* src/abg-suppression.cc: Likewise.

Signed-off-by: Ondrej Oprala <ondrej.oprala@gmail.com>
2017-04-14 04:41:44 -04:00
Dodji Seketeli
688d18dc71 Bug 21228 - Handle cloning union member functions
It turns out we allow member function cloning only for functions that
are members of classes, not for functions that are member of unions.

This patch fixes that by turning the method
class_decl::add_member_function into the
class_or_union::add_member_function.  Note that there was already an
overload of class_or_union::add_member_function; now, all the member
functions add_member_function are members of the class_or_union type.

The patch then modifies function_decl::clone to make that code avoid
assuming that only member functions of classes can be cloned.

	* include/abg-ir.h (class_or_union::add_member_function): Move the
	class_decl::add_member_function overload declaration into the
	class class_or_union class.
	(class class_decl): Make the class class_or_union be a friend of
	class_decl.
	* src/abg-ir.cc (class_decl::add_member_function): Transform the
	definition of this overload into ...
	(class_or_union::add_member_function): ... this one.  Make sure
	that when setting the virtual-ness attributes of the member
	function, we are effectively looking at the a function that is a
	member of a class.
	(function_decl::clone): Do not assert that a member function is
	necessarily a member of a class_decl.  It can also a member of a
	union_decl!.  So, rather, assert that the scope of the member
	function is of type class_or_union.
	* tests/data/test-diff-pkg/tbb-2017-8.20161128.fc26.x86_64.rpm:
	New test input RPM.
	* tests/data/test-diff-pkg/tbb-2017-9.20170118.fc27.x86_64.rpm:
	* tests/data/test-diff-pkg/tbb-debuginfo-2017-8.20161128.fc26.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/tbb-debuginfo-2017-9.20170118.fc27.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/tbb-2017-8.20161128.fc26.x86_64--tbb-2017-9.20170118.fc27.x86_64.txt:
	New reference test output.
	* tests/data/Makefile.am: Add the new test input RPMs to the
	source distribution.
	* tests/test-diff-pkg.cc (in_out_specs): Take the new input tests
	above into account.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-07 11:50:56 +01:00
Dodji Seketeli
2d828b3b32 Misc style fixes
* include/abg-ir.h (class_or_union): Fix indentation.
	* src/abg-dwarf-reader.cc (get_die_pretty_representation): Add new
	line.
	* src/abg-ir.cc (struct class_decl::priv): Fix indentation.
	(virtual_member_function_less_than::operator()): Fix a typo in a
	comment.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-02-14 12:49:48 +01:00
Dodji Seketeli
059c86ec0b Bug 20476 - Compare virtual member functions when comparing classes
There are cases where a virtual member function doesn't have an
implementation that is defined and publicly exported.  This is the
cases for virtual pure classes.

Even in those cases, users might want to detect vtable changes on
virtual member pure classes (interfaces).

Now that, for C++ binaries, all the partial representations of a class
are merged into one class (in a given binary), we can envision to
compare virtual member functions of classes as part of comparing two
classes.

This is what this patch does.  While comparing two classes, the
virtual member functions are compared too.

Note that as there can be several virtual member functions that have
the same vtable offset (think about a virtual destructor that might
have several generated functions that 'conceptually' share the same
vtable offset), comparing the virtual functions can be a little bit
non-trivial.

The approach taken is to check that in the first set of virtual
functions, each virtual function actually matches at least one virtual
function in the second set.  And the match is a "loose" one.  That is,
it doesn't take into account the symbol name or the mangled name.

The patch also fixes the "less than" operator used to sort virtual
member functions.

There is also a buglet in the way we compute the highest vtable offset
number today.  This patch provides a new function named
class_decl::get_biggest_vtable_offset that is used in the change reports.

The patch also fixes a related bug in where we were forgetting to
report about added and removed virtual member functions without an
associated elf symbol.  This patch fixes that.

	* include/abg-ir.h (class_decl::get_biggest_vtable_offset):
	Declare new member function.
	* src/abg-ir.cc (virtual_member_function_less_than::operator()):
	Either compare the symbol id strings if the functions have
	symbols or just compare their pretty representations.
	(class_decl::get_biggest_vtable_offset): Define new member
	function.
	(methods_equal_modulo_elf_symbol)
	(method_matches_at_least_one_in_vector): New static methods.
	(equals): In the overload for classes, compare the virtual member
	functions while comparing classes.
	* src/abg-comparison.cc (represent): In the overload for
	method_decl_sptr, fix the way we compute the highest vtable offset
	number for a give class_decl.
	(class_decl::ensure_lookup_tables_populated): Don't forget added
	and removed virtual member functions in the report for changed
	classes.
	* tests/data/test-diff-dwarf/libtest41-PR20476-hidden-old.so: New
	test binary input file.
	* tests/data/test-diff-dwarf/libtest41-PR20476-hidden-new.so: Likewise.
	* tests/data/test-diff-dwarf/test41-PR20476-hidden-report-0.txt:
	New reference output.
	* tests/data/Makefile.am: Add the new test material above to the
	source distribution.
	* tests/test-diff-dwarf.cc (in_out_spec): Add the new tests
	here.
	* tests/data/test-annotate/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-annotate/test11-pr18828.so.abi: Adjust.
	* tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust.
	* tests/data/test-annotate/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Adjust.
2017-02-14 12:49:47 +01:00
Dodji Seketeli
a821154753 Support virtual member functions with vtable offset not yet set
When reading C++ class informatin DWARF, it can happen that a given
virtual member function does not yet have a vtable offset.  Right now,
that offset is set to zero.  Just like a virtual member function which
actual vtable offset is zero.  So we don't make a difference between a
virtual function with no vtable offset and a virtual function with a
vtable offset set to zero.

This can lead to confusions during class comparison.

This patch fixes that problem by setting the default vtable offset to
-1.  So whenever a vtable offset is -1 it means that the virtual
member function doesn't yet have a vtable offset.

	* include/abg-fwd.h (member_function_has_vtable_offset): Declare
	new function.
	(get_member_function_vtable_offset): Return a ssize_t, not a
	size_t.
	(set_member_function_vtable_offset): Take a ssize_t, not a size_t.
	* include/abg-ir.h (class_decl::virtual_mem_fn_map_type): Adjust
	the map typedef to make it take ssize_t as the type of the key.
	(mem_fn_context_rel::vtable_offset_in_bits_): Make this data
	member be of ssize_t type, not size_t.
	(mem_fn_context_rel::mem_fn_context_rel): Initialize the
	vtable_offset_in_bits_ data member to -1.
	* src/abg-ir.cc (member_function_has_vtable_offset): Define new
	function.
	(get_member_function_vtable_offset): Return a ssize_t, not a
	size_t.
	(set_member_function_vtable_offset): Take a ssize_t, not a size_t.
	* src/abg-dwarf-reader.cc (die_virtual_function_index): Take an
	int64_t& rather than a uint64_t&.
	(finish_member_function_reading): Don't set the vtable offset if
	it's -1.
	* src/abg-reader.cc (build_class_decl): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 21:00:56 +01:00
Dodji Seketeli
9136c6a639 Handle several virtual member functions having the same vtable offset
In the DWARF for C++, it can happens that a virtual constructor leads
to several (up to 3) destructor functions that all have the same
vtable offset.  That vtable offset is the same as the offset of the
virtual destructor that the user actually defined in her source code.

This patch adds a map data structure to the private data of
class_decl.  That map associates a vtable offset X to a vector of
virtual member functions that have the same vtable offset X.

That new map is populated whenever a virtual member function is added
to the class.

	* include/abg-ir.h (class_or_union::virtual_mem_fn_map_type):
	Define new typedef.
	(class_decl::get_virtual_mem_fns_map): Declare new accessor.
	* src/abg-ir.cc (class_decl::priv::virtual_mem_fns_map_): New data
	member.
	(class_decl::get_virtual_mem_fns_map): Define new accessor.
	(fixup_virtual_member_function): Populate the new virtual member
	functions map.
	(class_decl::on_canonical_type_set): Sort the virtual member
	function vectors stored in the new virtual member functions map.
	(class_decl::add_member_function): Call
	set_member_function_is_virtual *after* calling
	set_member_function_vtable_offset because the former updates the
	virtual function map, so it needs the vtable offset.
	* src/abg-dwarf-reader.cc (finish_member_function_reading):
	Likewise.
	* src/abg-reader.cc (build_class_decl): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 21:00:54 +01:00
Dodji Seketeli
367da46e7a Speed up pretty representing (function) types
During structural (function) type comparison, computing the pretty
representation of the type at hand appears high on performance profiles,
especially when type canonicalization wasn't really effective.

This patch adds a type_base::get_cached_pretty_representation() and a
function_type::get_cached_name() to cache the pretty representation of
a type, as well as the function type name.  This is way, the type
representation is computed just once and stored into a cache.
subsequent invocations of the function just look into the cache
instead of computing the representation again.

Note that we do this only for non-canonicalized types because these
types can still be modified, and so caching the representation of a
type that might be changed (and thus see its representation change)
leads to issue.  So the representation of non-canonicalized types is
not cached.

	* include/abg-ir.h (type_base::get_cached_pretty_representation):
	Declare new function.
	(function_type::get_cached_name): Likewise.
	* src/abg-ir.cc (get_method_type_name): Use the new
	type_base::get_cached_pretty_representation function.
	(type_base::priv::{internal_cached_repr_, cached_repr_}): Add new
	data members.
	(function_type::priv::{internal_cached_name_, cached_name_}):
	Likewise.
	(type_base::get_cached_pretty_representation): Define new
	function.
	(function_type::get_cached_name): Likewise.
	(type_base::get_canonical_type_for): Call
	type_base::get_cached_pretty_representation here, so the internal
	representation is cached right before canonicalization.
	(function_type::{mark_as_being_compared, unmark_as_being_compared,
	comparison_started}): Uset he new type_base::get_cached_name to
	speed up function type name retrieval.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 21:00:54 +01:00
Dodji Seketeli
b49119584b Add missing deep comparison operators for {function, method}_decl_sptr
It turned out we were missing deep comparison operators for smart
pointers to function_decl and method_decl.  Because of coming patches
that compare virtual member functions as part of comparing classes, we
need these deep comparison operators.

	* include/abg-ir.h (operator==): Declare two new overloads for
	function_decl_sptr an method_decl_sptr.
	* src/abg-ir.cc (operator==): Define two new overloads for
	function_decl_sptr an method_decl_sptr.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 21:00:54 +01:00
Dodji Seketeli
0af65e6364 Fix performance regression while analyzing libjvm.so
abidiff libjvm.so libjvm.so is taking forever in the master branch
these days.  At some point it was taking ~ 15 minutes and 15GB of RAM
on a non-optimized build.

Profiling of CPU usage showed that sorting virtual member
functions of a class whenever a new virtual member function is added
was the hot spot.

This patch now sorts virtual member functions once right after the
type was canonicalized.  The patch adds a virtual function
type_base::on_canonical_type_set() that is invoked right after the
canonical type is set for a given type.  class_decl gets its own
version of that virtual function: class_decl::on_canonical_type_set.
In that function, the patch does sort the virtual member functions of
the current class_decl.

Now with this patch, abidiff is still taking around 15 minutes but it
consumes less than 12GB of ram.  This means the memory consumption was
reduced by 20%.  abipkgdiff performs on 16:30 minutes and in less than
12GB of RAM as well.  All these times are measured on a non-optimized
build.

	* include/abg-ir.h ({type_base,
	class_decl}::on_canonical_type_set): Declare new virtual member
	function.
	* src/abg-ir.cc (type_base::on_canonical_type_set): Define new
	virtual member function that does nothing.
	(class_decl::on_canonical_type_set): Define new virtual member
	function that sorts the virtual member functions of class_decl.
	(canonicalize): Invoke type_base::on_canonical_type_set when the
	canonical type is set.
	(fixup_virtual_member_function): Don't sort virtual member
	functions here.
	* src/abg-dwarf-reader.cc (finish_member_function_reading): Do not
	sort virtual member functions here.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 19:25:36 +01:00
Dodji Seketeli
9dc07f5534 Update copyright notice for abg-fwd.h, abg-ir.h and test-abidiff.cc
* include/abg-fwd.h: Adjust copyright.
	* include/abg-ir.h: Likewise.
	* tests/test-abidiff.cc: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 15:36:20 +01:00
Dodji Seketeli
c495a5c5f0 Handle per translation unit and per corpus types maps
Today, whenever a type is added to its scope, a map that associates
the qualified type name to the type is updated.  There is only one
such map in a given ABI corpus.

So whenever a type is looked up from its name, it's that per-corpus
type map that is used.

This setup makes libabigail type lookup be tailored only for binaries
that respect the One Definition Rule of C++[1] (aka ODR) which
basically says that there should be only one type of a given name in
an ABI corpus.

It turns out that many binaries, especically C binaries, don't respect
the ODR.  So a type "struct foo" can be defined in a file a.c and
another *different* type "struct foo" can also be defined in b.c.
What a useful and safe feature! Not.

For those binaries, just having one type map doesn't work.  We need to
have one type map per translation unit, and one map per-corpus map.

This is the strategy implemented by this patch.

With this patch, whenever a type is added to its scope, a
per translation unit type map is updated.  The per corpus map is
updated as well.  If there are more than one type of a given name, the
entry in the per corpus type map for that type is left empty.

Type lookup now potentially becomes a two phases lookup.  Whenever a
type is looked up from its name, the per corpus type map is looked at
first.  If the type is not in that per corpus type map, then the per
translation unit type maps are lookup up, in sequence.

The patch thus re-visits the type maps updating and lookup routines to
adapt them to the new scheme.  The patch also updates the clients of
the type map updating and lookup code.

Note that this patch is part of a series of patches which aims to move
libabigails away from its ODR-centric organization to make it work
well also on binary where the ODR is not relevant.  As such, the patch
doesn't assure that "make check" passes.  To have "make check" pass,
you need to have all the patches of the series applied.

[1]: https://en.wikipedia.org/wiki/One_Definition_Rule

	* include/abg-fwd.h (lookup_type_in_corpus): Remove.  This is to
	be replaced by the new lookup_type below.
	(lookup_{basic, class, union, enum, typedef, qualified, pointer,
	reference, array, function, class_or_typedef,
	class_typedef_or_enum}_type):
	(lookup_class_type_through_scopes, lookup_type)
	(lookup_type_through_scopes, lookup_or_synthesize_fn_type)
	* src/abg-ir-priv.h (struct translation_unit::priv):  Move this
	private type here, from abg-ir.h.
	(synthesize_type_from_translation_unit): Declare new functions.
	* include/abg-ir.h (class type_maps): Define new type.
	(translation_unit::get_function_types): Remove.
	(translation_unit::get_types): Now return a type_maps.
	(translation_unit::get_live_fn_types): Declare new type.
	(class decl_base): Make canonicalize be a friend of this class.
	* src/abg-ir.cc (struct translation_unit::priv): Move this to
	abg-ir-priv.h
	(struct type_maps::priv): Define new type.
	(type_maps::{basic, class, union, enum, typedef, qualified,
	pointer, reference, array, function}_types): Define new accessors.
	(translation_unit::bind_function_type_life_time): Adjust.
	(translation_unit::get_function_types): Remove accessor.
	(translation_unit::get_types, get_live_fn_types): Define new
	accessors.
	(lookup_type_in_translation_unit)
	(lookup_class_type_in_translation_unit)
	(lookup_function_type_in_translation_unit)
	(synthesize_type_from_translation_unit)
	(synthesize_function_type_from_translation_unit)
	(lookup_class_type_in_translation_unit) Remove function
	definitions.
	(lookup_type_in_map): Define function template.
	(lookup_{basic, class, union, typedef, class_or_typedef,
	class_typedef_or_enum, qualified, pointer, reference, array,
	function}_type): Define functions.
	(lookup_function_type, lookup_type_through_scopes)
	(lookup_class_type_through_scopes)
	(lookup_basic_type_through_translation_units)
	(lookup_union_type_through_translation_units)
	(lookup_enum_type_through_translation_units)
	(lookup_class_type_through_translation_units)
	(lookup_typedef_type_through_translation_units)
	(lookup_qualified_type_through_translation_units)
	(lookup_pointer_type_through_translation_units)
	(lookup_reference_type_through_translation_units)
	(lookup_array_type_through_translation_units)
	(lookup_function_type_through_translation_units)
	(lookup_type_through_translation_units)
	(lookup_or_synthesize_fn_type, lookup_type): Likewise.
	(maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map<class_decl>)
	(maybe_update_types_lookup_map<function_type>): Define function
	template, specilizations and functions.
	(synthesize_type_from_translation_unit)
	(synthesize_function_type_from_translation_unit): Define
	functions.
	* include/abg-corpus.h (corpus::get_types): Declare new accessor.
	* src/abg-corpus.cc (corpus::priv::get_types): Define new
	accessor.
	(corpus::get_types): Likewise.
	(lookup_type_in_corpus, lookup_class_type_in_corpus)
	(lookup_type_in_corpus, lookup_function_type_in_corpus)
	(maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map<class_decl>)
	(maybe_update_types_lookup_map<function_type>): Remove.
	(lookup_{basic, class, union, enum, typedef, qualified, pointer,
	reference, array, function, class_or_typedef,
	class_typedef_or_enum}_type): Likewise.
	* src/abg-corpus-priv.h (corpus::priv::{basic, class, union,
	typedef, qualified, pointer, reference, array, function}_types):
	Remove these data members.
	(corpus::priv::get_scopes): Remove member function.
	(corpus::priv::get_{basic, class, union, enum, typedef, qualified,
	pointer, reference, array, function}_types): Remove member
	function declarations.
	(corpus::priv::types_): New data member.
	(corpus::priv::get_types): Declare new member function.
	(lookup_{basic, class, enum, typedef, class_or_typedef, qualified,
	pointer, reference, array, function}_type): Declare new functions.
	* src/abg-dwarf-reader.cc
	(read_context::resolve_declaration_only_classes)
	(build_translation_unit_and_add_to_ir): Adjust use of
	lookup_class_type.
	* src/abg-reader.cc (read_context::type_is_from_translation_unit):
	Adjust to the use of lookup_function_type_in_translation_unit that
	got renamed into lookup_function_type.
	* src/abg-writer.cc (type_ptr_cmp::operator()): New operator
	implementation.
	(read_context::sort_type): Add new overloads.
	(write_translation_unit): Adjust to get the function types from
	the new translation_unit::get_live_fn_types and sort them.
	* tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust
	to use the new lookup_or_synthesize_fn_type, in lieu of
	lookup_function_type_in_corpus.  Adjust to use lookup_type in lieu
	of lookup_type_in_corpus.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:18:33 +01:00
Dodji Seketeli
bca3f9d163 Make abg-fwd.h use *_sptr typedefs
Until now, the abg-fwd.h where the necessary forward generic
declarations where put didn't contain the convenience typedefs of the
form foo_sptr that designate a shared pointer to type foo.

This patch moves these convenience typedefs as well as the missing
forward declarations from abg-ir.h to abg-fwd.h.  The patch also
adjusts the function declarations in abg-fwd.h to make them use these
convenience typedefs.

	* include/abg-ir.h: Move convience typedef declarations and some
	necessary forward declarations to ...
	* include/abg-fwd.h: ... here.
	(is_enum_type, is_var_decl): Take a pointer to type_or_decl_base.
	(lookup_type_in_scope): Return a type_base_sptr.
	(lookup_type_through_scopes): Introduce this to later replace the
	overload of lookup_type_in_translation_unit that takes a list of
	strings.
	(lookup_type_in_scope): Return a type_base_sptr, not a
	decl_base_sptr.
	* src/abg-ir.cc (lookup_type_in_scope, lookup_node_in_scope)
	(lookup_var_decl_in_scope): Adjust.
	(is_enum_type, is_var_decl): Take a pointer to type_or_decl_base.
	(lookup_node_in_scope): Return a type_or_decl_base_sptr.
	(lookup_type_in_scope): Return a type_base_sptr.
	(lookup_node_in_translation_unit): Return a
	type_or_decl_base_sptr.
	(lookup_type_through_scopes): Replace
	lookup_type_in_translation_unit.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-05 12:18:32 +01:00
Dodji Seketeli
5ed0e40bfd Bug 20887 - Show relative change of offsets
Until now, an offset change is reported by showing the old and new
offsets of the data member that changed.

This patch adds the string "(by +N bits)" with 'N' being the number of
bits by which the offset of the data member was increased, or "(by -N
bits) if the offset of the data member was decreased of N bits.

The patch also emits a string that says "size hasn't changed" if the
size of the structure did not change.

This can be disabled by a new --no-show-relative-offset-changes
option.

	* doc/manuals/abidiff.rst: Document the new
	--no-show-relative-offset-changes.
	* doc/manuals/abipkgdiff.rst: Likewise.
	* include/abg-comparison.h
	(diff_context::show_relative_offset_changes): New accessors.
	* include/abg-ir.h ({set,get}_data_member_offset): Return uint64_t
	instead of the less portable size_t.
	* src/abg-comparison.cc
	(diff_context::priv::show_relative_offset_changes_): New data
	member.
	(dif_context::show_relative_offset_changes): Define accessor.
	(maybe_show_relative_offset_change): Define new function.
	(represent): In the overload for var_diff, call the new
	maybe_show_relative_offset_change.
	(report_size_and_alignment_changes):  If the size of the type
	didn't change then say it now.
	* src/abg-ir.cc (set_data_member_offset, get_data_member_offset):
	Take or return a uint64_t instead of a size_t.
	* tools/abidiff.cc (options::show_relative_offset_changes): New
	data member.
	(options::options): Initialize it.
	(display_usage): Display help string for the new
	--no-show-relative-offset-changes.
	(parse_command_line): Parse the new
	--no-show-relative-offset-changes options.
	(set_diff_context_from_opts): Set the
	"show-relative-offset-changes" flag according to the new option.n
	* tools/abipkgdiff.cc (options::show_relative_offset_changes): New
	data member.
	(options::options): Initialize it.
	(display_usage): Add help string for the new
	--no-show-relative-offset-changes option.
	(set_diff_context_from_opts): Set the
	"show-relative-offset-changes" flag according to the new option.
	(parse_command_line): Parse the new command line option.
	* tests/data/test-diff-dwarf/test40-report-0.txt: Add new
	reference output.
	* tests/data/test-diff-dwarf/test40-v0.c: Source code of the first
	test binary.
	* tests/data/test-diff-dwarf/test40-v1.c: Source code of the
	second test binay.
	* tests/data/test-diff-dwarf/libtest40-v0.so: New first test binary.
	* tests/data/test-diff-dwarf/libtest40-v1.so: New second test binary.
	* tests/test-diff-dwarf.cc (in_out_spec): Add the new test
	binaries above to the set of binaries that are compared.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.
	* tests/data/test-abicompat/test7-fn-changed-report-0.txt: Adjust.
	* tests/data/test-abidiff/test-PR18791-report0.txt: Likewise.
	* tests/data/test-abidiff/test-enum0-report.txt: Likewise.
	* tests/data/test-abidiff/test-enum1-report.txt: Likewise.
	* tests/data/test-abidiff/test-struct1-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test0-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test1-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test10-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test11-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test13-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test15-enum-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test27-local-base-diff-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test32-fnptr-changes-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test33-fnref-changes-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test38-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test4-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test5-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test6-report.txt: Likewise.
	* tests/data/test-diff-dwarf/test8-report.txt: Likewise.
	* tests/data/test-diff-filter/test0-report.txt: Likewise.
	* tests/data/test-diff-filter/test01-report.txt: Likewise.
	* tests/data/test-diff-filter/test1-report.txt: Likewise.
	* tests/data/test-diff-filter/test13-report.txt: Likewise.
	* tests/data/test-diff-filter/test16-report-2.txt: Likewise.
	* tests/data/test-diff-filter/test16-report.txt: Likewise.
	* tests/data/test-diff-filter/test17-0-report.txt: Likewise.
	* tests/data/test-diff-filter/test17-1-report.txt: Likewise.
	* tests/data/test-diff-filter/test18-report.txt: Likewise.
	* tests/data/test-diff-filter/test19-enum-report-1.txt: Likewise.
	* tests/data/test-diff-filter/test2-report.txt: Likewise.
	* tests/data/test-diff-filter/test23-redundant-fn-parm-change-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test24-compatible-vars-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test25-cyclic-type-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test25-cyclic-type-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test26-qualified-redundant-node-report-0.t:
	Likewise.xt
	* tests/data/test-diff-filter/test26-qualified-redundant-node-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-1.txt:
	Likewise.
	* tests/data/test-diff-filter/test27-redundant-and-filtered-children-nodes-report-2.txt:
	Likewise.
	* tests/data/test-diff-filter/test29-finer-redundancy-marking-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test3-report.txt: Likewise.
	* 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-diff-filter/test31-pr18535-libstdc++-report-0.txt:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt:
	Likewise.
	* tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt: Likewise.
	* tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt: Likewise.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-5.txt: Likewise.
	* tests/data/test-diff-suppr/test0-type-suppr-report-7.txt: Likewise.
	* tests/data/test-diff-suppr/test1-typedef-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test1-typedef-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test10-changed-parm-c-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test2-struct-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test23-alias-filter-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test23-alias-filter-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test3-struct-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test3-struct-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test3-struct-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test30-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test4-local-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test4-local-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test5-fn-suppr-report-5.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-0-1.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test6-fn-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-0.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-1.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-2.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-3.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-4.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-7.txt: Likewise.
	* tests/data/test-diff-suppr/test7-var-suppr-report-8.txt: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-12-02 21:29:28 +01:00
Dodji Seketeli
72f50a16ce Very light speed improvements
When comparing of two kernel trees showed that for huge changesets
involving highly recursive types, leaf functions used by the
categorization code dominate the performance profile.

This patch introduces some changes that help gain around 30 seconds
(out of 14 minutes) on a non-optimized build, when comparing 4.7 nd
4.8 fedora kernels (between fedora 24 and 26).

	* include/abg-comp-filter.h (has_harmless_name_change): Pass smart
	pointers by reference.
	* src/abg-comp-filter.cc (access_changed)
	(function_name_changed_but_not_symbol)
	(non_static_data_member_type_size_changed)
	(static_data_member_type_size_changed, is_compatible_change)
	(decl_name_changed, has_harmless_name_change):  Pass smart
	pointers by reference.
	* include/abg-ir.h (decl_base::set_context_rel): Take a bare
	pointer, not a smart pointer.
	* src/abg-ir.cc (decl_base::priv::context_): Make this data member
	be a naked pointer, not a smart pointer.
	(decl_base::priv::priv): Initialize it.
	(decl_base::priv::~priv): New constructor.
	(decl_base::{get_context_rel, set_scope}): Adjust.
	(class_decl::method_decl::{method_decl, set_scope}): Likewise.
	(equals): In the overload for var_decl, compare the type of the
	var first as that might be faster (to detect var_decls with
	different types) in the general case where types are
	canonicalized.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 17:08:19 +01:00
Dodji Seketeli
e861bd3368 Introduce on-the-fly type canonicalization
During canonicalization of a type T, when T is structurally compared
to an already canonicalized type C, it can happen that
non-canonicalized sub-types of T are structurally compared again and
again to canonicalized sub-types of C.

This patch introduces a new optimization or those cases: on-the-fly
type canonicalized.

That means, if a not-yet-canonicalized sub-type S of the type T being
canonicalized structurally compares equal to a canonicalized sub-type,
then the canonical type of S is said to be the canonical type of the
canonicalized sub-type.  So sub-type S is canonicalized, on-the-fly,
during canonicalization of type T.

This considerably speeds up the canonicalization process while doing
"abidiff vmlinux vmlinux".  It goes from taking forever to taking 45
seconds on a non-optimized build.

	* include/abg-ir.h (environment::do_on_the_fly_canonicalization):
	Declare new member functions.
	({type_base, function_type}::priv_): Make this public so that
	static non-member functions defined in abg-ir.cc can access it.
	* src/abg-ir.cc
	(environment::priv::do_on_the_fly_canonicalization_): New data
	member.
	(environment::priv::priv): Initialize it.
	(environment::do_on_the_fly_canonicalization): Define new member
	functions.
	(type_base::get_canonical_type_for): Trigger on-the-fly
	canonicalization during comparison of the type being canonicalized
	and an already canonicalized type.
	(types_are_being_compared, maybe_propagate_canonical_type): Define
	new static functions.
	(equals): In overloads for class_decl and function_type, call
	maybe_propagate_canonical_type when the two types compare equal.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt:
	Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 17:07:28 +01:00
Dodji Seketeli
bd3fe4c748 Fix pretty representation of array types
It turned out we were wrongly emitting the pretty representation of
array types in two cases:

  1/ in case of qualified array types: a const array of string type
  was being pretty-represented as: "const string[]" instead of
  "string[] const".

  2/ in case of array with an empty sub-range DIE; that is a sub-range
  DIE with no attribute at all.  For instance an array of char with an
  empty sub-range DIE was being represented as: "char", instead of
  "char[]".

This patch fixes 1 and 2.  It also updates numerous test reference
output files.

	* include/abg-ir.h (array_type_def::is_infinite): Fix indentation.
	* src/abg-ir.cc (qualified_type_def::build_name): An empty set of
	sub-ranges for a vector is represented by "[]".
	(array_type_def::is_infinite): If a vector has no sub-range, that
	means it has an infinite size.  Adjust comment.
	* tests/data/test-diff-filter/test33-report-0.txt: Adjust.
	* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Adjust.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 16:51:19 +01:00
Dodji Seketeli
3981244c9d Support naming typedef and use them to speed up type canonicalization
There is a common C idiom in which an anonymous struct is named using
a typedef:

    typedef struct {int member;} anonymous_struct_type;

The typedef name "anonymous_struct_type" becomes the name of the
otherwise anonymous struct.  That is what a naming typedef is.

So, the nice thing about naming typedefs is that an anonymous class
type suddenly becomes non anymous.  So that type becomes eligible to
the ODR-based optimization during type canonicalization.  That speeds
up type canonicalization, at least for 'abidw'.

This patch represents naming typedefs for class_decl types in the
internal representation.  The patch also changes the meaning of an
anonymous class.  Whenever such a class becomes named by a typedef,
the class is not considered anonymous anymore, at least for the
purpose of type canonicalization.

	* include/abg-ir.h (typedef_decl_wptr): New typedef.
	(class_decl::{g,s}et_naming_typedef): Declare new member
	functions.
	* src/abg-dwarf-reader.cc (build_typedef_type): When the
	underlying type of a typedef is an anonymous class, the class type
	is said to have a naming typedef.
	* src/abg-ir.cc (is_anonymous_type):  An anonymous class that has
	a naming typedef is said to not be anonymous anymore.
	(class_decl::priv::naming_typedef): New data member.
	(class_decl::{g,s}et_naming_typedef): Define new member functions.
	(class_decl::get_pretty_representation): When called for internal
	purposes (e.g, for type canonicalization) compute the pretty
	representation of the class by using its typedef name, when class
	is anonymous and has a naming typedef.
	* src/abg-reader.cc (build_class_decl): Read the new
	"naming-typedef-id" attribute.
	* src/abg-writer.cc (write_naming_typedef): New function.
	(write_class_decl_opening_tag): Use the new write_naming_typedef
	function.
	* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
	* 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/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-29 16:44:06 +01:00
Dodji Seketeli
cfaa7d42b6 Implement de-duplication for types and decls at DWARF loading time
Many types and decls are redefined in every translation unit that make
up an ELF binary.  This patch detects that a DIE represents a type or
decl that has already been defined in the current corpus and so will
not create a new internal representation for it.

The patch defines facilities to build the pretty representation of a
type or decl.  It's by looking at the pretty representation of a DIE
that the patch detects that a different DIE has already defined the
same type or decl.

The patch also fixes detection of the const-ness of member functions
as there were many cases where const member functions were not
recognized as const.  This fix makes it so that the pretty
representation of the DIE of said member functions match the pretty
representation of their internal representation, as far as the
const-ness is concerned.

One bit of infrastructure change that is used by the const-ness fix is
that method_type now carries const-ness.  So a method_decl that has a
const method_type is going to be const itself.

	* include/abg-ir.h (method_type::priv_): Introduce new pimpl
	pointer here.
	(method_type::class_type_): Move this into the pimpl idiom.
	(method_type::method_type): Take a new is_const flag.
	(method_type::get_class_type): Make this method out-of-line.
	(method_type::{s,g}et_is_const): Declare new member functions.
	(get_method_type_name): Declare this function as a friend of
	the method_type type.
	* src/abg-dwarf-reader.cc: Include the new abg-ir-priv.h and
	abg-corpus-priv.h.
	(typedef die_tu_map_type): Fix comment.
	(typedef die_istring_map_type): New typedef.
	(class read_context::die_source_dependant_container_set): New
	class template.
	(read_context::{die_qualified_name_maps_, die_pretty_repr_maps_,
	die_pretty_type_repr_maps_}): Define new data members.
	(read_context::{get_die_qualified_name, get_die_qualified_name,
	get_die_qualified_type_name, get_die_pretty_type_representation,
	get_die_pretty_representation, lookup_type_artifact_from_die,
	lookup_artifact_from_die, lookup_artifact_from_die_representation,
	associate_die_to_artifact_by_repr,
	associate_die_to_artifact_by_repr_internal,
	lookup_type_from_die}): Define new member functions.
	(read_context::lookup_type_from_die_offset): Fix comment.
	(get_parent_die, get_scope_die, die_is_decl)
	(die_is_namespace, die_is_unspecified, die_is_void_type)
	(die_is_pointer_type, die_is_reference_type)
	(die_is_pointer_or_reference_type, die_is_class_type)
	(die_has_object_pointer, die_this_pointer_from_object_pointer)
	(die_this_pointer_is_const, is_decl_tag)
	(die_object_pointer_is_for_const_method, die_is_at_class_scope)
	(die_name, die_qualified_type_name, die_qualified_decl_name)
	(die_qualified_name, die_qualified_type_name_empty)
	(die_return_and_parm_names_from_fn_type_die)
	(die_function_signature, die_peel_qual_ptr)
	(die_function_type_is_method_type, die_pretty_print_type)
	(die_pretty_print_decl, die_pretty_print)
	(build_subranges_from_array_type_die)
	(build_or_get_fn_decl_if_not_suppressed)
	(lookup_class_or_typedef_type)
	(lookup_class_typedef_or_enum_type_from_corpus)
	(is_function_for_die_a_member_of_class)
	(add_or_update_member_function): Define new static functions.
	(read_context::associate_die_to_decl): Call
	associate_die_to_artifact_by_repr.
	(read_context::{associate_die_to_type,
	schedule_type_for_late_canonicalization}): Take just one "die"
	parameter rather than taking a die offset and a die source; adjust
	accordingly.
	(maybe_canonicalize_type): Likewise.
	(finish_member_function_reading): Take a const reference to
	function_decl_sptr.
	(die_loc_and_name): Use the new die_name function.
	(die_is_type): Rename is_type_die into this.
	(build_type_decl): Take a new "where_offset" parameter.  Adjust.
	If a type of the same name as the one for the current DIE is is
	already present, do not create a new type; just return the
	already-existing one.
	(build_enum_type): Take a new "where_offset" parameter.  Adjust.
	(finish_member_function_reading): Pass two smart pointers by const
	reference.  Assert that the type of the member function is a
	method_type.  Some light cleanups.
	(add_or_update_class_type): Rename build_class_type_and_add_to_ir.
	If a DIE defining the same class has already been seen, then
	return that class; don't construct any other internal
	representation for the same class.  Better handle the updating of
	member data and functions.  Do not duplicate member types.
	(build_qualified_type, build_pointer_type_def)
	(build_reference_type): Support de-duplication here.
	(build_function_type): Likewise.  Support detection and building
	of method type.  This also supports *const* method type building.
	(build_array_type): Use the new
	build_subranges_from_array_type_die.
	(build_type_decl): Cleanup logic.
	(build_or_get_var_decl_if_not_suppressed): Renamed
	build_var_decl_if_not_suppressed into this.  Perform
	de-duplication for data members.
	(build_function_decl): Don't set an empty source location.  If the
	function type cannot be constructed, do not construct the function
	decl either.  Adjust.
	(build_ir_node_from_die): Adjust.  When building a function for a
	DW_TAG_subroutine_type DIE, use the new
	build_or_get_fn_decl_if_not_suppressed.
	* src/abg-ir.cc (translation_unit::bind_function_type_life_time):
	Fix comment.
	(strip_typedef): Adjust.
	(qualified_type_def::build_name): Set the prefix name of a the
	name of a noop qualifier to "noop-qual", just like what is done in
	the new die_qualified_name function.
	(struct method_type::priv): New priv type for the method_type
	class.
	(method_type::method_type): Take a new 'is_const' parameter.
	Adjust as the method_type is now pimpl'ed.
	(method_type::{get_class_type, set_is_const, get_is_const}):
	Define new member functions.
	(function_decl::get_pretty_representation_of_declarator): Better
	detecter of const-ness.
	(class_decl::insert_member_decl):  Better setting of the
	const-ness.
	(class_decl::method_decl::method_decl): Adjust.  Deduce the
	const-ness of the method_decl from the const-ness of its
	method_type.
	(copy_member_function): Adjust.
	(set_member_is_static): Do not assume a non-nil scope anymore
	because member_decl can now be scope-less, at least for a little
	while.
	* src/abg-reader.cc (push_decl_to_current_scope): Adjust.
	(build_function_decl): Style adjustment.  Adjust for method_type
	const-ness changes.
	(build_function_type): Likewise.  Also, support the new
	"method-class-id" property that flags a function type as being a
	method type.
	* src/abg-writer.cc (write_function_decl): Style fixes.
	(write_function_type): Likewise.  Emit a new "method-class-id"
	property for function type that is actually a method type.  That
	property's value is the id of the class of the method type.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi: Adjust.
	* tests/data/test-diff-dwarf/test0-report.txt: Adjust.
	* tests/data/test-diff-filter/test0-report.txt: Adjust.
	* tests/data/test-diff-filter/test01-report.txt: Adjust.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Adjust.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Adjust.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Adjust.
	* tests/data/test-diff-pkg/libICE-1.0.6-1.el6.x86_64.rpm--libICE-1.0.9-2.el7.x86_64.rpm-report-0.txt: Adjust.
	* tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Adjust.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-0.txt: Adjust.
	* tests/data/test-diff-pkg/tbb-4.1-9.20130314.fc22.x86_64--tbb-4.3-3.20141204.fc23.x86_64-report-1.txt: Adjust.
	* tests/data/test-read-dwarf/libtest23.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Adjust.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Adjust.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Adjust.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Adjust.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust.
	* tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 16:16:56 +01:00
Dodji Seketeli
ccdc44b3eb Setup per-corpus type maps indexed by type names
This patch creates per-corpus maps that associate, for a certain kind
of type, the fully qualified name of the type to the type.

So there is a map for class_decl, one for enum_type_decl, one for
type_decl, etc.

These maps are populated when a new type is added to its scope.

The patch defines overloads of the function
maybe_update_types_lookup_map() that update the right map, depending
on the kind of type we are looking at.

Note that there also is a map in each class that associates a
signature string to a member functions.  This is so that member
functions of a given class can be looked up by signature.

This is so that looking up a type becomes now much faster than having
to walk all the translation units of a corpus to find one.

Note that this patch is specifically part of the series of patches
that implements types and declarations de-duplication while reading
DWARF information.

The patch might slightly change the output of abi serialization or
comparison so it needs some adjustments of some test reference files.
That adjustment is not done here.  Rather, it's done at once in
another patch of the set.

	* include/abg-corpus.h (corpus::priv_): Make this public so that
	functions from outside of the class can access it.  These
	functions are meant to be used only by code that is *inside*
	libabigail.so, though.
	* src/abg-corpus-priv.h: New file.
	* src/abg-corpus.cc: Include the new abg-corpus-priv.h file.
	(struct regex_t_deleter): Move this to abg-sptr-utils.h.
	(build_sptr<regex_t>): Move the declaration of this function
	template specialization to abg-sptr-utils.h and its definition to
	abg-sptr-utils.cc.
	(typedef regex_t_sptrs_type, typedef str_var_ptr_map_type)
	(struct corpus::exported_decls_builder::priv, struct
	corpus::priv): Move these declarations to the new
	abg-corpus-priv.h.
	(maybe_update_types_lookup_map): Define overloads of this (one per
	kind of type).
	(lookup_{basic, class, enum, typedef, class_or_typedef,
	class_typedef_or_enum, qualified, pointer, reference, array,
	function}_type): Define new functions.
	* include/abg-ir.h (typedef istring_type_base_wptr_map_type)
	(typedef istring_type_or_decl_base_sptr_map_type): Declare new
	typedefs.
	(class_decl::find_member_function_from_signature): Declare new
	member function.
	* src/abg-ir.cc: Include the new abg-corpus-priv.h file.
	(maybe_update_types_lookup_map): Remove this initial function.
	There are now new overloads in abg-corpus.cc for it.
	(scope_decl::{add_member_decl, insert_member_decl}): Adjust.
	(class_decl::{set_is_declaration_only, find_member_function,
	add_member_function}): Adjust.
	(class_decl::find_member_function_from_signature): Define new
	member function.
	* include/abg-sptr-utils.h (struct regex_t_deleter): Declare new
	type.
	(build_sptr<regex_t>): New build function template
	specializations.
	* src/abg-sptr-utils.cc: New file.
	* src/Makefile.am: Add src/abg-sptr-utils.cc and
	src/abg-corpus-priv.h to the build system.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 16:16:43 +01:00
Dodji Seketeli
1b94d60780 Allow pretty printing function decls for internal purposes
It appears that function_decl::get_pretty_representation doesn't make
the difference between internal and non-internal purposes.  This patch
fixes that by making the helper
get_pretty_representation_of_declarator() take an "internal" flag and
calls that.

	* include/abg-ir.h
	(function_decl::get_pretty_representation_of_declarator): Take an
	"internal" flag.
	* src/abg-ir.cc
	(function_decl::get_pretty_representation_of_declarator): Take an
	"internal" flag.
	(function_decl::get_pretty_representation): Pass the "internal"
	flag to the function
	function_decl::get_pretty_representation_of_declarator.
	(function_decl::parameter::get_type_name):  Better handle variadic
	parameter type.
	(function_decl::parameter::get_type_pretty_representation):
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-29 16:16:31 +01:00
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
Dodji Seketeli
ff0b07e711 Factorize out string representation of array_type_def::subrange_type
As we are going to need to print names of array types from DIEs
directly, we'll need to represent names of subranges.

This patch factorizes the string representation of the
array_type_def::subrange_type type.

	* src/abg-ir.cc (array_type_def::subrange_type::{as_string,
	vector_as_string}): Define methods.
	(array_type_def::get_subrange_representation): Use the new
	vector_as_string method.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-03 15:13:38 +01:00