Commit Graph

1067 Commits

Author SHA1 Message Date
Dodji Seketeli
edadded922 A series of small speed optimizations here and there
These are small speed optimizations that are induced by some lesser
hot spot identified by profiling.

	* src/abg-comparison.cc (var_diff::has_changes): Just compare the
	two var_decl.  It's (way) faster now than using recursive hashing
	for that.
	* src/abg-ir.cc (elf_symbol::does_alias): Get out early if the two
	main symbols are equal.
	(equals): In the overload for function_decl, start by comparing
	types.  This can be very fast for functions with different types,
	as it amounts to a pointer comparison.  In the overload for
	class_decl, avoid a map lookup when it's not necessary.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-15 13:50:48 +02:00
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>
2015-10-15 13:50:48 +02:00
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>
2015-10-15 13:50:48 +02:00
Dodji Seketeli
b198333ba7 Set the corpus of all ABI artifact reads from abixml
It turns out we were not setting the corpus for all ABI artifact read
from abixml.  That was preventing the use of the ODR-based speed
optimization during type canonicalization, for corpora built from abixml.

Fixed thus.

	* src/abg-reader.cc (read_translation_unit): Set the current
	corpus to the current translation unit being built.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-15 13:50:48 +02:00
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:

    0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness

But then, that didn't handle the case of composite types which have a
subtype of class type T, where the same T was declared as "struct" and
as "class" in the same binary.

This patch handles that case by passing a flag to the functions that
build the pretty representation of types.  Note that the pretty
representation is used as a key in the hash map that contains
canonical types.  That flag is passed all the way down to the function
that builds the pretty representation for class types, which decides
to use either "struct" or "class" as a previx for the representation.

The type canonicalization code then passes that flag (properly set) to
the pretty representation function.

	* include/abg-fwd.h (get_type_name, get_function_type_name)
	(get_method_type_name, get_pretty_representation): Add an
	"internal" flag to all overoads.
	* include/abg-ir.h
	({type_or_decl_base, decl_base, type_decl, scope_type_decl,
	qualified_type_def, array_type_def, enum_type_decl, typedef_decl,
	var_decl, function_decl, function_decl::parameter, function_type,
	method_type, class_decl}::get_pretty_representation): Add an
	'internal' flag.
	({decl_base, qualified_type_def, pointer_type_def,
	reference_type_def, array_type_def, enum_type_decl::enumerator,
	function_decl::parameter}::get_qualified_name): Likewise.
	(qualified_type_def::build_name): Likewise.
	* src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def,
	reference_type_def, array_type_def, enum_type_decl,
	enum_type_decl::enumerator,
	function_decl::parameter}::get_qualified_name): Take an "internal"
	flag.
	(qualified_type_def::build_name): Likewise.
	({decl_base, type_decl, namespace_decl, array_type_def,
	enum_type_decl, typedef_decl, var_decl, function_type,
	method_type, function_decl,
	class_decl}::get_pretty_representation): Likewise.
	(get_type_name, get_function_type_name, get_method_type_name)
	(get_pretty_representation): Likewise.
	(type_base::get_canonical_type_for): Call
	get_pretty_representation() with the "internal" flag set to
	"true", to get a pretty representation that is independant from
	the struct-ness of the subtypes of the type being canonicalized.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-15 13:50:48 +02:00
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>
2015-10-15 13:50:48 +02:00
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>
2015-10-15 13:50:48 +02:00
Dodji Seketeli
d7c2caf23a Fix "is-anonymous" abixml property impact on some tests
Since we started to rely on ODR for type canonicalization, we needed
to mark anonymous structures (and enums) as being anonymous, hence, a
new "is-anonymous" property was introduced in the abixml format.
While looking at something else, I noticed that some anonymous
structures in test files
tests/data/test-abidiff/test-corpus0-v{0,1}.so.abi were not marked as
anonymous, and that was causing some comparison issues.  This patch
adjusts those abixml files.  I forgot at the time to mention that
those files were coming from the libtirpc.so binary provided in bug
18166, so I am renaming the files now to reflect that.  Also, I am
adding the binary here.  I have thus re-generated a new abixml file
from that *.so file; it now has the proper "is-anonymous" properties.

	* tests/data/test-abidiff/test-PR18166-libtirpc.so: New file.
	* tests/data/test-abidiff/test-PR18166-libtirpc.so.abi: Likewise.
	* tests/data/test-abidiff/test-corpus0-report0.txt: Renamed into
	tests/data/test-abidiff/test-PR18166-libtirpc.so.report.txt.
	* tests/data/test-abidiff/test-corpus0-v{0,1}.so.abi: Removed.
	* tests/data/Makefile.am: Renamed test-corpus0-* files into
	test-PR18166-libtirpc.so-* files.
	* tests/test-abidiff.cc (specs): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-15 13:50:48 +02:00
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>
2015-10-15 13:50:48 +02:00
Dodji Seketeli
7b783500d7 Fix strip_typedef issues
strip_typedef currently has at least two issues.  First, it was
triggering a potentially wrong early canonicalization.  Second, it was
asserting too eagerly that a return type should not be nil; the truth
is that there can be a short period of time where a function has an
empty result type; that is usually during the building of said
function type, before the return type is fully built.

This patch addresses those two issues.

	* src/abg-ir.cc (strip_typedef): Do not canonicalize
	the return type of the method type to typedef-strip.
	Acknowledge that the return type can be nil.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-15 13:50:48 +02:00
Dodji Seketeli
832e6b6366 Force late canonicalizing of function types read from abixml
This is the first patch of a series which aims at fixing:

    Bug 19024 - abidw --abidiff fails and aborts when run against r300_dri.so

The issue reported in that bug is the manifestation of several
problems that different patches in the series address on a case by
case basis.

Suffice it to say abidw --abidiff on my X220 laptop was taking more
than 40 minutes, and north of 11GB or ram.  An rather than yielding
the empty set, it was emitting lots of false postives!

The patchset thus applies a series of optimizations to reduce the time
and memory taken, so that I can at least debug the issues that prevent
abidw --abidiff from yielding the empty set, as it should.  Then, with
those optimizations applied, I came up with a series of fixes.

With the series applies, abidw --abidiff now takes less than 8 minutes
and around of 4.8GB of ram.

The first seven patches are those fixes.  The next five patches are
the time and size optimization that allowed me to work on the first
fixes.  The thirteenth patch applies some needed modification (both
fixes and improvements) to abidw --abidiff itself. The last patch
carries the necessary adjustments to the regression tests output.

Here are the short titles of the patches of the set, including this one:

    Force late canonicalizing of function types read from abixml
    Fix strip_typedef issues
    Do not compare access specs for member types & functions
    Fix "is-anonymous" abixml property impact on some tests
    Fix const-ness of a function parameter
    Handle aliased function decls when comparing decls in general
    Make canonicalization non sensitive to struct-ness of subtypes
    Set the corpus of all ABI artifact reads from abixml
    Implement fast type lookup in a corpus
    Accelerate a slow path in hash_type_or_decl()
    A series of small speed optimizations here and there
    Allow only one definition of a given type per corpus in abixml
    Make abidw --abidiff not show definitely harmless changes
    Adjust tests for the patchset

We do not add the r300_dri.so library to the repository because of the
time it still takes to complete.

And now, here is the cover letter for this first patch.

When reading the abixml format, sometimes, function types can be
early-canonicalized.  This can be wrong especially is the function
type has sub-types that are not canonicalized yet.

So this patch forces those to be late-canonicalized.

	* src/abg-reader.cc (build_function_type): Late-canonicalize
	function types.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-15 13:49:25 +02:00
Ondrej Oprala
b2a5bf6389 Bug 19082 - Recognize suppression spec files
When abipkgdiff is invoked on a set of packages, the newer (second) one is also
inspected for files matching the pattern '*.abignore', whose contents are read
and interpreted as suppression specifications.

	* tests/data/Makefile.am: Add new test material to the build system.
	* tests/data/test-diff-pkg/dirpkg-{0-dir1,{1,2}-dir2}/dir.abignore:
	A test suppression specification.
	* tests/data/test-diff-pkg/dirpkg-{2,3}-dir2/.abignore: Likewise.
	* tests/data/test-diff-pkg/dirpkg-3.suppr: Likewise.
	* tests/data/test-diff-pkg/dirpkg-{1,2,3}-dir{1,2}/libobj-v0.so: New
	binary test inputs.
	* tests/data/test-diff-pkg/dirpkg-{1,2,3}-dir{1,2}/obj-v0.cc: New test
	source files
	* tests/data/test-diff-pkg/dirpkg-{1,2,3}-report-{0,1}.txt: New
	reference outputs
	* tests/test-diff-pkg.cc: Adjust to run the new tests.
	* tools/abipkgdiff.cc (prog_options): New static pointer to struct
	opts.
	(file_tree_walker_callback_fn): Rename to
	first_package_tree_walker_callback_fn.
	(second_package_tree_walker_callback_fn): Check for ELF files just
	like the previous function but additionally check for files
	ending with ".abignore", unless disabled from the command line.
	({create_maps_of_package,extract_package_and_map_its}_content):
	Add a callback as a new argument.
	(main) handle the new "--no-abignore" option, which turns off
	the search for suppression files within the new package.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-10-13 09:19:47 +02:00
