mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-20 00:40:05 +00:00
65318dacfb
126 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
Dodji Seketeli
|
65318dacfb |
[xml-writter] Avoid using RTTI when dynamically hashing types
When we dynamically hash types in the abixml writter, we use hash_type_or_decl. This function uses runtime type identification to determine if the (type) artifact is a decl or a type, and based on that, choose how to compute its hash value. Profiling shows that using the RTTI in hash_type_or_decl at this point is a hotspot. Because we know that the type ABI is a *type*, we obviously can avoid using RTTI there. The patch thus implements a hash_type function, and uses that in the xml writter. Emitting the abixml output is faster with this patch. * include/abg-fwd.h (hash_type): Declare new function. * src/abg-ir.cc (hash_type): Define new function. * src/abg-writer.cc (type_hasher::operator()): Use the new hash_type rather than the old hash_type_or_decl. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
c940a229c9 |
Implement a poor-man's RTTI for performance
Profiling showed that a number of use of dynamic_cast are a speed bottleneck. This patch implements a poor-man's RTTI that allows us to implement a form of dynamic_cast that is specific to the types of the internal reprenstation that are in the namespace abigail::ir. It speeds up things greatly. Basically, the base type of all ABI artifacts (abigail::ir::type_or_decl_base) now contains three new data members. The first one contains a bitmap that identifies the type of artifact. The second one contains a pointer to the dynamic type sub-object of the current instance of the artifact. The last one contains either a pointer to the type_base sub-object of the current instance of ABI artifact if it's a type, or a pointer to the type_decl sub-object of the current instance. Together these three data members allow the patch to implement the abigail::ir::{is_type(), is_decl(), is_<type_kind>_type} functions that we need to make the code base noticeably faster when using abidw on a big vmlinux binary. * include/abg-fwd.h (is_type_decl): Replace the overloads that takes a type_base* and/or a decl_base* by one that takes a type_or_decl_base*. * include/abg-ir.h (type_or_decl_base::type_or_decl_kind): Define new enum. (type_or_decl_base::{kind, runtime_type_instance, type_or_decl_base_pointer}): Declare new accessors. (operator{|,|=,&,&=): Declare new operators for the new type_or_decl_base::type_or_decl_kind enum. (global_scope::global_scope): Move the definition of this constructor to ... * src/abg-ir.cc (global_scope::global_scope): ... here. (type_or_decl_base::priv::{kind_, rtti_, type_or_decl_ptr_}): Add new data members. (type_or_decl_base::priv::priv): Take a type_or_decl_base::type_or_decl_kind enum. (type_or_decl_base::priv::kind): Define new accessors. (operator{|,|=,&,&=): Define new operators for the new type_or_decl_base::type_or_decl_kind enum. (type_or_decl_base::type_or_decl_base): Take a type_or_decl_base::type_or_decl_kind enum. (type_or_decl_base::{kind, runtime_type_instance, type_or_decl_base_pointer}): Define new accessors. (decl_base::decl_base, scope_decl::scope_decl) (type_base::type_base, scope_type_decl::scope_type_decl) (class_or_union::class_or_union) : Adjust to set the runtime type identifier of the instances of these types. (global_scope::global_scope, type_decl::type_decl) (qualified_type_def::qualified_type_def) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def array_type_def::subrange_type::subrange_type) (array_type_def::array_type_def, enum_type_decl::enum_type_decl) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter, method_decl::method_decl) (class_decl::class_decl, class_decl::base_spec::base_spec) (union_decl::union_decl, template_decl::template_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Likewise and call runtime_type_instance() here to set the runtime type instance pointers of the current instance. (is_decl, is_type, is_class_type, is_pointer_type): Adjust to use the new poor-man's rtti machinery. (is_type_decl): Replace the overloads that takes a type_base* and/or a decl_base* by one that takes a type_or_decl_base*. (pointer_type_def::operator==, class_decl::operator==): Use the poor-man's rtti machinery to replace dynamic_cast. hash_type_or_decl: Replace dynamic_cast<const type_base> by is_type() and dynamic_cast<const decl_base*> by is_decl(). Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
2209df1b90 |
Make abidiff --harmless show harmless changes in unions
Since the previous commit filters out harmless changes inside unions, this one allows those changes to be reported whenever the user runs abidiff with the --harmless option. The patch just displays the "before" and "after" of the union because some of the harmless changes are not tracked anymore. Because we want to display the before and after of the union we use the function get_class_or_union_flat_representation. The patch adds a "qualified_name" boolean parameter to that function so that we can choose to display union members names in a non-qualified fashion, which is the natural way of displaying those names in the context of a union (or class) representation. Because get_class_or_union_flat_representation uses type_or_decl_base::get_pretty_representation, the patch has also added a "qualified_name" boolean parameter to that function so that we can choose to display names in a non-qualified manner. * include/abg-fwd.h (get_class_or_union_flat_representation): Add a "qualified_name" boolean parameter. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, namespace_decl, array_type_def::subrange_type, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl, union_decl}::get_pretty_representation): Likewise. * src/abg-ir.cc ({type_or_decl_base, decl_base, type_decl, namespace_decl, array_type_def::subrange_type, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl, union_decl, }::get_pretty_representation): Adjust the code to emit qualified or non-qualified names depending on the new "qualified_name" boolean parameter. (get_class_or_union_flat_representation): Likewise. * src/abg-default-reporter.cc (default_reporter::report): Use get_class_or_union_flat_representation with the new "qualified_name" boolean set to false. * tests/data/test-diff-dwarf/test38-union-report-0.txt: Adjust. * tests/test-diff-filter.cc (in_out_specs): Run the test harness on test-PR24731-v{0,1}.o make abidiff use the --harmless option. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Matthias Maennich
|
1e67db0797 |
abg-writer: drop deprecated API
Drop the deprecated overloads for write_translation_unit, write_corpus, write_corpus_group. Also remove the deprecation facilities as they are not used anymore. * include/abg-fwd.h (ABG_DEPRECATED): Remove this macro. * include/abg-writer.h (write_translation_unit, write_corpus) (write_corpus_group): Drop the deprecated overloads of these declarations. * src/abg-writer.cc (write_translation_unit, write_corpus) (write_corpus_group): Drop the deprecated overloads of these definitions. Signed-off-by: Matthias Maennich <maennich@google.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Matthias Maennich
|
b0f123c18e |
Add deprecation facilities
Add the macro 'ABG_DEPRECATED' to mark APIs as to be removed in a next major release. APIs marked with that flag are supposed to work as before, but might come with downsides. E.g. they could perform worse or provide only limited functionality. All deprecated functions shall come with a hint to equivalent functionality within the non-deprecated part of the API. * include/abg-fwd.h: Introduce deprecation macro ABG_DEPRECATED Signed-off-by: Matthias Maennich <maennich@google.com> |
||
Dodji Seketeli
|
04d61a726d |
Don't try to de-duplicate all anonymous struct DIEs
Trying to de-duplicate anonymous struct DIEs can lead to subtle issues, because there can be two different naming typedefs designating two anonymous structs that are equivalent, in the same translation unit. In that case, de-duplicating the two leaf anonymous structs DIEs leads to non-resolvable conflict. This patch avoids de-duplicating anonymous structs DIEs and rather de-duplicates (naming) typedefs. * include/abg-fwd.h (is_typedef): Remove the overloads for type_base_sptr and decl_base_sptr. Replace those with an overload for type_or_decl_base_sptr. * src/abg-ir.cc (is_typedef): Do the same for the definitions. * src/abg-dwarf-reader.cc (add_or_update_class_type) (add_or_update_union_type): Do not de-duplicate anonymous struct/union DIEs. (build_typedef_type): Try to de-duplicate typedefs DIEs. * tests/data/test-annotate/test17-pr19027.so.abi: Adjust. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise * tests/data/test-annotate/test21-pr19092.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/test16-pr18904.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/test9-pr18818-clang.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Matthias Maennich via libabigail
|
87bbc09b9e |
abg-fwd.h: fix mismatched tags for ir_node_visitor
ir_node_visitor is defined as `class` in include/abg-ir.h:4429 and should therefore also be forward-declared as such. * include/abg-fwd.h: forward-declare ir_node_visitor as class Signed-off-by: Matthias Maennich <maennich@google.com> |
||
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> |
||
Dodji Seketeli
|
ad8732316a |
Bug 23044 - Assertions with side effects
There are lots of spots in libabigail's source code where the argument of the assert() call does have side effects. This is a problem because when the code is compiled with the NDEBUG macro defined, the assert call does nothing, so the side effects of its argument are then suppressed, changing the behaviour of the program. To handle this issue, this patch introduces the ABG_ASSERT macro which is a wrapper around the assert call that enable the use of side effects in its argument. The patch now uses that ABG_ASSERT macro instead of using the assert call directly. The patch also makes it so that the configure option accepts the --disable-assert option so that the user can build libabigail with the NDEBUG macro defined. Tested by running the testsuite with and without the --disable-assert option to configure. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
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> |
||
Dodji Seketeli
|
caa100603e |
Bug 23708 - categorize void* to pointer change as harmless
Changing a void* pointer into another pointer of the same size is a change that is harmless in terms of data layout. This commit thus categorizes such a change as harmless. * include/abg-comparison.h (VOID_PTR_TO_PTR_CHANGE_CATEGORY): New enumerator in the diff_category enum. Also, adjust the EVERYTHING_CATEGORY enumerator. * include/abg-fwd.h (is_void_pointer_type): Declare new function. * src/abg-comp-filter.cc (has_void_ptr_to_ptr_change): Define new static function and ... (categorize_harmless_diff_node): ... use it here. * src/abg-comparison.cc (get_default_harmless_categories_bitmap): Add the new abigail::comparison::VOID_PTR_TO_PTR_CHANGE_CATEGORY category in here. (operator<<(ostream& o, diff_category c)): Add support for the new VOID_PTR_TO_PTR_CHANGE_CATEGORY. * src/abg-ir.cc (is_void_pointer_type): Define new function. * tests/data/Makefile.am: Add the new test material below to source distribution. * tests/data/test-diff-filter/test47-filter-void-ptr-change-report-0.txt: New test reference output. * tests/data/test-diff-filter/test47-filter-void-ptr-change-v{0,1}.c: Source code of the new binary test input below. * tests/data/test-diff-filter/test47-filter-void-ptr-change-v{0,1}.o: New binary test input. * tests/test-diff-filter.cc: Add the test input/output above to test harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
af5e660fba |
Explicitely detect anonymous data member changes
This patch detects when a data member becomes anonymous or when an anonymous data member becomes non anonymous and emits an explicit message. * include/abg-comp-filter.h (has_anonymous_data_member_change): Add new function declaration. * include/abg-fwd.h (is_data_member, is_anonymous_data_member): declare new overloads. * src/abg-comp-filter.cc (has_anonymous_data_member_change): Define new overloads. * src/abg-ir.cc (is_data_member, is_anonymous_data_member): Define new overloads. * src/abg-reporter-priv.cc (represent): In the var_diff overload, detect when we have anonymous data member changes and emit explicit error messages then. * tests/data/test-diff-dwarf/test45-anon-dm-change-report-0.txt: New test material. * tests/data/test-diff-dwarf/test45-anon-dm-change-v0.cc: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v0.o: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v1.cc: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v1.o: Likewise. * tests/data/Makefile.am: Add the new test material above to source distribution. * tests/test-diff-dwarf.cc (in_out_specs): Add the new test material above to the test harness. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust. * 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/test35-pr18754-no-added-syms-report-0.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
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> |
||
Dodji Seketeli
|
1ef833b38d |
Improve detection of local *type* changes
For variables and data member, we are quite gross in the way we detect a local type change. Basically, if a textual representation of the variable (and thus of its type) changes, then we consider that the variable has a local (possibly type) change. This leads us to (wrongly) report changes like this: 'struct S1 at test-44-anonymous-data-member-v0.c:1:1' changed: type size hasn't changed there are data member changes: anonymous data member at offset 32 (in bits) changed from: union {int b; float c;} to: union {int b; float c; char e;} Here, you see that the textual representation of the anonymous data member (of union type) changed from: union {int b; float c;} to: union {int b; float c; char e;} You see that although the textual representation of the type changed, the *structure* of the type hasn't really changed. I am using the "vague" term structure, on purpose. Here, in the case of a union, the structure hasn't change because the size of the union hasn't changed. This patch thus introduces the concept of "similarity of type structures". That is, even if two types are different, if "their structure is similar", then the type change is not a local type change. More precisely, here is what we mean by type similarity: Two indirect types (pointers, references) have similar structure if their underlying types are of the same kind and have the same name. In this indirect types case, the size of the underlying type does not matter. Two direct types (i.e, non indirect) have a similar structure if they have the same kind, name and size. Two class types have similar structure if they have the same name, size, and if their data members have similar types. This patch then uses that similarity concept to detect local type changes. * include/abg-fwd.h (is_type_decl): Declare new overload for type_base*. (types_have_similar_structure): Declare new function. * src/abg-comparison.cc (class_or_union_diff::priv::count_filtered_changed_dm): Even when looking at local changes only, do not forget to count nodes that were filtered out. * src/abg-ir.cc (types_have_similar_structure): Define new function. (is_type_decl): Define new overload for type_base*. (is_enum_type): (equals): In the overload for var_decl, use the new types_have_similar_structure function to detect local (type) changes. * src/abg-reporter-priv.cc (represent): In the overload for var_decl, use the diff::has_local_changes function to detect local changes, now that we can better detect local changes. * tests/data/test-diff-filter/test44-anonymous-data-member-report-1.txt: Adjust. * tests/data/test-diff-suppr/test36-leaf-report-0.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
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> |
||
Dodji Seketeli
|
e73901a523 |
Do not mark "distinct" diff nodes as being redundant
When a char is changed into a const char several times in different spots of the type graph, we want to see all the occurence of those changes. Generalizing this in Abigail parlance, we'd say that we want to see all occurences of distinct diff nodes, so we don't want to mark them as being redundant. Right now, libabigail will only show the first occurence of that change will flag subsequent onces as being redundant, by virtue of the redundancy marking pass. This patch avoids marking distinct diff nodes as being redundant. 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-comp-filter.h (is_mostly_distinct_diff): Declare new function. * include/abg-fwd.h (peel_typedef_pointer_or_reference_type): Take a boolean to decide to peel qualified types or not. * src/abg-comp-filter.cc (is_mostly_distinct_diff): Define this function. * src/abg-comparison.cc (redundancy_marking_visitor::visit_begin): Do not mark distinct_diff nodes as being redundant. * src/abg-ir.cc (peel_typedef_pointer_or_reference_type): Implement taking a boolean to decide to peel qualified types or not. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
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> |
||
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> |
||
Dodji Seketeli
|
2bbfc662d2 |
Misc style fixes
* include/abg-fwd.h (get_pretty_representation): Add missing white space. * src/abg-ir.cc (get_name): Fix typo in comment. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
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> |
||
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> |
||
Dodji Seketeli
|
50231b5537 |
Create a Corpus Group API extension
To support the upcomping analysis of the Linux kernel and its modules, we need a way to represent a union of corpora. The first corpus loaded would be the one representing the vmlinux binary. Subsequent corpora loaded would be those representing the modules. This patch provides the new abigail::ir::corpus_group type that represents such a corpus group. * include/abg-corpus.h (corpus::{find_translation_unit, get_type_per_loc_map}): Declare new member functions. (corpus::{get_architecture_name, is_empty}): Make these member functions const. (corpus::{get_sorted_fun_symbols, get_functions, get_variables, get_unreferenced_function_symbols, get_unreferenced_variable_symbols}): Make these member functions virtual. (class corpus_group): Declare a new type. * include/abg-fwd.h (corpus_sptr, corpus_group_sptr) (string_tu_map_type, istring_var_decl_ptr_map_type) (istring_function_decl_ptr_map_type): Define new typedefs. * src/abg-corpus-priv.h (corpus_priv::{path_tu_map, type_per_loc_map_}): Add new data members. * src/abg-corpus.cc (corpus_add): Complete the function comment. Assert that at most one translation unit of a given path can be added to the corpus. (corpus::{find_translation_unit, get_type_per_loc_map}): Define new member functions. (corpus::{get_architecture_name}): Make this member function const. (struct corpus_group::priv): Define new type. (corpus_group::{corpus_group, ~corpus_group, add_corpus, get_corpora, is_empty, get_functions, get_variables, get_var_symbol_map, get_fun_symbol_map, get_sorted_fun_symbols, get_sorted_var_symbols, get_unreferenced_function_symbols, get_unreferenced_variable_symbols}): Define member functions of the new corpus_group type. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
ae3c88da13 |
Remove useless overloads of is_type
Now that there is a is_type predicate that takes a a type_or_decl_base type, the overloads that take a decl_base or a type_base are useless and can even lead to overload resolution issues. This patch removes those useless overloads. * include/abg-fwd.h (is_type): Remove the overloads that take decl_base and type_base types. * src/abg-ir.cc (is_type): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Slava Barinov
|
888cd3c376 |
Fix types in header to meet sources
Package fails to build for 32bit architectures since size_t is not 64 bits. Make header consistent with source * include/abg-fwd.h: Include stdint.h for uint64_t. (ir::set_data_member_offset): Take uint64_t rather than size_t. (ir::get_data_member_offset): Return uint64_t rather than size_t. Signed-off-by: Slava Barinov <v.barinov@samsung.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
0c820488d4 |
Bug 21296 - Reporting diff of const ref against non-const ref aborts
References are always const. But then GCC sometimes emits DWARF that represents a const reference. This leads, for instance, to a given reference to be considered as different from that same reference wraps into a const qualifier. Which is wrong. Libabigail then represents those const references as a particular case of a "no-op qualifier". That is, a qualifier that should be ignored by the comparison code. In the case of this issue, the comparison engine considers the two references (const and non-const) to be equal, but the reporting code forgets to ignore the ignore no-op qualifier and thus (wrongly) considers the two references as being different. That inconsistency leads to an abort of the process. This patch moves the code that ignores no-op qualifiers at a lower level of the comparison engine so that whenever function parameters are compared, no-op qualifiers are ignored as they should. * include/abg-fwd.h (look_through_no_op_qualified_type): Declare new function. * src/abg-ir.cc (look_through_no_op_qualified_type): Define it. (compute_diff_for_types): Use the new look_through_no_op_qualified_type here rather than open-coding it. (equals): In the overload for function_decl::parameter, use the new look_through_no_op_qualified_type function. * tests/data/test-diff-dwarf/test40-PR21296-clanggcc.cc: Source code of the new test inputs. * tests/data/test-diff-dwarf/test40-PR21296-clanggcc-report0.txt: New test input. * tests/data/test-diff-dwarf/test40-PR21296-libgcc.so: New binary test input. * tests/data/test-diff-dwarf/test40-PR21296-libclang.so: Likewise. * tests/test-diff-dwarf.cc (in_out_specs): Add the new test inputs to the test harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
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> |
||
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> |
||
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> |
||
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> |
||
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> |
||
Dodji Seketeli
|
c86ffddab7 |
Cleanup some entry points in abg-fwd.h
While looking at something else I came accross some interface cleanup opportunities, as usual. This patch honours some of those opportunities. * include/abg-fwd.h (add_decl_to_scope): Pass the scope smart pointer by reference. (is_member_type): pass the type smart pointer by reference. (is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. * include/abg-ir.h (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (scope_decl::{add_member_decl, insert_member_decl}): Pass the member smart pointer by reference. (scope_decl::remove_member_decl): Take a non-const smart pointer. (class_decl::add_member_decl): Pass the decl smart pointer by reference. (is_method_decl): Take pointer or reference to type_or_decl_base rather than function_decl. * src/abg-ir.cc (translation_unit::priv::corpus): Make this a pointer to non-const corpus. (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (translation_unit::get_global_scope): Adjust. (translation_unit::bind_function_type_life_time): Adjust. (type_or_decl_base::translation_unit): Make this a pointer to non-const translation_unit. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (is_member_type): pass the type smart pointer by reference. (scope_decl::{add_member_decl, insert_member_decl}): Take a reference to the member decl smart pointer. Adjust. (class_decl::add_member_decl): Likewise. (scope_decl::remove_member_decl): Take a non-const smart pointer. (add_decl_to_scope): Pass the scope smart pointer by reference. (is_decl, is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_method_decl, is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
e73c0ed0fb |
Add new helper functions
In preparation of dropping ABI artifacts from the IR, add new generic helper functions. * include/abg-fwd.h (get_location, build_qualified_name): Declare new functions. * include/abg-ir.h (is_method_decl): Declare two new overloads of this function. * src/abg-ir.cc (get_location, build_qualified_name) (is_method_decl): Define these functions declared above. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
b07fcbcc0d |
Cleanup is_class and is_compatible_with_class_type
There was two overloads of is_class, one for types and one for decls. Now that we have type_or_decl_base which is a common base type for both, having just one is_class function that takes a type_or_decl_base is more compact and easier to maintain. This patch does that. It also cleans up the declaration of the is_compatible_with_class_type function. * include/abg-fwd.h (is_class): Remove the overloads that take a decl_base or a type_base. Add one that takes a type_or_decl_base. (is_compatible_with_class_type): Make this take a reference to smart pointer, not just the smart pointer. * src/abg-ir.cc (is_class): Do the same as in the header file. (is_compatible_with_class_type): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
9da7ae49d7 |
Add a new overload for is_type_decl
While working on something else, it appeared that I needed an overload for is_type_decl that takes a shared pointer to decl_base. The current is_type_decl takes a shared opinter to type_base. This patch also updates some code that unnecessarily calls is_type_decl. * include/abg-fwd.h (is_type_decl): Declare a new overload * src/abg-ir.cc (is_type_decl): Define a new overload. (function_decl::parameter::get_pretty_representation): Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
22cd4059cd |
Light optimizations by passing reference to smart pointers around
Profiling shows that some smart pointers were unnecessarily created here and there, and that had a noticeable effect on performance, when comparing two gtk3 packages. This patch passes references to smart pointers in those cases. * include/abg-fwd.h (get_type_name): Take a reference to type_sptr. * src/abg-ir.cc (get_type_name): Take a reference to type_sptr. (suppression_base::priv::{get_file_name_regex, get_file_name_not_regex, get_soname_regex, get_soname_not_regex}): Return a reference to regex_t_sptr. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
7cd624a1cd |
Split suppression engine off of abg-comparison.{cc,h}
Until now, the suppression engine was part of the comparison engine. The code of both was in the abg-comparison.{cc,h} files. For the sake of greater modularity, this patch separates the suppression engine from the comparison engine. The suppression engine now lives in include/abg-suppression.h and src/abg-suppression.cc. The patch also updates logical consumers of the suppression engine to adapt them to the change. * include/Makefile.am: Add abg-suppression.h to source distribution. * include/abg-comparison.h: Remove abg-ini.h include directive. (suppression_sptr, suppressions_type): Move these typedefs to abg-fwd.h. (class suppression_base, type_suppression) (type_suppression::insertion_range) (type_suppression::insertion_range::boundary) (type_suppression::insertion_range::integer_boundary) (type_suppression::insertion_range::fn_call_expr_boundary) (function_suppression, function_suppression::parameter_spec) (variable_suppression): Move these type definitions to the new abg-suppression.h. (read_suppressions, is_type_suppression, is_integer_boundary) (is_fn_call_expr_boundary, is_function_suppression) (is_variable_suppression, operator&) (operator|): Move these function declarations to the new abg-suppression.h. (type_suppression, type_suppression_sptr, type_suppression_type) (function_suppression, function_suppression_sptr) (function_suppressions_type, variable_suppression) (variable_suppression_sptr, variable_suppressions_type): Move these forward declaration and typedefs to the new abg-suppression.h. (diff_context::suppressions): Adjust return type to suppr::suppressions_type&. (diff_context::add_suppression): Adjust parameter type to suppr::suppressions_sptr. (diff_context::add_suppressions): Adjust parameter type suppr::suppressions_type&. (is_type_diff, is_decl_diff, is_var_diff, is_function_decl_diff) (is_pointer_diff, is_reference_diff, is_fn_parm_diff) (is_base_diff, is_child_node_of_function_parm_diff) (is_child_node_of_base_diff): Declare these new functions. They were previously static, local to abg-comparison.cc only. Now they need to be exported because they are used by the suppression engine's code that now lives in its one files. * include/abg-fwd.h (suppr::{suppression_base, suppression_sptr, suppressions_type}): Forward declare these here. * include/abg-suppression.h (class suppression_base) (type_suppression, type_suppression::insertion_range) (type_suppression::insertion_range::boundary) (type_suppression::insertion_range::integer_boundary) (type_suppression::insertion_range::fn_call_expr_boundary) (function_suppression, function_suppression::parameter_spec) (variable_suppression): Move these type definitions here, in the namespace suppr. (read_suppressions, is_type_suppression, is_integer_boundary) (is_fn_call_expr_boundary, is_function_suppression) (is_variable_suppression, operator&) (operator|): Move these function decalration here, in the namespace suppr. (type_suppression_sptr, type_suppressions_type) (function_suppression_sptr, function_suppressions_type) (variable_suppression_sptr, variable_suppressions_type): Move these typedefs here, in the namespace suppr. * src/Makefile.am: add src/abg-suppression.cc to source distribution. * src/abg-comparison.cc (is_type_diff, is_decl_diff, is_var_diff) (is_function_decl_diff, is_pointer_diff, is_reference_diff) (is_reference_or_pointer_diff, is_fn_parm_diff, is_base_diff) (is_child_node_of_function_parm_diff, is_child_node_of_base_diff): Export these functions. (*suppression*): Move all the suppression-related definitions to the new abg-suppression.cc. * src/abg-suppression.cc: New file. Contains all the *suppression* definitions from src/abg-comparison.cc, that are put in the suppr namespace. * tools/abicompat.cc: Adjust. * tools/abidiff.cc: Likewise. * tools/abipkgdiff.cc: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
cf8eba68c3 |
Implement string interning for Libabigail
This patch implements string interning optimization. One can read about the principles of this optimization at https://en.wikipedia.org/wiki/String_interning. The patch introduces an abigail::interned_string type, as well as an abigail::interned_string_pool type. Each environment type owns a string pool and strings are interned in that pool for all types and decls of that environments. The interned_string has methods to interact seemingly with std::string including a hashing function. Of course hashing and comparing interned_string is faster than for std::string. To enable ABI artifacts to intern strings, each constructor of ABI artifacts now takes the environment it's constructed in as parameter. From the environment, it can thus use the interned string pool. The patch then changes declaration names to be of type interned_string, and performs the necessary adjustments. The hash maps that hash strings coming from those declaration names are adjusted to hash interned_string. * include/Makefile.am: Add the new abg-interned-str.h file to source distribution. * include/abg-corpus.h (corpus::corpus): Re-arrange the order of * src/abg-corpus.cc (corpus::exported_decls_builder::priv::get_id): Return interned_string rather than std::string. (corpus::corpus): Re-arrange the order of parameters: take an environment as first parameter. parameters: take an environment as first parameter. * include/abg-dwarf-reader.h (lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Likewise. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab) (lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab) (lookup_symbol_from_elf, lookup_public_function_symbol_from_elf) (lookup_public_variable_symbol_from_elf, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Take an environment as first parameter and adjust. (build_translation_unit_and_add_to_ir) (build_namespace_decl_and_add_to_ir, build_type_decl) (build_enum_type, finish_member_function_reading) (build_class_type_and_add_to_ir, build_function_type) (read_debug_info_into_corpus, read_corpus_from_elf): Adjust. * include/abg-fwd.h: Include abg-interned-str.h (get_type_name, get_function_type_name, get_method_type_name): Return a interned_string, rather than a std::string. * include/abg-interned-str.h: New declarations for interned strings and their pool. * include/abg-ir.h (environment::intern): Declare new method. (elf_symbol::{g,s}et_environment): Likewise. (type_or_decl_base::type_or_decl_base): Make the default constructor private. ({translation, type_or_decl_base}::set_environment) (set_environment_for_artifact): Take a const environment*. (elf_symbol::elf_symbol) (elf_symbol::create) (type_or_decl_base::type_or_decl_base) (translation::translation, decl_base::decl_base) (scope_decl::scope_decl, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator) (function_type::function_type, method_type::method_type) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl, class_decl::class_decl): Take an environment. (type_or_decl_base::operator=) (enum_type_decl::enumerator::get_environment): Declare new method. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_qualified_name, get_name, get_qualified_parent_name, get_linkage_name}, qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::{get_name, get_qualified_name}) ({var,function}_decl::get_id) (function_decl::parameter::{get_type_name, get_name_id}): Return an interned_string, rather than a std::string. (decl_base::{set_qualified_name, set_temporary_qualified_name, get_qualified_name, set_linkage_name}) (qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string, rather than a std::string. (class_decl::member_{class,function}_template::member_{class,function}_template): Adjust. * src/abg-ir.cc (environment_setter::env_): Make this be a pointer to const environment. (environment_setter::visit_begin): Adjust. (interned_string_pool::priv): Define new type. (interned_string_pool::*): Define the method declared in abg-interned-str. h. (operator==, operator!=, operator+): Define operator for interned_string and std::string (operator<<): Define for interned_string. (translation_unit::priv::env_): Make this be a pointer to const environment. (translation_unit::priv::priv): Take a pointer to const environment. (elf_symbol::priv::env_): New data member. (elf_symbol::priv::priv): Adjust. Make an overoad take an environment. (translation_unit::{g,s}et_environment): Adjust. (interned_string_bool_map_type): New typedef. (environment::priv::classes_being_compared_): Make this hastable of string be a hashtable of interned_string. (environment::priv::string_pool_): New data member. (environment::{get_void_type_decl, get_variadic_parameter_type_decl}): Adjust. (type_or_decl_base::priv::env_): Make this be a pointer to const environment. (type_or_decl::base::priv::priv): Adjust. (type_or_decl_base::set_environment) (set_environment_for_artifact): Take a pointer to const environment. (elf_symbol::{g,s}et_environment, environment::intern) (type_or_decl_base::operator=): Define new methods. (decl_base::priv::{name_, qualified_parent_name_, temporary_qualified_name_, qualified_name_, linkage_name_}): Make these data member be of tpe interned_string. (decl_base::priv::priv): Make this take an environment. Adjust. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_linkage_name, get_qualified_parent_name, get_name, get_qualified_name}, get_type_name, get_function_type_name) (get_method_type_name, get_node_name) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::get_qualified_name) (var_decl::get_id, function_decl::get_id) (function_decl::parameter::get_{name_id, type_name}): Return an interned_string. (decl_base::{set_qualified_name, set_temporary_qualified_name}) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string. (decl_base::{set_name, set_linkage_name}): Intern the std::string passed in parameter. (equals): In the overload for decl_base, adjust for a little speed optimization that is justified by profiling. (pointer_type_def::priv::{internal_qualified_name_, temp_internal_qualified_name_}): Make these data member be interned_string. (enum_type_decl::enumerator::priv::env_): New data member. (enum_type_decl::enumerator::priv::{name_, qualified_name}): Make these data member be of type interned_string. (enum_type_decl::enumerator::get_environment): New method. (enum_type_decl::enumerator::priv::priv) Adjust. (typedef_decl::operator==): Implement a little speed optimization. (var_decl::priv::nake_type_): New data member. (var_decl::priv::id_): Make this data member be of type interned_string. (equals): In the overload for var_decl, function_type, function_decl, adjust for the use of interned_string. (function_decl::priv::id_): Make this be of type interned_string. (scope_decl::{add_member_decl, insert_member_decl}) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit, lookup_node_in_scope) (lookup_type_in_scope, scope_decl::scope_decl) (qualified_type_def::qualified_type_def) (qualified_type_def::get_qualified_name) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def) (array_type_def::array_type_def, array_type_def::append_subrange) (array_type_def::get_qualified_name) (enum_type_decl::enum_type_decl) (enum_type_decl::enumerator::get_qualified_name) (enum_type_decl::enumerator::set_name) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter) (class_decl::priv::comparison_started) (class_decl::add_base_specifier) (class_decl::base_spec::base_spec) (class_decl::method_decl::method_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, class_tdecl::class_tdecl) (qualified_name_setter::do_update): Adjust. (translation_unit::translation_unit, elf_symbol::elf_symbol) (elf_symbol::create, type_or_decl_base::type_or_decl_base) (decl_base::decl_base, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator, class_decl::class_decl) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Take an environment. * src/abg-comparison.cc (function_suppression::suppresses_function): Adjust. * src/abg-reader.cc (read_translation_unit) (read_corpus_from_input, build_namespace_decl, build_elf_symbol) (build_function_parameter, build_function_decl, build_type_decl) (build_function_type, build_enum_type_decl, build_enum_type_decl) (build_class_decl, build_function_tdecl, build_class_tdecl) (read_corpus_from_native_xml): Likewise. * src/abg-writer.cc (id_manager::m_cur_id): Make this mutable. (id_manager::m_env): New data member. (id_manager::id_manager): Adjust. (id_manager::get_environment): New method. (id_manager::{get_id, get_id_with_prefix}): Return an interned_string. (type_ptr_map): Make this be a hash map of type_base* -> interned_string, rather a type_base* -> string. (write_context::m_env): New data member. (write_context::m_type_id_map): Make this data member be mutable. (write_context::m_emitted_type_id_map): Make this be a hash map of interned_string -> bool, rather than string -> bool. (write_context::write_context): Take an environment and adjust. (write_context::get_environment): New method. (write_context::get_id_manager): New const overload. (write_context::get_id_for_type): Return an interned_string; adjust. (write_context::{record_type_id_as_emitted, record_type_as_referenced}): Adjust. (write_context::type_id_is_emitted): Take an interned_string. (write_context::{type_is_emitted, record_decl_only_type_as_emitted}): Adjust. (write_translation_unit, write_corpus_to_native_xml, dump): Adjust. * tools/abisym.cc (main): Adjust. * tests/data/test-read-write/test22.xml: Adjust. * tests/data/test-read-write/test23.xml: Adjust. * tests/data/test-read-write/test26.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
1466510881 |
[PERF] Pass a bunch of perf-sensitive smart pointers by reference
* include/abg-fwd.h (lookup_type_in_corpus, lookup_type_in_scope) (lookup_var_decl_in_scope): Pass the decls smart pointers by reference. * src/abg-ir.cc (lookup_type_in_corpus, lookup_type_in_scope) (lookup_var_decl_in_scope): Pass the decls smart pointers by reference, for performance reasons. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
1bee40c075 |
Do not forget to peel qualified type off when peeling types
When peeling off typedefs, references and pointers to see if a type is made of a class type, we forget to peel qualified types off. This is in the context of parsing type info from DWARF and to determine if we should delay type canonicalization (because a given type is made of a class) or not. Fixed thus. * include/abg-fwd.h (peel_qualified_type): Declare new function ... * src/abg-ir.cc (peel_qualified_type): ... and define it. (peel_typedef_pointer_or_reference_type): Peel qualified types here too. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
35dd76bc69 |
Constify is_qualified_type()
* include/abg-fwd.h (is_qualified_type): Make this take a const parameter. * src/abg-ir.cc (is_qualified_type): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
caaeaea10b |
Misc style cleanup
* include/abg-fwd.h: Remove unnecessary declaration of class parameter. * src/abg-ir.cc: Remove trailing space in a comment. * src/abg-reader.cc: Fix a comment. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
60425d2996 |
Implement fast type lookup in a corpus
Profiling has shown that on libraries with a lot of class types declarations (more than 10K types), the phase of resolving those declarations to their definition was a hot spot. The lookup of the type definition inside the entire corpus was the bottleneck. This patch removes (or loosen) that bottleneck by doing away with the graph-walking-based type lookup algorithm that was used. Rather, maps of name -> types are maintained by each scope, in each translation unit. Those maps are updated each time a type is added to a scope. And looking up a type amounts to a lookup in a map. Way faster. * include/abg-fwd.h (components_to_type_name): Declare new function. * include/abg-ir.h (string_type_base_wptr_map_type): New typedef. (translation_unit::{get,set}_types): Declare new member functions. * src/abg-ir.cc (translation_unit::priv::types_): New data member. (translation_unit::{get,set}_types): Define these member functions. (maybe_update_types_lookup_map): Define new static function. (components_to_type_name): Define new function. (scope_decl::{add_member_decl, insert_member_decl}): Call the new maybe_update_types_lookup_map. (scope_decl::find_iterator_for_member): Fix logic. (class_decl::set_is_declaration_only): When a class declaration becomes a definition, update the name -> type map maintained in the scope of the class. (lookup_type_in_translation_unit): Use the hash map of qualified name -> types that is now maintained in the translation unit. This is way faster than the previous walking algorithm. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir): When fixing up global variable declarations that need to be re-added to the translation unit, use the new fast type lookup function. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
4b754229d1 |
Make canonicalization non sensitive to struct-ness of subtypes
In a previous patch, we made canonicalization independant from
struct-ness of class types. This was in this commit:
|
||
Dodji Seketeli
|
1a6b957401 |
Fix const-ness of a function parameter
* include/abg-fwd.h (is_function_decl): Add a const to the parameter to make it comply with the definition in abg-ir.cc. Woops. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
f95af3a89a |
Do not compare access specs for member types & functions
It turns that in some DWARF (e.g, from the r300_dri.so binary in bug libabigail/19024) the same class Foo can be declared as a struct, and later defined as a class. Or the other way around. In some cases, Foo can be declared as a struct, have a member type Foo::Type with no access specifier, and later that member type is still present with no access specifier when Foo is defined as a class. So when comparing Foo::Type (from struct Foo) against Foo::Type (from class Foo) we must not consider the access specification of Type, otherwise, as in the first case it's 'public' and in the second case it's 'private', the two member types would be considered different. And something similar happens for member function declarations too. This patch thus avoids comparing access specifiers for member types and functions. Though it can be considered as a regression compared to what was being done before, access specifiers don't have an impact on ABI per se. And they can cause noise in the result, as we are seeing here. * include/abg-fwd.h (is_function_decl): Declare a new overload. * src/abg-ir.cc (is_function_decl): Define a new overload. (equals): In the overload for decl_base, do not compare access specifiers when comparing member functions and types. * tests/data/test-diff-dwarf/test0-report.txt: Adjust. * tests/data/test-diff-filter/test0-report.txt: Likewise. * tests/data/test-diff-filter/test01-report.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test4-report.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
e9bdb488b3 |
Bug 19025 - abixml writer forgets to emit some member types
When a member type (a type that is a member of a class) M is referenced by some types emitted by abixml, but the context of M (the class type which M is a member of) is not itself referenced by any ABI artifact, then abixml forgets to emit the context of M and thus M itself. With this patch, when the abixml writer has emitted almost all ABI artifacts for the current translation unit, it looks for types that have been referenced by the emitted ABI artifacts, but that haven't been emitted themselves. It then emits those referenced-but-not-emitted types, and makes sure their contexts are emitted as well. * include/abg-fwd.h (is_namespace): Fix prototype. * src/abg-writer.cc (struct type_ptr_comp_functor): New internal type. (sort_type_ptr_map): New static function. (write_context::m_referenced_types_map): Renamed m_referenced_fntypes_map data member into this. (write_context::get_referenced_types): New member function. (write_context::record_type_as_referenced): Renamed record_fntype_as_referenced member function into this. Adjust. (write_context::type_is_referenced): Renamed fntype_is_referenced into this. (write_context::clear_referenced_types_map): Renamed clear_referenced_fntypes_map member function into this. Adjust. (write_decl_in_scope): New static function. (write_translation_unit): Use it here to emit types that are referenced by other types in the TU, but that are not emitted. Adjust. (write_pointer_type_def, write_reference_type_def) (write_typedef_decl): Record the underlying types referenced by the emitted types as being, well, referenced. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so: New test binary input. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: New reference output of the binary input above. * tests/data/Makefile.am: Add the new test material above to the source distribution. * tests/test-read-dwarf.cc (in_out_spec): Add the new test inputs. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust. * tests/data/test-read-dwarf/test10-pr18818-gcc.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. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
9a0abd846b |
Use the ODR to speed up type canonicalization
This is the last patch of the series of 11 patches that started at the patch with the subject: constify is_class_type() And below starts the cover letter of this patch. While analyzing some libraries like libmozjs.so[1] it appeared that type canonicalization takes a significant time to comparing composite types that are re-defined in each translation units again and again. The One Definition Rule[2] says that two types with the same name shall designate the same thing; so when a type T being canonicalized has the same name of a canonical type C in the same ABI corpus, then this patch considers C as being the canonical type of T, without comparing T and C structurally. This saves us from comparing T and C. Before this patch, `abidw --noout libmozjs.so` was taking approximatively 5 minutes; with the patch, it takes 1 minutes and 30 seconds. To do this, the patch changes ABI artifacts to carry a pointer to the corpus it belongs to. Whenever an ABI artifact is added to a given context, the corpus of that context is propagated to the artifact; that is now possible as the artifact now carries the property of the corpus it belongs to. During type canonicalization the ODR-based optimization outlined above is performed as we can now compare the corpus of a given type again the one of another type; it's now possible to know if two types come from the same corpus. There are a few cases though were the optimization is not performed: - anonymous struct; when a struct is anonymous (it has no name, as described in the DWARF), the DWARF reader gives it a name nonetheless, so that diagnostics can refer to that anonymous type. But then all anonymous types in the system have the same name. So when faced with two anonymous types (with the same name) from the same corpus, it's wrong to consider that they name the same thing. The patch added an "is_anonymous" property to types created by the DWARF reader so that such anonymous types can be detected by the type canonicalizer; they are thus not involved in this optimization. Note that the abixml writer and reader have been updated to emit and read this property. - typedefs. I have seen in some boost code two typedefs of the same name refer to different underlying types. I believe this is a violation of ODR. I'll need to investigate on this later. And I think we really need to detect these ODR violations as part of this enhancement request: https://sourceware.org/bugzilla/show_bug.cgi?id=18941. - pointers, references, arrays and function types, as they can refer to the two exceptions above. This is the last patch of the series which aimed at speeding up type canonicalization in the context of types being re-defined a lot in translation units. [1]: Instruction to build libmozjs.so from the mongodb sources: - git clone https://github.com/mongodb/mongo.git - cd mongo - scons --link-model=dynamic build/opt/third_party/mozjs-38/libmozjs.so [2] One Definition Rule: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (class corpus): Forward-declare this. (is_anonymous_type): Declare this new function. * include/abg-ir.h (corpus_sptr, corpus_wptr): Declare these typedefs here too. (translation_unit::{g,s}et_corpus): Declare new member functions. (type_or_decl_base::{g,s}et_corpus): Likewise. * src/abg-ir.cc (translation_unit::priv::corpus): New data member. (translation_unit::priv::priv): Initialize it. (translation_unit::{g,s}et_corpus): Define new accessors. (translation_unit::get_global_scope): Propagate the corpus of the translation unit to its newly created global scope. (translation_unit::bind_function_type_life_time): Propagate the corpus of the translation_unit to the added function type. (type_or_decl_base::priv::corpus_): Add new data member. (type_or_decl_base::priv::priv): Initialize it. (type_or_decl_base::{g,s}et_corpus): Define new accessors. (scope_decl::{add,insert}_member_decl): Propagate the context's corpus to the member added to the context. (decl_base::priv::is_anonymous_): Add new data member. (decl_base::priv::priv): Initialize it. (decl_base::{s,g}et_is_anonymous): Define accessors. (is_anonymous_type): Define a new test function. (decl_base::set_name): Update the "is_anonymous" property. (type_base::get_canonical_type_for): Implement the ODR-based optimization to type canonicalization. * src/abg-corpus.cc (corpus::add): When a translation unit is added to a corpus, set the corpus of the translation unit. * src/abg-dwarf-reader.cc (build_enum_type) (build_class_type_and_add_to_ir): Set the "is_anonymous" flag on anonymous enums and classes. * src/abg-reader.cc (read_is_anonymous): Define new static function. (build_type_decl, build_enum_type, build_class_decl): Call the new read_is_anonymous function and set the "is_anonymous" property on the built type declaration. * src/abg-writer.cc (write_is_anonymous): Define new static function. (write_type_decl, write_enum_type_decl, write_class_decl): Write the "is_anonymous" property. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Adjust. * tests/data/test-read-dwarf/test9-pr18818-clang.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. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
6e36a4381d |
Late canonicalize all types that reference classes when reading DWARF
Until now, the DWARF reader would late canonicalize typedefs to classes, as well as classes. That is not enough. Let's also late-canonicalize pointers, references and array of classes too. This is because classes that might not be finished yet might be referenced by those types, and so we want to wait until they are finished before we canonicalize them. * include/abg-fwd.h (peel_array_type): Declare new function. * src/abg-ir.cc (peel_array_type): Define it. (peel_typedef_pointer_or_reference_type): Peel arrays too, to get the type of its element. * src/abg-dwarf-reader.cc (maybe_canonicalize_type): If a pointer, reference, array or typedef references a class, then do late-canonicalize this type. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
db02f0bdb4 |
constify is_class_type()
This the first patch of a series of 11 patches which aims at speeding up the time taken by "abidw --noout libmozjs.so". That shared library is built among by the mongodb project, among others. And abidw is taking around 5 minutes on my old Lenovo X220 laptop. After the series of patches, the same command is taking one minute and a half. The core of the optimization is to speed up type canonicalization that happens at the end of DWARF reading, once libabigail has built the IR or the ABI of the entire elf binary. The optimization comes from an insight derived from the One Definition Rule of C++, as explained at https://en.wikipedia.org/wiki/One_Definition_Rule. But before being able to perform that optimization, several fixes and code massaging were necessary. I have split those changes up in the first 10 patches of the series. The last patch thus contains the crux of the optimization. Its cover letter also contains instructions on how to build libmozjs.so, from mongodb, for those who want to replicate the results I have seen. Note that some of the first 10 patches incur adjustment in the test suite, but don't carry those necessary adjustments. All test suite adjustments are carried by the last, 11Th patch. The short description of the patches of the series are: constify is_class_type() Add missing deep equality operator for pointer and reference types Cleanup some IR type comparison operators Do not overly canonicalize types during typedef stripping Fix detection of changes in pointer diff in the comparison engine Prevent build_function_type from not canonicalizing certain types Do not use recursive type hashing when writing out function types Try harder to hash_type_or_decl avoid the slow path Fix infinite loop in peel_typedef_pointer_or_reference_type Late canonicalize all types that reference classes when reading DWARF Use the ODR to speed up type canonicalization And below is the ChangeLog of this first patch. * include/abg-fwd.h (is_class_type): Take a pointer to const. * src/abg-ir.cc (is_class_type): Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
0cc38b2327 |
Add new test functions
This patch adds a new set of test functions that are going to be used in subsequent patches to come. * include/abg-fwd.h (is_function_decl, is_decl, is_namespace) (is_scope_decl): Declare new function overloads. * src/abg-ir.cc (is_function_decl, is_decl, is_namespace) (is_scope_decl): Define them. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |