mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-19 16:30:04 +00:00
1bb3461d1d
386 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
Dodji Seketeli
|
1bb3461d1d |
Bug 19638 - DWARF reader fails to link clone function to its declaration
There are three mains issues that cause the reported problem. Let's look at them closely. Suppose there is a DIE of a member function Klass::clone_of_foo, which is a clone of the DIE of the function Klass_foo, which is the concrete instance of the DIE of the declaration of Klass::foo. When libabigail's DWARF reader sees the DIE for Klass::clone_of_foo, it fails to get the context of the declaration of Klass::clone_of_foo -- which is Klass::foo. So, in the model built by libabigail, the symbol of Klass::clone_of_foo never gets associated to Klass::foo. It thus looks like Klass::clone is never defined. It also looks like that symbol is unreferenced. From there, a number of bad things happen. This is the first root cause of the reported problem. I call it issue 1/. 2/ While looking at this, I noticed that libabigail uses the underlying symbol name of a given function as the linkage name of that function, rather than using the value of the DW_AT_linkage_name DWARF property. This usually works, until the the function has a symbol which has several aliases. In that case, depending on the symbol alias that is used, a given function can have different linkage names. This causes problems later at comparison time. This is issue 2/. 3/ I also noticed that in the libabigail model, even if type Klass does have all its member functions (including Klass::foo) defined in in a particular translation unit TU1 , the same Klass in another translation unit TU2 might not have that Klass::foo defined, just because that function is not used in TU2. So after type canonicalization, if the version of Klass that is kept is the one from TU2, we end up with a type Klass *NOT* having Klass::foo defined. Sometimes, it's just that one member function in the canonical type doesn't have any underlying symbol, whereas the same member function in another type of the same class of equivalence as the canonical type does have that an underlying symbol. This is issue 3/. To address issue 1/ the patch fixes build_ir_node_from_die, in the case where a DW_TAG_subprogram DIE is being handled. It fixes the case of finding the root interface of the clone of a function definition. The patch also fixes a bug in build_function_decl that prevents it to update the linkage name of a function, *if* that function already had one. This was preventing build_function_decl to adjust the linkage name of a function which is a clone of an original function which already had a non-empty linkage name. To address 2/ the patch makes function_decl::get_id return the linkage name of the function, *if* it exists (rather than primarily returning the ID of the underlying symbol). To address 3/ the patch implements the copying of member functions or underlying function symbols missing from the canonical type -- but otherwise present in the type that has just been canonicalized. * include/abg-ir.h (decl_base::set_linkage_name): Make this member function virtual. (class_decl::string_mem_fn_ptr_map_type): Define new member type. (class_decl::find_member_function): Declare new member function. (copy_member_function): Declare new function. Declare it as friend of class_decl. (method_decl::set_linkage_name): Declare an overload for this virtual function. * src/abg-dwarf-reader.cc (build_function_decl): Allow updating of linkage_name even if the linkage_name was already defined. (build_ir_node_from_die): In the case DW_TAG_subprogram, make the lookup of scope of the DIE work even if it has both an abstract origin and a specification (DW_AT_abstract_origin and DW_AT_specification). * src/abg-ir.cc (maybe_adjust_canonical_type): Define new function. (canonicalize): Use it. (function_decl::get_id): Return the linkage name first, if it exist. (class_decl::priv::mem_fns_map_): New data member. (class_decl::find_member_function): Define new member function. (class_decl::method_decl::set_linkage_name): Likewise. (class_decl::add_member_function): Update the new data member class_decl::priv::mem_fns_map_. (copy_member_function): Define new static function. * tests/data/test-abidiff/test-PR18791-report0.txt: Adjust. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Adjust. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Adjust. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Adjust. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Adjust. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Adjust. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
f8761a48af |
Add function lookup by linkage name to libabigail::corpus
Until now, it was not possible to lookup a function declaration from a corpus, using a symbol name for the function. This patch adds that functionnality, which is useful, at least for debugging purposes. * include/abg-corpus.h (corpus::lookup_functions): Declare new member function. * src/abg-corpus.cc (class corpus::exported_decls_builder::priv): Make class corpus be a friend of this type. (corpus::exported_decls_builder::priv::add_fn_to_id_fns_map): Fix a thinko that was preventing the fn_id -> functions map from ever being filled. Fix this function to make it associate each aliases of a given function to the function, in the hash table. (corpus::lookup_functions): Define new member function. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
421aa4ab5f |
Fix style cleanups
* include/abg-ir.h (method_type::{method_type, set_class_type, get_type, set_type}): Use type_base_sptr and class_decl_sptr instead of the full non-typedefed name. (method_type):Do some cleanups in the definition of the convenience typedefs. * src/abg-ir.cc (method_type::{method_type, set_class_type, get_type, set_type}): Use type_base_sptr and class_decl_sptr instead of the full non-typedefed name. * src/abg-writer.cc (write_class_decl): Add a comment. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
b0335a42d5 |
Prefix abidiff error message with the 'abidiff' program name
* include/abg-tools-utils.h (emit_prefix): Declare new function. (check_file): Add a new parameter with a default value, so that existing code keeps compiling. * src/abg-tools-utils.cc (emit_prefix): Define new function. (check_file): Use the emit_prefix function and give it the program name passed as a new parameter. * tools/abidiff.cc (display_usage, main): Use the new emit_prefix to prefix error messages. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
4b7e295b20 |
Bug 19596 - Incorrect exit status for incompatible ABI change
The comparison engine doesn't take virtual offset changes into account when deciding if a diff node carries an incompatible change. This is obviously an oversight. Fixed thus. * include/abg-comparison.h (enum diff_category): Adjust the comment for enumerator VIRTUAL_MEMBER_CHANGE_CATEGORY; changes of this category are incompatible ABI changes. (corpus_diff::diff_stats::num_func_with_virtual_offset_changes): Declare new accessors. * src/abg-comparison.cc (corpus_diff::diff_stats::priv::num_func_with_virt_offset_changes): New data member. (corpus_diff::diff_stats::priv::priv): Initialize the new data member. (corpus_diff::diff_stats::num_func_with_virtual_offset_changes): Define new accessors. (corpus_diff::priv::apply_filters_and_compute_diff_stats): Use the new accessor to set the number of functions with virtual offset changes onto the stats data structure. (corpus_diff::has_incompatible_changes): Take functions with virtual offset changes into account. * tests/test-abidiff-exit.cc: New test harness to test for exit codes of abidiff. * tests/Makefile.am: Build the new test harness runtestabidiff from the test-abidiff-exit.cc source file. * tests/data/test-abidiff-exit/test1-voffset-change-report0.txt: New reference test output. * tests/data/test-abidiff-exit/test1-voffset-change-v0.cc: New test input source code. * tests/data/test-abidiff-exit/test1-voffset-change-v0.o: New test input. * tests/data/test-abidiff-exit/test1-voffset-change-v1.cc: New test input source code. * tests/data/test-abidiff-exit/test1-voffset-change-v1.o: New test input. * tests/data/Makefile.am: tests/data/Makefile.am: Add the new test inputs above to the source distribution. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
2f88edd3b3 |
Fix synthesizing of pointer type
Libabigail fails to to synthesize a non-existing pointer type to an existing type. This makes abicompat fail in weak mode when trying to detect changes to a function type where the parameter is a pointer to a structure which changed. In the application, the function is invoked and a pointer to the structure is passed to it. It appears that the type of structure is defined in the debug info of the application, but not the pointer to that structure. So abicompat needs to synthesize that pointer to struct in order to synthesize the type of the function, and so, compare it to the type of the function coming from the library. It appears that synthesizing a pointer type (to an existing type) is not supported. Only synthesizing qualified type was supported. This patch adds support for that and thus fixes the abicompat test case that is attached. * include/abg-ir.h: Update copyright. * src/abg-ir.cc (synthesize_type_from_translation_unit): Support synthesizing pointer types. * tests/data/test-abicompat/libtest8-fn-changed-libapp-v0.so: New test input. * tests/data/test-abicompat/libtest8-fn-changed-libapp-v1.so: Likewise. * tests/data/test-abicompat/test8-fn-changed-app: Likewise. * tests/data/test-abicompat/test8-fn-changed-app.c: Likewise. * tests/data/test-abicompat/test8-fn-changed-libapp-v0.c: Likewise. * tests/data/test-abicompat/test8-fn-changed-libapp-v0.h: Likewise. * tests/data/test-abicompat/test8-fn-changed-libapp-v1.c: Likewise. * tests/data/test-abicompat/test8-fn-changed-libapp-v1.h: Likewise. * tests/data/test-abicompat/test8-fn-changed-report-0.txt: Likewise. * tests/data/Makefile.am: Add the new test input files to source distribution. * tests/test-abicompat.cc (in_out_specs): Add the new test inputs above to the test harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
11c89cad3e |
Pass parm of elf_symbol::add_alias by reference
* include/abg-ir.h (elf_symbol::add_alias): Pass parameter by reference. * src/abg-ir.cc (elf_symbol::add_alias): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
640b3a2f59 |
Bug 19141 - Libabigail doesn't support common ELF symbols
Libabigail's internal representation of elf symbols fails to account for common symbols in relocatable files. There can be several common symbols of the same name (defined in a section of SHN_COMMON kind). In that case, Libabigail wrongly considers these multiple instances of the same common symbol as being alias, and that breaks some basic assumptions about aliases. Oops. This patch adds support for the common symbols (and the fact that relocatable files can have several instances of the same common symbol) and amends the ELF reader to make it properly represent those. * include/abg-ir.h (elf_symbol::elf_symbol): Take a new flag to say if the symbol is common. (elf_symbol::{is_common_symbol, has_other_common_instances, get_next_common_instance, add_common_instance}): New member functions. * src/abg-ir.cc (elf_symbol::priv::{is_common_, next_common_instance_): New data members. (elf_symbol::priv::priv): Adjust. (elf_symbol::{elf_symbol, create}): Take a new flag to say if the symbol is common. (textually_equals): Adjust to account for symbol common-ness. (elf_symbol::{is_common_symbol, has_other_common_instances, get_next_common_instance, add_common_instance}): Define new member functions. (elf_symbol::add_alias): Drive-by fix; compare symbols using pointer value. Value comparison is not necessary. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab, lookup_symbol_from_symtab) (read_context::lookup_elf_symbol_from_index): Adjust the creation of the symbol to account for common-ness. (read_context::load_symbol_maps): Recognize instances of a given common symbol and represent them as such. Do not mistake this with symbol aliases. * src/abg-reader.cc (build_elf_symbol): Adjust the creation of the symbol to account for common-ness. * src/abg-writer.cc (write_elf_symbol): Adjust symbol serialization to account common-ness. * tests/data/test-types-stability/pr19141-get5d.o: Add new test binary input. * tests/data/test-types-stability/pr19142-topo.o: Likewise. * tests/data/Makefile.am: Add the new test inputs to source distribution. * tests/test-types-stability.cc (elf_paths): The the new test inputs into account. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
c3869ecc7b |
Bug 19434 - invalid character in attribute value
* include/abg-tools-utils.h (string_is_ascii_identifier): Declare new function. * src/abg-tools-utils.cc (string_is_ascii_identifier): Define new function. * src/abg-dwarf-reader.cc (build_function_type): Discard parameter name if it's made of non-identifier ascii characters. * tests/data/test-types-stability/pr19434-elf0: New test binary input file. * tests/data/Makefile.am: Add the new test input to source distribution. * tests/test-types-stability.cc: Test the new test input into account. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
f275939df2 |
Use worker threads pattern to speed up some tests
We are going to need to speed up more and more tests, and coding directly with libpthread for that can be tedious and bug-prone. So I devised an implementation for the worker threads design pattern instead, and used it to speed up some tests. * include/Makefile.am: Add the new abg-workers.h to source distribution. * include/abg-workers.h: New file. * src/Makefile.am: Add the new abg-worker.cc to source distribution. * src/abg-workers.cc: New file. * tests/test-utils.cc: Update copyright. Make get_src_dir() and get_build_dir() return a const char*, as opposed to returning a string. Make that const char reside in thread local storage, so that two concurrent threads can safely call these functions in parallel, without any race. * tests/test-utils.h: Make get_src_dir() and get_build_dir() return a const char*, as opposed to returning a string. * tests/test-abicompat.cc: Update copyright. Adjust for get_src_dir() and get_build_dir() change. * 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-pkg.cc: Likewise. * tests/test-diff-suppr.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. Use the new task queue type to run these tests in parallel. * tests/test-diff-filter.cc: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
64375c64d3 |
Make enum values take 64 bits on all platforms
The is still some changes in the way values of enumerators are represented in 32 and 64 bits systems. This is because the type of enumerators is size_t which 32 bits on 32 bits systems and 64 bits on 64 bits systems. The problem is, the output of, abidw can thus be different on 32 and 64 bits, making some tests output be different on these platforms. This patch thus uses uint64_t to represent enumerator values on all platforms. * include/abg-ir.h: Include stdint.h for int64_t. (enumerator::enumerator): Take an int64_t value for the value of the enumerator. (enumerator::{s,g}et_value): Take/return an int64_t value. * src/abg-ir.cc (enum_type_decl::enumerator::priv): Store the value in an int64_t. (enumerator::priv::priv): Take a int64_t for the value. (enum_type_decl::enumerator::enumerator): Likewise. (enum_type_decl::enumerator::{s,g}et_value): Take/returnan int64_t value. * src/abg-dwarf-reader.cc (die_unsigned_constant_attribute): Take an uint64_t value. (die_signed_constant_attribute): Take an int64_t value. (die_location, die_size_in_bits, die_access_specifier) (die_virtuality, die_is_virtual, die_is_declared_inline) (build_translation_unit_and_add_to_ir, build_type_decl) (build_enum_type, build_pointer_type_def, build_array_type): Adjust. * src/abg-reader.cc (build_enum_type_decl): Adjust. * src/abg-writer.cc (write_enum_type_decl): Do not cast the result of enumerator::get_value() anymore, it's value is now a int64_t. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
5c8c049e70 |
Bug 19138 - Failure to relate variables address from DWARF and ELF
In this problem report libabigail's DWARF reader wrongly looks up the address of variables (that it got from DWARF) in the .bss section of the ELF file. But then, in these files (generated by the Intel C++ compiler) the variables we are looking at have their addresses in the .data1 section. This patch changes the DWARF/ELF reader to make it look for variable addresses in .data, .data1, .rodata and .bss sections, as it should be. * include/abg-dwarf-reader.h (elf_type::ELF_TYPE_RELOCATABLE): New enumerator. * src/abg-dwarf-reader.cc (find_section): Factorize this from ... (find_text_section, find_bss_section): ... these. (find_rodata_section, find_data_section, find_data1_section): Define new static functions. (elf_file_type): Move this static function definition up. (read_context::{get_elf_file_type, address_is_in_section, get_data_section_for_variable_address}): New member functions. (read_context::maybe_adjust_fn_sym_address): Adjust comment. Adjust to use the new read_context::get_data_section_for_variable_address(). * tests/data/test-types-stability/pr19138-elf0: New test input binary. * tests/data/Makefile.am: Add the new test input binary to the test suite. * tests/test-types-stability.cc (elf_paths): Take it into account. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
d50882bf4f |
Make class_decl::base_spec class follow the pimpl pattern
* include/abg-ir.h (class_decl::base_spec::priv): Declare new private data type. (class_decl::base_spec::priv_): Declare new pimpl data member. (class_decl::base_spec::{base_class_, offset_in_bits_, is_virtual_}): Remove. (class_decl::base_spec::{get_base_class, get_is_virtual, get_offset_in_bits}): Make these member functions out of line. * src/abg-ir.cc (struct class_decl::base_spec::priv): New type. (class_decl::base_spec::{get_base_class, get_is_virtual, get_offset_in_bits}): Define these functions here. (class_decl::base_spec::base_spec): Adjust because now there is only one pimpl data member to initialize. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Ondrej Oprala
|
6a7566d513 |
Add the option of printing the file, line and column information about a type being reported.
* bash-completion/abicompat: Complete the new "--no-show-locs" option. * bash-completion/abidiff: Likewise. * bash-completion/abidw: Likewise. * bash-completion/abipkgdiff: Likewise. * doc/manuals/abicompat.rst: Mention the new "--no-show-locs" option. * doc/manuals/abidiff.rst: Likewise. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-comparison.h (show_locs): Add declarations. * src/abg-comparison.cc: (diff_context::priv): Add a new switch called "show_locs_" and set its default value to false. (report_loc_info): New function. Outputting the extra information is conditionalized based on the associated diff contexts settings. (show_locs): define a getter/setter for diff_context::priv::show_locs_. ({distinct,pointer,reference,qualified_type,enum,class,scope,fn_parm, typedef,corpus}_diff::report): Call report_loc_info when appropriate. (maybe_report_diff_for_member): Likewise. (represent): Accept a const reference to a diff_context_sptr as a first argument and call report_loc_info on its second argument. * src/abg-dwarf-reader.cc: * tests/data/Makefile.am: Add the new test reference files. * tests/data/test-abicompat/test0-fn-changed-report-2.txt: New test reference output. * tests/data/test-abicompat/test5-fn-changed-report-1.txt: Likewise. * tests/data/test-abicompat/test6-var-changed-report-1.txt: Likewise. * tests/data/test-abicompat/test7-fn-changed-report-2.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-pkg/dirpkg-3-report-2.txt: Likewise. * tests/data/test-diff-suppr/test6-fn-suppr-report-0-1.txt: Likewise. * tests/test-abidiff.cc: Explicitly create a diff context and turn off location emitting. * tests/test-diff-dwarf.cc: Likewise. * tests/test-abicompat.cc: Add --no-show-locs to all existing test arguments. Run a few of the existing tests again, but without this option. * tests/test-diff-filter.cc: Likewise. * tests/test-diff-pkg.cc: Likewise. * tests/test-diff-suppr.cc: Likewise. * tools/abicompat.cc: Handle the new "--no-show-locs" option. * tools/abidiff.cc: Likewise. * tools/abidw.cc: Likewise. * tools/abipkgdiff.cc: Likewise. Signed-off-by: Ondrej Oprala <ooprala@redhat.com> |
||
Dodji Seketeli
|
b017143876 |
[PERF] Access naked pointers for canonical types and function types
Performance profiling has shown that accessing shared_ptr to canonical types and function type during type comparison was noticeable slowing down the process. This patch thus access naked pointers for canonical types and function types at these performance hot spots. The profiling took place while running abidw --abidiff on the r300_dri.so binary. * include/abg-ir.h (type_base::get_naked_canonical_type): Declare new accessor. (function_decl::get_naked_canonical_type): Likewise. (function_decl::set_type): Pass a reference to the shared_ptr. * src/abg-ir.cc (type_base::priv::naked_canonical_type): New data member. (type_base::priv::priv): Initialize it. (canonicalize): Set the naked canonicalize type when we set its shared pointer. (type_base::get_naked_canonical_type): Define new accessor. ({pointer_type_def,reference_type_def,function_type,class_decl}::operator==): Use naked canonical pointers rather than the slower shared_ptr to canonical pointers. (function_decl::priv::naked_type_): New data member. (function_decl::priv::priv): Initialize it. (function_decl::get_naked_type): Define new accessor. (function_decl::set_type): Pass a reference to the shared_ptr . (equals): In the overload for function_decl, use the faster naked pointers to the type of the function. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
c0de97846c |
[PERF] Turn some pimpl pointers into naked pointers
The private data pointers of libabigail IR types are usually managed using shared_ptr. But performance profiling has shown that de-referencing some of these private data shared_ptr can have a noticeable performance impact. This is because de-referencing shared_ptr involves some locking that show up on some performance profile. So, for decl_base, type_base, and function_decl, this patch replaces the private data shared pointers by naked pointers. This speeds up the access to private data members, especially during comparison of class pointer, reference and function types. And that has a noticeable impact when libabigail handles huge binaries with lots of functions an type, like r300_dri.so. * include/abg-ir.h ({decl_base, type_base, function_decl}::priv_) Make this a naked pointer to priv, rather than a shared_ptr<priv>. * src/abg-ir.cc (decl_base::~decl_base): Destroy the private data pointer, aka pimpl pointer. (type_base::~type_base): Likewise. (function_decl::~function_decl): Likewise. (class_decl::~class_decl): Likewise. 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
|
0ec2416837 |
Bug 19126 - abidw segv on a dwz compressed version of r300_dri.so
Suppose a declaration D (which locus is in a file F) is imported at an offset offset of O1 into a compilation unit C1 and at an offset O2 (using DW_TAG_imported_unit) into a compilation unit C2. When the DWARF reader creates the ABI artifact for D in O1, its location is encoded by a location manager that is handled by C1. At O2 (in C2) the ABI artifact for D (created at O1, in C1) is re-used. But then, to decode the location of D, the DWARF reader wrongly uses the location manager that is handled by C2. It should use the location manager of C1, because that is the one used to encode the location of D. It picks the wrong location manager because it picks the wrong translation unit for D. Right now, the translation unit for a given declaration is the "current" translation unit at the moment the DIE was being inspected. And that is wrong when imported type units kick in. 1/ More generally, each ABI artifact should be associated with its translation unit, which is the current translation unit when the artifact was created. As there is just one copy of D, its translation unit should always be the same. 2/ Also, the location should ensure that about the location manager used to encode it is the same one used to decode it, so that this kind of bug cannot arise. This patch fixes the issue by doing 1/ and 2/. The r300_dri.so test case on which is was failing is not added to the test suite because it's too big. It was taking more than 55 minutes to have complete abidw --abidiff complete on that binary, on my machine. So I am going to work on the performance side of things, I think. * include/abg-ir.h (class location_manager): Forward declare it before class location. (location::loc_manager_): New data member. (location::location): Take the location manager in one overload and initialize the new loc_managers_ in all the overloads. (location::get_location_manager): New getter. (location::expand): New member function. (location::*): Add API doc to all entry points. (location_manager::expand_location): Take a const location. (type_or_decl_base::set_corpus): Remove. (type_or_decl_base::{get,set}_translation): New accessors. (decl_base::{decl_base,get_location}): Take or return a reference on location. (scope_decl::scope_decl): Likewise. (type_decl::type_decl): Likewise. (namespace_decl::namespace_decl): Likewise. (qualified_type_def::qualified_type_def): Likewise. (pointer_type_def::pointer_type_def): Likewise. (reference_type_def::reference_type_def): Likewise. (array_type_def::subrange_type::{subrange_type, get_location}): Likewise. (enum_type_decl::enum_type_decl): Likewise. (typedef_decl::typedef_decl): Likewise. (var_decl::var_decl): Likewise. (function_decl::function_decl): Likewise. (function_decl::parameter::parameter): Likewise. (template_decl::template_decl): Likewise. (type_tparameter::type_tparameter): Likewise. (non_type_tparameter::non_type_tparameter): Likewise. (function_tdecl::function_tdecl): Likewise. (class_tdecl::class_tdecl): Likewise. (class_decl::class_decl): Likewise. (class_decl::method_decl::method_decl): Likewise. * src/abg-ir.cc (location::expand_location): Define new member function. (type_or_decl_base::priv::corpus_): Remove. (type_or_decl_base::priv::translation_unit_): New data member. (type_or_decl_base::priv::priv): Adjust. (type_or_decl_base::set_corpus): Remove. (type_or_decl_base::get_corpus): Adjust. (type_or_decl_base::{get,set}_translation_unit): New member functions. (decl_base::priv::priv): Take a reference to location. (decl_base::decl_base): Likewise. (decl_base::get_location): Return a reference to location. (location_manager::create_new_location): Adjust. (location_manager::expand_location): Take a reference to location. (translation_unit::get_global_scope()): Adjust. (translation_unit::bind_function_type_life_time): Likewise. (scope_decl::{add,insert}_member_decl): Adjust. (get_translation_unit): Likewise. (type_decl::type_decl): Take a reference to location. (namespace_decl::namespace_decl): Likewise. (qualified_type_def::qualified_type_def): Likewise. (pointer_type_def::pointer_type_def): Likewise. (reference_type_def::reference_type_def): Likewise. (array_type_def::subrange_type::priv::priv): Likewise. (array_type_def::subrange_type::{subrange_type, get_location}): Likewise. (enum_type_decl::enum_type_decl): Likewise. (typedef_decl::typedef_decl): Likewise. (var_decl::var_decl): Likewise. (function_decl::function_decl): Likewise. (function_decl::parameter::parameter): Likewise. (template_decl::template_decl): Likewise. (type_tparameter::type_tparameter): Likewise. (non_type_tparameter::non_type_tparameter): Likewise. (function_tdecl::function_tdecl): Likewise. (class_tdecl::class_tdecl): Likewise. (class_decl::class_decl): Likewise. (class_decl::method_decl::method_decl): Likewise. * src/abg-writer.cc (write_location): Take a reference to location and adjust. (write_array_type_def, write_function_decl, dump_decl_location): Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
2eda63d0f2 |
Fix internal name for pointers, typedefs and arrays
Internal names (and pretty representation) of types are used for type canonicalization. These were not being correctly computed for pointers typedefs and arrays because we were forgetting sometimes to use internal names of the underlying types, especially because of caching issues. This patch addresses that. Note that I noticed this while comparing the two versions of libgromacs_d.so.0.0.0 involved in the comparison referenced by bug https://bugzilla.redhat.com/show_bug.cgi?id=1283906. But then that library is too big (and takes too much time) to be included as a non regression test :( * include/abg-ir.h (pointer_type_def::priv_): New data structure. The type is now pimpled. (typedef_decl::priv_): Likewise. * src/abg-ir.cc (struct pointer_type_def::priv): New struct. (pointer_type_def::pointer_type_def): Adjust. (pointer_type_def::get_pointed_to_type): Likewise. (pointer_type_def::get_qualified_name): Store temporary/internal names into different caches. (array_type_def::priv::{temp_internal_qualified_name_, internal_qualified_name_}): New data members. (get_type_representation): In the overload for array_type_def, take requests for internal names into account. (array_type_def::get_qualified_name): Take requests for internal names into account. Store temporary/internal names into different caches. (typedef_decl::priv): New struct. (typedef_decl::typedef_decl): Adjust. (typedef_decl::get_underlying_type): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
fa4b7c8069 |
Fix comparison in qualified_type_diff::has_changes
* src/abg-comparison.cc (qualified_type_diff::has_changes): Make this stupid and simple, now that we have (fast) canonical type based comparison. * include/abg-ir.h (qualified_type_diff::operator==): Add an overload for qualified_type_diff here. (operator==): Likewise. * src/abg-ir.cc (qualified_type_diff::operator==): Define it. (operator==): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
43c908ed15 |
Bug 19336 - Better handle redundantly qualified reference types
Sometimes we can see const references in DWARF. But then, a reference is always const, so that qualified reference is redundant. Furthermore, having that construct make its way into the internal representation can cause awkward diagnostics. The DWARF reader was thus eliding such redundant qualifiers in the function "maybe_strip_qualification". It was doing so by stripping the qualifier from the qualified type. So const reference, for instance, becomes a (non-qualified) reference. In that case, we are turning a qualified type into a non-qualified one. But as the accompanying problem report suggests, this can cause issues during the DWARF parsing. This is because a given Debug Information Entry (DIE) of qualified type kind can be referenced elsewhere, by another type. That other type expects that DIE to be a qualified type. And libabigail's DWARF reader code enforces that. So the internal representation of a type resulting from a qualified type DIE must be a qualified type itself. So the way the function "maybe_strip_qualification" was doing the redundancy elision was wrong. This patch fixes that by keeping the type qualified, but introducing a "no-op" qualifier. Actually, the IR already has that "no-op" qualifier: abigail::ir::qualified_type_def::CV_NONE. So now "maybe_strip_qualification" just turns the CV_CONST qualifier into a CV_NONE one when the former is redundant. Now that the libabigail type system actually *has* types qualified with this no-op qualifier, we need to handle things like printing the name of such qualified types. When we are printing the name of the type for internal reasons (i.e, for type canonicalization purposes) we need to make a difference between the name of a no-op qualified type and the name of the underlying type of the qualified type, otherwise, the canonicalizer wrongly considers the two types as being equal. But then when we are printing the name of the no-op qualified type for diagnostics reasons, then the name is the same as the name of its underlying unqualified type. * src/abg-dwarf-reader.cc (maybe_strip_qualification): Do not nuke the qualified type. Rather, just turn the redundant const qualifier into a no-op one. * src/abg-comparison.cc (compute_diff_for_types): Look through no-op qualified types. * include/abg-ir.h (decl_base::{peek,set}_temporary_qualified_name): Declare new accessors. * src/abg-ir.cc (decl_base::priv::temporary_qualified_name_): New data member. (decl_base::{peek,set}_temporary_qualified_name): Define new accessors. (qualified_type_def::priv::{temporary_internal_name_, internal_name}): New data members. (qualified_type_def::build_name): For a no-op qualified type, the internal name (which contains the 'none' qualifier) is different from the non-internal name. (qualified_type_def::get_qualified_name): Handle temporary names and non-temporary names in two different caches. Also handle internal and non-internal names in two different caches. This makes four different caches. (qualified_name_setter::do_update): Do not touch the non-internal, non-temporary qualified name cache if the qualified parent name is empty. * tools/abidw.cc (main): change --check-alternate-debug-info to make it *not* display the name/path to the alternate debug info, when it's found. Rather, only --check-alternate-debug-info-base-name keeps displaying the base name of the alternate debug info. * tests/data/test-alt-dwarf-file/test1-libgromacs-debug-dir/*: New test material. * tests/data/Makefile.am: Add the new test material to the build system. * tests/test-alt-dwarf-file.cc (in_out_specs): Take the new test input into account. * tests/data/test-read-dwarf/test1.abi: Adjust. * tests/data/test-read-dwarf/test7.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/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/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. 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
|
86ec69a86d |
Read enum values in the size_t and write them in ssize_t
Make sure to read enum values in the widest possible integer (size_t) but write them (in abixml writer) using a signed type to ease comparison. This makes the runtestreaddwarf pass on 32 bit x86, because we were losing some precision reading enum values using a signed integer. * include/abg-ir.h (enum_type_def::enumerator::get_value): Return a size_t. * src/abg-ir.cc (enum_type_decl::enumerator::get_value): Likewise. * src/abg-dwarf-reader.cc (die_signed_constant_attribute): #if-out this static function that is not used anymore. (build_enum_type): Read the value of the enumerator using a size_t value. * src/abg-reader.cc (build_enum_type_decl): Read the enum value using a long long int. * src/abg-writer.cc (write_enum_type_decl): Write using a ssize_t. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
266fa9288e |
Add --version option to several libabigail tools
This patch changed the revision number of the libabigail library to make it reflect the fact that we are not in "release candidate" mode, before the first 1.0 release. So the revision number is now "rc0". The configuration manager has been updated to support version numbers that are strings, so that it can supports things like "rc0". Then, several libabigail tools have been modified to support the --version option to display their version number. * configure.ac: Set the version revision to "rc0". * doc/manuals/abicompat.rst: Adjust manual for new --version option. * doc/manuals/abidiff.rst: Likewise. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abilint.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-config.h (config::{m_format_minor, m_format_major}): Make these be strings. (config::{get,set}_format_minor_version_number): Make these return strings. (config::{get,set}_format_major_version_number): Make these return or take strings. (abigail_get_library_version): Make this take strings. * src/abg-config.cc (config::config): Adjust. (config::{get,set}_format_major_version_number): Make these return or take strings. (config::{get,set}_format_minor_version_number): Make these return strings. (abigail_get_library_version): Make this take strings. * include/abg-version.h.in: Make the version variables be strings. * src/abg-writer.cc (write_translation_unit): The version numbers are now strings so adjust. * tools/{abicompat,abidiff,abidw,abilint,abipkgdiff,abisym}.cc (options::display_version): New data member. (options::options): Initialize it. (display_usage): Add documentation for new --version option. (parse_command_line): Parse new --version option. (main): Support --version. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
ba980025fb |
Bug 19173 - Abidiff doesn't detect symbol size change in library
It appears that libabigail does not represent the size of ELF symbols, so it doesn't detect when a symbol size changes without impacting the size of the type of said symbol, as described by debug info. It appears that Address Sanitizer as implemented by Clang does change the size of variable symbols when it instruments those variables. And of course, the size of type of said symbols (as described by debug information) remains unchanged. This patch makes Libabigail become aware of symbol sizes, especially for variables. Symbol sizes for functions are ignored for now, because a change in a function symbol size is not an ABI change. The patch makes libabigail detect and report symbol size changes for variables, but looking at the ELF information, independently from the debug information. The patch adjusts the existing tests and adds a new test using the binaries that were filed in the bug report. * include/abg-ir.h (elf_symbol::{elf_symbol, create}): Take a size parameter. (elf_symbol::{get,set}_size): New accessors. * src/abg-ir.cc (elf_symbol::priv::size_): New data member. (elf_symbol::priv::priv): Initialize it. (elf_symbol::{elf_symbol, create}) Take a size parameter. (textually_equals): Compare the size of variable symbols. (elf_symbol::{get, set}_size): New accessors. * src/abg-comparison.cc (maybe_report_diff_for_symbol): New static function. ({function_decl_diff,var_diff}::report): Use it. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab, lookup_symbol_from_symtab) (read_context::lookup_elf_symbol_from_index): Set the size of the elf symbols' internal representation. * src/abg-reader.cc (build_elf_symbol): Read the size attribute if present. * src/abg-writer.cc (write_elf_symbol): Write the size attribute for variable symbols, if it's not zero. * tests/data/test-diff-dwarf/test34-pr19173-libfoo.so: New test input binary. * tests/data/test-diff-dwarf/test34-pr19173-libfoo2.so: Likewise. * tests/data/test-diff-dwarf/test34-pr19173-libfoo-report-0.txt: New reference test output. * tests/data/Makefile.am: Add the new test input binaries to the build system. * tests/test-diff-dwarf.cc (in_out_specs): Add the new test input above to the test harness. * tests/data/test-diff-dwarf/test9-report.txt: Adjust. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * tests/data/test-read-dwarf/test1.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/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.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/test6.so.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
4adbafaa43 |
Pass a bunch of parameters by reference as they ought to be
* include/abg-ir.h (operator==): In the overload for elf_symbol_sptr, pass the parameters by reference. * src/abg-ir.cc (operator==): Do the same at definition site. * src/abg-comparison.cc (maybe_report_diff_for_member): Pass parameters by reference. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
7b35e89315 |
Bug 19139 - DWARF reader doesn't handle garbage in function names
In this bug, the DWARF debug info of the binary (generated by Intel's ICC compiler) has interesting constructs like: [ 6b5a0] subprogram decl_line (data2) 787 decl_column (data1) 15 decl_file (data1) 46 declaration (flag) accessibility (data1) public (1) type (ref4) [ 6b56a] prototyped (flag) name (string) "ldiv" MIPS_linkage_name (string) "ldiv" [ 6b5b6] formal_parameter type (ref4) [ 5f2aa] name (string) "$Ë2" [ 6b5bf] formal_parameter type (ref4) [ 5f2aa] name (string) "$Ë3" Note the strings that make up the name of the formal parameters of the function, near the end: [ 6b5b6] formal_parameter type (ref4) [ 5f2aa] name (string) "$Ë2" [ 6b5bf] formal_parameter type (ref4) [ 5f2aa] name (string) "$Ë3" The strings "$Ë2" and $Ë3" (which are the names of the parameters of the function) are garbage. Libabigail's DWARF reader naively uses those strings as names for the function parameters, in the type of the function. Then, the abixml writer emits an XML document, with these strings as property values, representing the name of the type of the function. And of course, the XML later chokes when it tries to read that XML document, saying that the property is not valid UTF-8. This patch addresses the issue by dropping those garbage names on the floor, for function type names. In that context, any string that is not made of ASCII characters is considered as being garbage, for now. The patch, in the abixml writer, also escapes function parameters names so that they don't contain characters that are not allowed in XML. The abixml reader already handles the un-escaping of the names it reads, so I think there is nothing to do there. Ultimately, I guess I should get the unicode value of the characters of that string, encode the string into UTF-8 and use the result as the name for the parameter. That would mean using UTF-8 strings for function parameter names, and, for all declarations names. But that is too much for worfk too little gain for now. The great majority of the binaries we are dealing with are still using ASCII for declaration names. The patch also introduces a new test harness that runs "abidw --abidiff" on a bunch of input binaries. This harness runs over the binaries that were submitted in this bug report. * include/abg-tools-utils.h (string_is_ascii): Declare new function ... * src/abg-tools-utils.cc (string_is_ascii): ... and define it. * src/abg-writer.cc (write_function_type): Escape forbidden XML characters in function type names. * src/abg-dwarf-reader.cc (build_function_type): If a parameter name is not ascii, drop it on the floor. * tests/data/test-types-stability/pr19139-DomainNeighborMapInst.o: New test input binary. * tests/data/test-types-stability/pr19202-libmpi_gpfs.so.5.0: Likewise. * tests/data/Makefile.am: Add the new binaries above to the build system. * tests/test-types-stability.cc: New test harness. * tests/Makefile.am: Add the new test harness to the build system. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
089b3fc762 |
Support updating a class in the abixml reader
In DWARF, the same class declaration can be present several times but with different "views", that is, it can be present in a first translation unit, but without any member type; then in a subsequent translation unit, its member types are defined. In another, it'll be completely defined, with all its data members and base classes. The DWARF reader knows how to amend the class to add new members to it, as they show up in the debug information. This patch adds the same functionality to the abixml reader. The writer has already started to write class declarations with different "views" too, since it's started to avoid duplicating full class definitions in every translation unit that uses them. Without this patch, abixml misses some class members, and that is a bug. * include/abg-ir.h (class_decl::{find_base_class, find_member_type, find_data_member}): Declare new member functions .. * src/abg-ir.cc (class_decl::{find_base_class, find_member_type, find_data_member}): ... and define them. * src/abg-reader.cc (build_class_decl): Add the ability to update a class to add new data members, member types and base classes to it, if necessary. 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
|
093bc5da06 |
Pass some more parameters in reference
Profiling as shown that we might gain some precious cycles by passing some well chosen parameters by reference. * include/abg-ir.h (operator==): For the type_base_sptr and decl_base_sptr overloads, pass the parameters by reference. ({var,function}_decl::{set,get}_symbol): Pass the elf_symbol_ptr by reference. * src/abg-ir.cc (operator==): For the type_base_sptr and decl_base_sptr overloads, pass the parameters by reference, now in the definition. ({var,function}_decl::{set,get}_symbol): Pass the elf_symbol_ptr by reference, now in the definition. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
7bb65377a5 |
Accelerate a slow path in hash_type_or_decl()
Profiling shows that hash_type_or_decl() is very slow when hashing function parameters and base class specifications. This is because in those two cases we use the slow recursive hashing algorithm to hash types, rather than using the faster one based on using the pointer values of canonical types when possible. This was making corpora comparison very slow, as it uses hash_type_or_decl() to hash diffs of ABI artifacts. This patch fixes that. * include/abg-ir.h (is_function_parameter, is_class_base_spec): Declare new functions. * src/abg-ir.cc (is_function_parameter, is_class_base_spec): Define them. (hash_type_or_decl): Handle hashing of function parameters are class base specifications with the fast path of type hashing. 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
|
f1c48fe80f |
Handle aliased function decls when comparing decls in general
When comparing two declarations, we look at their linkage name. When the linkage names are different, then we infer that the two decls are different. But then, for *function* decls, it can happen that two different linkage names are actually for different symbols that do alias; the (ELF) symbols are different but they have the same address; so they point to the same "thing". The two functions are not different, then. And we were not supporting this last case of diffent linkage names that are aliases of each other. This patch adds support for that. * include/abg-ir.h (is_function_decl): Add a const to the reference parameter, making it comply with the definition. * src/abg-ir.cc (equals): In the overload for decl_base, when the two linkage names are different, consider the case of the decls being aliased functions. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
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
|
0e3416e7e2 |
Bug 19023 - Type canonicalization is sensitive to struct-ness
In some debug info of some shared library, the same type can be present as a struct in some translation units, and as a class in others. As we are using the "pretty representation" of types to hash types during type canonicalization, a "class foo" and "struct foo" are (wrongly) considered different, because those pretty representations are different. This patch changes the canonicalization code to make it independent from the struct-ness of the class being canonicalized. * include/abg-ir.h (class_decl::is_struct): Declare a setter for the "is-struct" property. * src/abg-ir.cc (class_decl::is_struct): And define that setter here. (type_base::get_canonical_type_for): Temporarily set the 'is-struct' flag of the class type to 'false' before building its pretty representation. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so: New test input binary. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: New test reference output. * tests/data/Makefile.am: Add the new test material above to the source distribution. * tests/test-read-dwarf.cc (in_out_specs): Add the two new test inputs to the list of test inputs to consider. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
48801d23e4 |
Bug 19037 - Make ABI corpus support several functions with same symbol
It turns out that, in DWARF, there can be function template instantiations foo<int>(int) and foo<TypedefOfInt>(TypedefOfInt) which have the same symbol name, if TypedefOfInt is a typedef of int. An ABI corpus retains only one function declaration per symbol name. So in the example of the bug the input DWARF has the two instantiations, but libabigail is just keeping one of the two; so the abixml only has one of the two template instantiations. This patch changes the ABI corpus model so that it represents the fact that there can be several function declarations for a given symbol. The patch then adjust the comparison engine to make it know about this new model. * include/abg-corpus.h (corpus::exported_decls_builder::str_{fn,var}_ptr_map_type): Remove these typedefs from here as they only used internally in abg-corpus.cc. So we move them there instead. * src/abg-corpus.cc (str_fn_ptrs_map_type): New typedef. (str_var_ptr_map_type): Moved the typedef that was in corpus::exported_decls_builder here. (corpus::exported_decls_builder::id_fns_map_): Rename the fns_ data member into this. Make it have a str_fn_ptrs_map_type as a type. (corpus::exported_decls_builder::id_fns_map): Renamed the fns_map() accessor into this one. (corpus::exported_decls_builder::{fn_id_is_in_id_fns_map, fn_is_in_fns}): New member functions. (corpus::exported_decls_builder::fn_is_in_id_fns_map): Rename fn_is_in_map into this. (corpus::exported_decls_builder::add_fn_to_id_fns_map): Rename add_fn_to_map into this. (corpus::exported_decls_builder::add_fn_to_exported): Adjust. (corpus::exported_decls_builder::maybe_add_fn_to_exported_fns): Adjust. * src/abg-comparison.cc (function_decl_diff::report): Emit reports about function name changes (for a given function ID) only if there are sub-type changes to be reported for the function. In that case, do not forget to emit the sub-type changes after the name changes have been reported. (corpus_diff::priv::ensure_lookup_tables_populated): Several functions of the same ID can be removed or added from/to the corpus. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so: New test input binary. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: New test output reference. * tests/data/Makefile.am: Add the new test materials to the source distribution. * tests/test-read-dwarf.cc (in_out_specs): Adjust to add the new test inputs above. 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
|
38e17e0e07 |
Cleanup some IR type comparison operators
* include/abg-ir.h (operator==): In the overloads for type_decl, enum and class_decl, turn the shared_ptr parameter into a const reference to the shared_ptr. * src/abg-ir.cc (operator==): Do the same in the definitions. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
da4aaf467a |
Add missing deep equality operator for pointer and reference types
I noticed that abigail::ir::pointer_type_def_sptr and abigail::ir::reference_type_def_sptr did not have any free form operator '==' defined. So writing a == b with a and b being either pointer_type_def_sptr or reference_type_def_sptr was using pointer value comparison, as opposed to deeply comparing the pointer and reference instances. This patch adds those two missing operators. * include/abg-ir.h (pointer_type_def::operator==): Add an overload for pointer_type_def. (reference_type_def::operator==) Add an overload for reference_type_def. (operator==): Add an overload for pointer_type_def_sptr and reference_type_def_sptr. * src/abg-ir.cc (pointer_type_def::operator==): Make the overload for type_base& use the overload for decl_base&. Add a new overload for pointer_type_def& and make is use the overload for decl_base& too. (operator==): Add free form overloads for pointer_type_def& and reference_type_def&. (reference_type_def::operator==): Add comments. Add an overload for reference_type_def&. 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> |
||
Ondrej Oprala
|
9cb146a013 |
Bug 17340 - Support pointers and references to functions
* include/abg-comparison.h (compute_diff_for_distinct_kinds): Take the first two arguments of type const type_or_decl_base_sptr instead. * include/abg-ir.h (translation_unit::get_function_types): Declare new method. (function_types): Declare new typedef. * src/abg-comparison.cc (compute_diff_for_types): Take the first two arguments of type const type_or_decl_base_sptr instead of a const decl_base_sptr. (try_to_diff): Likewise. (try_to_diff<class_decl>): Likewise. (try_to_diff_distinct_kinds): Likewise. (compute_diff_for_distinct_kinds): Likewise. Also remove a variant accepting arguments of type const type_base_sptr. * src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Skip building a pointer if it points to the beginning of a vptr. (build_pointer_type_def): Declare utype_decl of type type_or_decl_base_sptr and adjust assignments to it accordingly. (build_function_type): New function definition. (build_function_decl): Call build_function_type instead of building an ftype manually. (build_ir_node_from_die): Amend case DW_TAG_subroutine_type with appropriate calls to build a function type. * src/abg-ir.cc (translation_unit::get_function_types): New method definition. ({pointer,reference}_type_def::pointer_type_def): Expect that pointed_to might not have an accompanying declaration and set a type's name in this case as well. ({pointer,reference}_type_def::get_qualified_name): Generate a qualified name even if the pointed-to type has no declaration. * src/abg-reader.cc (build_function_type): New function definition. (handle_element_node): Return a type_or_decl_base_sptr instead and try calling handle_function_type in addition to others. (handle_function_type): New function definition that calls build_function_type. (build_type): Try calling build_function_type as well. * src/abg-writer.cc (fn_shared_ptr_map): Declare new typedef. (write_context::{clear_referenced_fntypes_map,fntype_is_referenced, record_fntype_as_referenced}): New member functions. (write_translation_unit): Call the new clear_referenced_fntypes_map. * tests/data/Makefile.am: Add the new test material to the build system. (write_translation_unit): Separately write function types that have been recorded to emit by write_{pointer,reference}_type_def. (write_{pointer,reference}_type_def): Record the type pointed to as a type to be emitted if type == function type. (write_function_type): Write the details of a function type in the abixml format and unmark the type. * tests/data/test-diff-dwarf/test32-fnptr-changes-report-0.txt: New test reference report. * tests/data/test-diff-dwarf/test32-fnptr-changes-v{0,1}.cc: New test source files. * tests/data/test-diff-dwarf/test32-fnptr-changes-v{0,1}.o: New binary test inputs. * tests/data/test-diff-dwarf/test33-fnref-changes-report-0.txt: New test reference report. * tests/data/test-diff-dwarf/test33-fnref-changes-v{0,1}.cc: New test source files. * tests/data/test-diff-dwarf/test33-fnref-changes-v{0,1}.o: New binary test inputs. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: 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/test9-pr18818-clang.so.abi: Likewise. * tests/data/test-read-write/test27.xml: New test source file. * tests/test-diff-dwarf.cc: Adjust to launch the new tests. * tests/test-read-write.cc: Likewise. Signed-off-by: Ondrej Oprala <ooprala@redhat.com> |
||
Ondrej Oprala
|
4ec793b9d0 |
Move a constructor declaration
* include/abg-ir.h (decl_base): Change the decl_base() declaration's visibility to private. Signed-off-by: Ondrej Oprala <ooprala@redhat.com> |
||
Dodji Seketeli
|
4173b2a421 |
Add a missing function declaration
* include/abg-tools-utils.h (dir_name): Add missing function declaration. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
912eb7e36b |
Speed up type canonicalization by avoiding recursive hashing
Recursive type hashing was showing up as the major hot spot of performance profiles. After spending a few days on trying to speed it up, I have officially declared recursive tree node hashing as a slow process and I am giving up. I have thus decided to not use that at type canonicalization time. Rather, I am proposing a new type canonicalization routine where types are first hashed by hashing their pretty representation string. Basically, if T is the total number of types in the system and C the number of classes of equivalences (or the number of canonical types), the number of type comparisons done by a naive type canonicalization routine is N x C. With the worse C being equal to N itself, that worse number of comparisons is N*N. By using a hash table to store the canonical types, keyed by a hash of their pretty representation string, the number of type comparisons can be brought down to N*P, where P is a the greater number of which pretty representation string hash collide. That number P is usually small; my measurements show that N usually goes from 1 to 3. And moreover, computing the hash of the pretty representation string of the function is way faster than using the recursive type hash! As a result, running abidw on the libcilkrts.so library, from GCC goes from 12 minutes to 0.4 seconds! Incidentally, now that we are not trying to speed up the recursive type hashing process, all the complicated business we had around caching the result of the hashing is gone! I was thinking that hash cashing was inherently a bad idea, especially for recursive types -- that refer to themselves directly or indirectly, because in those case, depending on when you cached the hash value, the value of the hashing can be different. The abixml writer's code doesn't use the recursive type hash anymore either; it uses the pointer value of the canonical type as hash. Super fast too! The patch had to fix pieces here and there to comply with the fact that canonical types are now used across the board in a mandatory fashion. * include/abg-ir.h (canonical_types_map_type): Adjust this typedef to make it point to an unordered_map which the key is now a string and the value is a vector of types. (type_or_decl_base::{get_cached_hash_value, set_cached_hash_value, cached_hash}): Remove these member functions and type. (struct type_base::cached_hash): Remove. * src/abg-ir.cc (struct type_or_decl_base::priv::hash_): Remove. (type_or_decl_base::priv::priv): Adjust. (type_or_decl_base::{g,s}et_cached_hash_value): Remove. (type_base::get_canonical_type_for): For declaration-only classes, look at their definition for the canonical_type. Do not use recursive type hashing anymore. Rather, use the pretty representation string, and hash that. (class_decl::base_spec::get_hash): Do away with hash value caching here. (class_decl::operator==): For decl-only classes, look at their definitions for canonical types. (hash_type_or_decl): Adjust comment. Use the canonical type pointer value for type hash. That's the fast path. Otherwise, if not available, fall back to a slow path which is the recursive type hash we were using before. * src/abg-dwarf-reader.cc (maybe_canonicalize_type): Schedule all classes and typedef to classes for late canonicalization. * src/abg-hash.cc (type_base::dynamic_hash::operator()): There is no hash value cashing anymore. (type_base::cached_hash::operator()): Remove. * src/abg-reader.cc (read_context::get_type): Slight style adjustment. (read_translation_unit_from_file) (read_translation_unit_from_buffer): Do not forget to canonicalize types when reading just one translation unit. (build_type_tparameter, build_template_tparameter): Canonicalize the type. * src/abg-writer.cc (struct type_hasher): New hasher type. (type_ptr_map): Use a deep pointer comparison equal operator functor, and canonical types as type hash values. (write_class_decl): Do not write size and alignment on decl-only classes. Do not record decl-only classes as being emitted. Their definition must be emitted before. * tests/test-read-write.cc (main): Do not do abi testing on translation units (as opposed to doing it on abi corpora) as that code is not wet yet. We need to know how to diff namespaces. * tests/data/test-abidiff/test-PR18791-report0.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/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. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |
||
Dodji Seketeli
|
3e146f14ba |
Update qualified name of a decl when it's added to its context
The building of the qualified name of a declaration is showing up in performance profile as a hot spot. This patch addresses that performance issue by updating the qualified name of a declaration whenever the declaration is added to its context and saving the result. Getting the qualified name later is just a matter of a string copy. I guess we can do something about those string copies later as they don't show up high performance profiles at the moment. * include/abg-ir.h (decl_base::priv_): Make this be public, so that the qualified name updater function can access it. (class class_decl): Make set_member_is_static() a friend function. * src/abg-ir.cc (class ::qualified_name_setter): New tree walking type. (decl_base::get_qualified_parent_name): Do not do any computation here. Just return the pre-computed qualified parent name string. (decl_base::get_qualified_name): Likewise, for qualified name. (scope_decl::{add,insert}_member_decl): Update the qualified name of the newly added member. Set the scope of the member here. It's not going to be set elsewhere, from now on. (add_decl_to_scope): Do not set the scope here anymore. Just call scope_decl::add_member_decl and let it do the work. (insert_decl_into_scope): Likewise, just call scope_decl::insert_member_decl and let it do the work. (class_decl::{add_data_member, add_member_function}): Do not handle details of context setting at this point. Let scope_decl::add_member_decl do it. Adjust the properties of the context relation afterwards. In add_data_member, when a data member changes its static-ness, move the data member into the class_decl::priv::non_static_data_members_ or out of it, as necessary. (class_decl::insert_member_decl): By default, a data member is considered static. (set_member_is_static): Move this definition after the definitions of class_decl, so that this function can see those. Also, when a data member changes its static-ness, move the data member into the class_decl::priv::non_static_data_members_ or out of it, as necessary. (class_decl::add_member_function_template): As we the underlying function template decl to the context, do not do any scope adding for it here. (::qualified_name_setter::{do_update, visit_begin}): Define new member functions. (update_qualified_name): Define new static function. * src/abg-reader.cc (build_class_decl): Make build_function_decl, build_var_decl, build_function_tdecl and build_class_tdecl automatically add the created decl to their context, and then update the properties of the resulting member decl later, just like what we do in the DWARF reader. Signed-off-by: Dodji Seketeli <dodji@redhat.com> |