Dodji Seketeli
efeb4e2a8a Bug 19024 - Failing to flag underlying type of enums as anonymous
The for now, the underlying type of an enum type is always assumed to
be anonymous by libabigail.  But then, the code of the DWARF reader
was failing to set the "is-anonymous" flag on it.  So type
canonicalizing code was comparing the enum underlying types by looking
at their names; they all have the same name -- as we forget that they
are anonymous; so they (wrongly) all look the same, within the same
ABI corpus.

This patch sets properly sets the is-anonymous flag on enumerator
underlying types again.

	* src/abg-dwarf-raeder.cc (build_enum_type): Set the is-anonymous
	flag on the underlying type of the enum.
	* tests/data/test-read-dwarf/test0.abi: 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.
	* 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.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-11 13:54:24 +02:00
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>
2015-10-08 13:50:49 +02:00
Ondrej Oprala
fcea5dffce Parallelize test read-dwarf.
* tests/Makefile.am: Link runtestreaddwarf with libpthread.
	* tests/test-read-dwarf.cc (main) Create worker threads corresponding
	to the number of CPUs online, add a "--no-parallel" option and move
	the main loop...
	(handleInOutSpec) ...here.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-10-07 11:07:58 +02:00
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>
2015-10-07 00:41:32 +02:00
Dodji Seketeli
ca6a5147c6 Style adjustment in abg-corpus.cc
* src/abg-corpus.cc (corpus::exported_decls_builder::id_var_map_):
	Renamed data member vars_map_ into this.
	(corpus::exported_decls_builder::id_var_map): Renamed vars_map
	into this.
	(corpus::exported_decls_builder::var_id_is_in_id_var_map): Renamed
	var_is_in_map into this.
	(corpus::exported_decls_builder::{add_var_to_map,
	add_var_to_exported, maybe_add_var_to_exported_vars}): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-06 13:32:13 +02:00
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>
2015-10-06 13:32:12 +02:00
Ondrej Oprala
81b028641a Do not imply private access when building a struct from ABIXML.
* src/abg-reader.cc (read_context): Abort if we run into an
	unsupported access specifier.
	(build_class_decl) Default to public access for the children
	of a struct.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-10-05 15:11:02 +02:00
Ondrej Oprala
5115d16241 Fix minor warnings when building documentation.
* manuals/abilint.rst: Fix the "Literal block expected" warning.
	* manuals/abipkgdiff.rst: Fix the "Title underline too short" warning.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-10-05 09:27:16 +02:00
Ondrej Oprala
99cc564fe1 Fix an "Unknown target name" error during make info.
* doc/manuals/libabigail-overview.rst: Fix the reference to
	"ELF symbols".

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-10-05 08:35:57 +02:00
Ondrej Oprala
9e0bc5e617 Fix a path in doc/Makefile.am
* doc/Makefile.am: Prefix the path for DOXY_WEBSITE_SRC_CFG and
	DOXY_WEBSITE_BLD_{CFG,DIR} with "/doc" to protect it against make
	clean.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-10-05 08:03:35 +02:00
Dodji Seketeli
8ae8472825 Misc style cleanups
* src/abg-reader.cc (read_is_struct): Fix comment.
	(build_type_decl): Use type_decl_sptr rather than
	shared_ptr<type_decl>.
	(build_type_decl): Use typedef_decl_sptr rather than
	shared_ptr<typedef_decl>.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-04 13:53:26 +02:00
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>
2015-10-04 13:52:25 +02:00
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>
2015-10-04 13:51:25 +02:00
Dodji Seketeli
c20c8c79e7 Fix infinite loop in peel_typedef_pointer_or_reference_type
* src/abg-ir.cc (peel_typedef_pointer_or_reference_type): Make
	sure the variable tested in the condition is the one updated by
	the loop.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-04 13:51:25 +02:00
Dodji Seketeli
4d0d387696 Try harder to hash_type_or_decl avoid the slow path
In hash_type_or_decl, when we encounter a declaration-only class
(those have no canonical type), we not trying to get the canonical
type of the definition, when the class had a definition.  We were
instead going straight to the slow path of computing the recursive
hash of the type.

This patch tries to get the canonical type of the class definition,
when it exists.

	* src/abg-ir.cc (hash_type_or_decl):  When a declaration-only
	class has a definition, then use the canonical type of that
	definition as a hash value.  If the class no definition, only
	then, use the slow patfh of computing the recursive progressive
	hash value of the type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-04 13:51:25 +02:00
Dodji Seketeli
8b76f6c34e Do not use recursive type hashing when writing out function types
When the abixml writer emits function types, it puts function
types that are referenced by pointers or references into a map on the
side.  Unfortunately, that map hashes types by recursively calculating
a progressive hash value.  That is dog slow and we avoid that
throughout the code base.

This patch changes that to use the numerical values of the canonical
type pointer of the function type as a hash, making abixml fast again,
again on big library as libmozjs.so.

	* src/abg-writer.cc (typedef fn_shared_ptr_map): Remove.
	(write_context::m_referenced_fntypes_map): Change the type of this
	into type_ptr_map.
	(write_context::{record_fntype_as_referenced,
	fntype_is_referenced}): Use the pointer value of the canonical
	type of the referenced type as key for the map.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-04 13:51:25 +02:00
Dodji Seketeli
501c514245 Prevent build_function_type from not canonicalizing certain types
I noticed that in some cases in build_function_type, when building the
sub-types of the function type, the construction of a function type
for the same DIE could be triggered.  This happens frequently for
aggregate types that happen to be recursive.  In those cases, we must
arrange for the construction of the function type for the same DIE to
return the same type that is being currently built by
build_function_type; otherwise, several types are going to be built
for the same DIE, and only one of them is going to be canonicalized.
build_function_type was just not prepared for this.

This patch fixes that.

Please note that the patch changes the test output
/home/dodji/git/libabigail.git/merge/build/tests/output/test-read-dwarf/test12-pr18844.so.abi
but it's a later patch that adjust that file because several patches
are going to require an update to that file.  We are going to update
that patch in one go at the end of the patch series.

	* src/abg-dwarf-reader.cc (build_function_type): Associate the
	type being built with its DIE, before starting to build the
	sub-types.  The current type is then amended with the sub-types
	that are built later.
	(build_ir_node_from_die): In the case for DW_TAG_subroutine_type,
	do not associate the type to the DIE here, as it's been done in
	build_function_type.
	* src/abg-ir.cc (function_type::set_parameters): Adjust the index
	of the parameters being set to the function: they start at 1,
	unless the first parameter is artificial, in which case its index
	starts at zero.  This is just like what is done when the function
	type is constructed directly with the parameters passed as an
	argument to the constructor.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-04 13:51:25 +02:00
Dodji Seketeli
21e159a66e Fix detection of changes in pointer diff in the comparison engine
* src/abg-comparison.cc (pointer_diff::has_changes): Just
	comparing the underlying type might not be enough.  Let's just
	compare the pointer itself.  Now that we have canonical types,
	comparing the pointer itself is not slower.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-04 13:51:25 +02:00
Dodji Seketeli
d208e0e6c2 Do not overly canonicalize types during typedef stripping
strip_typedef() canonicalizes the stripped typed, even if the input
type was not canonicalized.  This can lead to early canonicalization
that is not warranted.  For instance, is_compatible_with_class_type()
calls strip_typedef() and can be called during DWARF reading on types
that haven't been canonicalized yet; this was triggering a
canonicalization what was happening too early.

With this patch, strip_typedef() does not canonicalize a stripped type
if the input type wasn't itself canonicalized.

	* src/abg-ir.cc (strip_typedef): Do not canonicalize the stripped
	type if the input one is not canonicalized.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-04 13:51:25 +02:00
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>
2015-10-04 13:51:24 +02:00
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>
2015-10-04 13:51:24 +02:00
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>
2015-10-04 13:40:51 +02:00
Ondrej Oprala
910672f8c2 Bug 19027 - ABI asymmetry with enums over INT_MAX
* src/abg-reader.cc (build_enum_type_decl): Use strtol
	instead of atoi to parse the values and check for overflow.
	* tests/data/Makefile.am: Add the new test material to the build
	system.
	* tests/data/test-read-dwarf/test17-pr19027.so: New test file.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/test-read-dwarf.cc: Adjust to launch the new test.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-10-01 11:40:52 +02:00
Dodji Seketeli
1354bcf59b Encourage people to use autoreconf -i
This lets autoreconf add stuff that might be missing, rather than just
bailing out.

	* COMPILING: Mention autoreconf -i, rather than just autoreconf.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-01 10:40:51 +02:00
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>
2015-09-30 21:20:42 +02:00
Ondrej Oprala
116a65c653 Generalize some dwarf-reader functions to generate and return
instances of type_or_decl_base_stpr to be able to propagate
types occurring without an accompanying declaration.

	* src/abg-dwarf-reader.cc (build_ir_node_from_die): Return
	a type_or_decl_base_sptr instead.
 	(get_scope_for_die): Likewise.
	(build_class_type_and_add_to_ir): Typecast the assignment from
	build_ir_node_from_die properly.
	(build_{qualified,reference,array,typedef}_type): Likewise.
	(build_pointer_type_def): Likewise.
	(build_{var,function}_decl): Likewise.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-09-29 14:53:16 +02:00
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>
2015-09-29 11:26:08 +02:00
Dodji Seketeli
d0b8ef6521 Bug 18535 - abidiff reports false positive ABI difference for libstdc++
When the DWARF reader of libabigail sees a data member for a given
class flagged as being a declaration, it considers the declaration as
being a definition.  The reason why it doesn't strictly trust the
"is_declaration" flag of DWARF is that some DWARF producers sometimes
wrongly emit that flag.

But then, it turns out that a class declaration can have a *static*
data member without loosing its declaration-only property.  This patch
thus changes the behaviour of the DWARF reader to make it consider the
class declaration as being a definition when the class has a
*non-static* data member; a static data member only is not enough to
make the class declaration become a definition.

	* src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): The
	presence of a data member shouldn't make a declaration-only class
	loose its declaration-only-ness; the presence of a enon-static*
	data member should.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-4.8.3.so:
	New binary test input.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-4.9.2.so:
	Likewise.
	* tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt:
	New test reference output.
	* tests/data/Makefile.am: Add the new test material to the build
	system.
	* tests/test-diff-filter.cc (in_out_specs): Add the new test
	inputs to the set of inputs to consider.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-24 11:51:56 +02:00
Dodji Seketeli
8e05364ac5 Remove duplicated runtestreaddwarf test
* tests/Makefile.am: Remove one copy of the runtestreaddwarf test
	that is present twice.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-21 15:23:14 +02:00
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>
2015-09-21 15:22:35 +02:00
Dodji Seketeli
133d0e491d Remove some dead code in abilint
* tools/abilint.cc (options::bidiff): Remove.
	(options::options): Adjust.
	(display_usage): Remove usage string for --bidiff
	(parse_command_line): Remove parsing of un-implemented option
	--bidiff.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-21 15:20:10 +02:00
Dodji Seketeli
bd0926a2b5 Add a new --abidiff option to abidw
This is a debugging and sanity check option.  It saves the abi of the
ELF binary to a temporary file, reads it back and compares the abis of
the temporary file against the abi of the input ELF binary.

	* tools/abidw.cc (options::abidiff): New data member.
	(options::options): Initialize it.
	(display_usage): Add a usage string for the new --abidiff option.
	(parse_command): Parse the new --abidiff options.
	(main): Save the abi of the input elf in a temporary abixml file;
	read it back and compare both.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-21 15:14:26 +02:00
Dodji Seketeli
de93cb442f Misc style fixes
* src/abg-hash.cc (class_decl:#️⃣:operator()): Use a temporary
	variable to ease debugging.
	* src/abg-reader.cc (read_context::is_wip_type): Make this
	function const.
	* src/abg-writer.cc (write_context): Move data members at the top.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-21 14:49:29 +02:00
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>
2015-09-21 13:51:31 +02:00
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>
2015-09-21 12:58:06 +02:00
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>
2015-09-21 10:53:33 +02:00
Dodji Seketeli
46c263fbae Constify some diff-utils functor operators
* include/abg-diff-utils.h (deep_ptr_eq_functor::operator()): Make
	the overloads be const.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-21 10:46:06 +02:00
Dodji Seketeli
16299395d7 Support source_location_not_in and source_location_not_regexp suppressions
This patch adds support for properties source_location_not_in and
source_location_not_regexp in the [suppress_type] section of
suppression specifications.  So the suppression specification:

  [suppress_type]
    source_location_not_in = foo1.h, foo2.h bar1.h bar2.h

suppresses ABI change reports about types that are *NOT* defined in
files foo{1,2}.h and bar{1,2}.h.  The intended use of this construct is to
constrain abi change reports to types that are part of the API of a
given shared library.  The API of the library is supposed to be
defined in foo.h and bar.h only.

Similarly, the suppression specification:

  [suppress_type]
    source_location_not_regexp = (foo|bar){1,2}\\.h

suppresses ABI change reports about types that are not defined in the
same set of files foo1.h, foo2.h, bar1.h and bar2.h.

	* include/abg-ini.h (enum property_value::value_kind): Add a
	LIST_PROPERTY_VALUE kind.
	(class {list_property_value, list_property}): Declare new types.
	(is_list_property, is_list_property_value): Declare new functions.
	* src/abg-ini.cc (struct list_property_value::priv): Define new
	type.
	(list_property_value::{list_property_value, get_content,
	set_content, as_string}): Define new member functions.
	(is_list_property_value): Define new function.
	(struct list_property::priv): Define new type.
	(list_property::{list_property, get_value, set_value,
	handle_escape}): Define new member functions.
	(is_list_property): Define new function.
	(read_context::buf_): New data member.
	(read_context::{peek, get, put_back, good, eof, read_string,
	read_list_property_value}): New member functions.
	(read_context::read_next_char): Use the new read_context::{get,
	good, eof} member function, rather than using the input stream
	directly.
	(read_context::{skip_white_spaces, skip_comments,
	skip_white_spaces_or_comments, read_property_name,
	read_function_name, read_function_argument,
	read_function_call_expr, read_property_value,
	read_tuple_property_value, read_section_name, read_section}):
	Adjust to use the new member functions of read_context rather than
	using the input stream directly.
	(read_context::read_string_property_value): Likewise.  Use the new
	read_context::read_string() method.
	(read_context::{read, write}_property): Support reading list_property.
	* include/abg-comparison.h
	(type_suppression::{get_source_locations_to_keep,
	set_source_locations_to_keep,
	set_source_location_to_keep_regex_str,
	get_source_location_to_keep_regex_str}): Add new member functions.
	* src/abg-comparison.cc
	(type_suppression::priv::{source_location_to_keep_,
	source_location_to_keep_regex_str_,
	source_location_to_keep_regex_}): Add new data members.
	(type_suppression::priv::{g,s}et_source_location_to_keep_regex):
	Define new member functions.
	(type_suppression::{g,s}et_source_locations_to_keep): Define new
	member functions.
	(type_suppression::{g,s}et_source_location_to_keep_regex_str):
	Likewise.
	(type_suppression::suppresses_type): Support
	"source_location_not_regexp" and "source_location_not_in"
	properties of suppression specifications.
	(read_type_suppression): Likewise. Also adjust to the fact that
	ta tuple property value that is a list of strings is not a list
	property value.
	* doc/manuals/libabigail-concepts.rst: Add documentation for
	source_location_not_in and source_location_not_regexp.
	* tests/data/test-diff-suppr/libtest26-loc-suppr-v{0,1}.so: New
	binary test inputs.
	* tests/data/test-diff-suppr/test26-loc-suppr-{0,1,2}.suppr: New
	suppression specification test inputs.
	* tests/data/test-diff-suppr/test26-loc-suppr-report-{0,1,2,3}.txt:
	New test reference reports.
	* tests/data/test-diff-suppr/test26-loc-suppr-v{0,1}.cc: Source
	code of the test binary input above.
	* tests/data/test-diff-suppr/test26-loc-suppr.h: Likewise.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.
	* tests/test-diff-suppr.cc (in_out_specs): Add the new test inputs above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-16 20:54:40 +02:00