libabigail/include/abg-comparison.h
Dodji Seketeli c32b8ec9f3 Bug 24690 - Support comparing non-reachable types of a binary
This patch adds the ability to compare all types of a binary,
including those types that are not reachable from global functions and
variables.

This implies that for types that are not reachable from public
interfaces, we want compare them against each others directly, without
first comparing global functions/variables and walking the graph of
reachable types from there.

The patch adds the --non-reachable-types option to abidiff and
abipkgdiff, instructing them to also compare types that are
non-reachable from global variables and functions.

Using that option, for instance, here is what the summary of
abipkgdiff now looks like, in the test case attached added by this
patch:

================ changes of 'libflatpak.so.0.10204.0'===============
  Functions changes summary: 0 Removed, 0 Changed (16 filtered out), 16 Added functions
  Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
  Unreachable types summary: 3 removed (2 filtered out), 1 changed (15 filtered out), 3 added (1 filtered out) types

You can see that there is a new summary line which starts with the
string: "Unreachable types summary:"

Then in the body of the report, those unreachable types are reported
separately.

In practise, we want to limit the unreachable types to compare
somehow, otherwise we'll end up comparing all the types of the types
of the binary and that can be huge.  So we want to limit the
unreachable type analysis to types that are defined in public headers.

So, for abipkgdiff, one can limit the analysis of non-reachable types
to those defined in public headers by supplying the --devel{1,2}
options that specifies the development packages that contain said
public headers.  For abidiff however, you'll want to use the
--headers-dir{1,2} options for that.

The patch comes with appropriate regression tests.

	* include/abg-comparison.h (string_type_base_sptr_map): Define new
	typedef.
	(diff_context::show_unreachable_types): Declare new member
	functions.
	(corpus_diff::{deleted_unreachable_types,
	deleted_unreachable_types_sorted, added_unreachable_types,
	added_unreachable_types_sorted, changed_unreachable_types,
	changed_unreachable_types_sorted}): Likewise.
	(maybe_report_unreachable_type_changes): Declare this function a
	friend of class corpus_diff.
	(corpus_diff::diff_stats::{num_added_unreachable_types,
	num_added_unreachable_types_filtered_out,
	net_num_added_unreachable_types, num_removed_unreachable_types,
	num_removed_unreachable_types_filtered_out,
	net_num_removed_unreachable_types, num_changed_unreachable_types,
	num_changed_unreachable_types_filtered_out,
	net_num_changed_unreachable_types}): Likewise.
	* src/abg-comparison-priv.h
	(diff_context::priv::show_unreachable_types_): Define new data
	member.
	(diff_context::priv::priv): Initialize the new data member.
	(diff_comp::operator()): Use pretty representation of diff
	subjects to sort them, rather than just their name.  Also, add
	comment to the other member functions of diff_comp.
	(corpus_diff::{unreachable_types_edit_script_,
	deleted_unreachable_types_, deleted_unreachable_types_sorted_,
	suppressed_deleted_unreachable_types_, added_unreachable_types_,
	added_unreachable_types_sorted_,
	suppressed_added_unreachable_types_, changed_unreachable_types_,
	changed_unreachable_types_sorted_}): Define new data members.
	(corpus_diff::priv::apply_supprs_to_added_removed_fns_vars_unreachable_types):
	Changed the name of
	corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars into
	this.
	(corpus_diff::priv::{added_unreachable_type_is_suppressed,
	deleted_unreachable_type_is_suppressed,
	changed_unreachable_types_sorted, count_unreachable_types}):
	Declare new member functions.
	(corpus_diff::diff_stats::priv::{num_added_unreachable_types,
	num_added_unreachable_types_filtered_out,
	num_removed_unreachable_types,
	num_removed_unreachable_types_filtered_out,
	num_changed_unreachable_types,
	num_changed_unreachable_types_filtered_out}): Define new data
	members.
	(sort_string_type_base_sptr_map): Declare new function.
	* src/abg-comparison.cc (sort_string_type_base_sptr_map)
	(diff_context::show_unreachable_types): Define new functions.
	(corpus_diff::diff_stats::{num_added_unreachable_types,
	num_added_unreachable_types_filtered_out,
	net_num_added_unreachable_types,
	net_num_removed_unreachable_types,
	num_removed_unreachable_types_filtered_out,
	num_removed_unreachable_types}): Define new member functions.
	(diff_maps::insert_diff_node): Do not update the map "diff ->
	impacted interfaces" if the current impacted interface is nil.
	This happens if we are looking at a diff node for a change on a
	type that is not reachable from any interfaces.
	(corpus_diff::priv::ensure_lookup_tables_populated): Handle the
	edit script for unreachable types.
	(corpus_diff::priv::apply_supprs_to_added_removed_fns_vars_unreachable_types):
	Rename
	corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars
	into this.  Apply suppression specifications to added and removed
	unreachable types as well.
	(corpus_diff::priv::{added,deleted}_unreachable_type_is_suppressed):
	Define new member functions.
	(corpus_diff::priv::{count_unreachable_types,
	changed_unreachable_types_sorted}): Likewise.
	(corpus_diff::priv::apply_filters_and_compute_diff_stats): Update
	statistics (including walking changed unreachable types to apply
	categorization and redundancy filters to them) related to
	unreachable types.
	(corpus_diff::priv::emit_diff_stats): Emit diff stats related to
	unreachable types.
	(corpus_diff::priv::maybe_dump_diff_tree): Dump diff tree nodes
	related to unreachable types.
	(corpus_diff::{deleted_unreachable_types,
	deleted_unreachable_types_sorted, added_unreachable_types,
	added_unreachable_types_sorted, changed_unreachable_types,
	changed_unreachable_types_sorted): Define new member functions.
	(corpus_diff::has_changes): Take deleted/added/changed unreachable
	types into account.
	(corpus_diff::has_incompatible_changes): Take net removed/changed
	unreachable types into account.
	(corpus_diff::has_net_subtype_changes): Take net removed and
	changed unreachable types into account.
	(corpus_diff::has_net_changes): Take net removed/added/changed
	unreachable types into account.
	(corpus_diff::traverse): When traversing the components of a
	corpus_diff node, make sure to traverse the changed unreachable
	types of the corpus.
	(leaf_diff_node_marker_visitor::visit_begin): Arrange for the fact
	that the current topmost interface can be nil if we are looking at
	types not reachable from global functions/variables.  Also, make
	sure that only leaf nodes that are reachable from a global
	function/variable are recorded as leaf nodes.
	(compute_diff): In the overload for corpus_sptr, compute the
	changes between types not reachable from global functions and
	variables, if the user wishes that we do so.  Also, add more
	comments.
	(apply_suppressions): Update for the name change of the function
	apply_suppressions_to_added_removed_fns_vars to
	apply_supprs_to_added_removed_fns_vars_unreachable_types.
	* include/abg-corpus.h
	(corpus::{record_type_as_reachable_from_public_interfaces,
	type_is_reachable_from_public_interfaces,
	get_types_not_reachable_from_public_interfaces}): Declare new
	member functions.
	(corpus::recording_types_reachable_from_public_interface_supported):
	Declare new virtual member function.
	(corpus_group::get_public_types_pretty_representations): Declare
	new member functons.
	(corpus_group::recording_types_reachable_from_public_interface_supported):
	Declare new virtual member function.
	* src/abg-corpus-priv.h
	(corpus::priv::{types_not_reachable_from_pub_ifaces_,
	pub_type_pretty_reprs_}): Define new data members.
	(corpus::priv::priv): Initialize the pub_type_pretty_reprs_ data
	member because it's a pointer.
	(corpus::priv::get_public_types_pretty_representations): Declare
	new member function.
	(corpus::priv::~priv): Declare a destructor.
	* src/abg-corpus.cc
	(corpus::priv::get_public_types_pretty_representations): Define
	new member function.
	(corpus::priv::~priv): Define new destructor to delete the new
	pub_type_pretty_reprs_ member pointer.
	(corpus::{record_type_as_reachable_from_public_interfaces,
	type_is_reachable_from_public_interfaces,
	get_types_not_reachable_from_public_interfaces,
	recording_types_reachable_from_public_interface_supported}):
	Define new member functions
	(corpus_group::get_public_types_pretty_representations): Likewise.
	* include/abg-diff-utils.h (struct deep_ptr_eq_functor): Document
	the equality operator.  Also, add an overload to the equality
	operator, for weak_ptr<T>.  The existing equality operator
	overload was just for shared_ptr<T>.
	* include/abg-fwd.h (is_user_defined_type): Declare function.
	* include/abg-ir.h (operator!=(const decl_base_sptr&, const
	decl_base_sptr&)): Declare new operator.
	(type_maps::get_types_sorted_by_name): Declare
	new member function.
	(decl_base::{g,s}et_is_artificial): Declare new member function.
	(function_decl::parameter::{g,s}et_artificial): Remove these
	member functions.
	* src/abg-ir.cc (operator!=(const decl_base_sptr&, const
	decl_base_sptr&)): Define new operator.
	(decl_base::priv::is_artificial_): Define new data
	member.
	(type_maps::priv::sorted_types_): Define new data member.
	(struct type_name_comp): Define new comparison functor to sort
	types based on their pretty representations.
	(decl_base::priv::priv): Initialize it.
	(decl_base::{g,s}et_is_artificial): Define new member functions.
	(type_maps::get_types_sorted_by_name): Define new member function.
	(is_user_defined_type): Define new function overloads.
	(strip_typedef, function_type::{function_type, set_parameters}):
	Adjust using decl_base::get_is_artificial rather than
	function_decl::parameter::get_artificial.
	(function_decl::parameter::priv::artificial_): Remove this data
	member.
	(function_decl::parameter::priv::priv): Adjust to the removal of
	function_decl::parameter::priv::artificial_.  This constructor
	does not take an "is_artificial" flag anymore.
	(function_decl::parameter::parameter): Adjust to the removal of
	the is_artificial flag from the arguments of the constructor of
	function_decl::parameter::parameter::priv.
	(function_decl::parameter::get_artificial): Remove this member
	function.
	* src/abg-reporter-priv.h (maybe_report_unreachable_type_changes):
	Declare new function.
	* src/abg-reporter-priv.cc
	(maybe_report_unreachable_type_changes): Define new function.
	* src/abg-default-reporter.cc (default_reporter::report): In the
	overload for corpus_diff&, report added/removed/changed types that
	are not reachable from global functions and variables using the
	new function maybe_report_unreachable_type_changes.
	* src/abg-leaf-reporter.cc (leaf_reporter::report): In the
	overload for corpus_diff, report changes to types unreachable from
	global functions or variables, using the new function
	maybe_report_unreachable_type_changes.
	* src/abg-dwarf-reader.cc (build_ir_node_from_die): When the user
	requests that all types be loaded, record relevant types as
	reachable from global functions and variables.
	(build_enum_type, add_or_update_class_type)
	(add_or_update_union_type): Read the 'is-artificial' DWARF
	attribute and set the corresponding decl_base property
	accordingly.
	(finish_member_function_reading, strip_typedef)
	(function_type::function_type): Adjust using
	decl_base::get_is_artificial, rather than
	function_decl::parameter::get_artificial.
	* include/abg-reader.h
	(consider_types_not_reachable_from_public_interfaces): Declare new
	function.
	* src/abg-reader.cc
	(read_context::m_tracking_non_reachable_types): Add new data
	member.
	(read_context::read_context): Initialize it.
	(read_context::tracking_non_reachable_types): Define accessors for
	the new data member above.
	(read_is_declaration_only): Re-indent.
	(read_is_artificial): Define new helper function.
	(build_function_parameter): Use the new read_is_artificial
	function here, rather than open-coding it.
	(build_enum_type_decl, build_class_decl, build_union_decl):
	Support reading the 'is-artificial' property by using the new
	read_is_artificial function.
	(read_corpus_from_input): If the user wants us to take
	non-reachable types into account, then make sure we do so.
	(read_tracking_non_reachable_types, read_is_non_reachable_type):
	Define new static functions.
	(handle_element_node, build_type): Read the "is-non-reachable"
	attribute on type element nodes if the user wants us to track
	non-reachable types.
	(consider_types_not_reachable_from_public_interfaces): Define new
	function.
	* src/abg-writer.cc (write_is_artificial): Define new static
	helper function.
	(annotate): Adjust using decl_base::get_is_artificial rather than
	function_decl::parameter::get_artificial.
	(write_enum_type_decl, write_class_decl_opening_tag)
	(write_union_decl_opening_tag): Support writing the
	"is-artificial" property, using the new write_is_artificial
	function.
	(write_function_type): Adjust this to use the new
	write_is_artificial rather than open-coding writing the
	'is-artificial' attribute.
	(write_is_non_reachable)
	(write_tracking_non_reachable_types): Define new static functions.
	(write_enum_type_decl, write_class_decl_opening_tag)
	(write_union_decl_opening_tag): Write the 'is-no-reachable'
	attribute when applicable.
	(write_corpus, write_corpus_group): Write the
	'tracking-non-reachable-types' attribute when applicable.
	* tools/abidiff.cc (options::options): Initialize ...
	(options::show_all_types): ... new data member.
	(display_usage): Add help string from the new
	--non-reachable-types option.
	(parse_command_line): Parse the new --non-reachable-types option.
	(set_diff_context_from_opts): Set the
	dwarf_reader::read_context::show_unreachable_types property.
	(set_native_xml_reader_options): Define new
	static function.
	(main): Load all types when analyzing the DWARF or the ABIXML
	files, if the user wants us to do so.
	* tools/abipkgdiff.cc (options::show_all_types): Define new data
	member.
	(options::options): Initialize it.
	(parse_command_line): Parse the --non-reachable-types option to
	set the options::show_all_types data member.
	(display_usage): Add a help string for the new
	--non-reachable-types option.
	(set_diff_context_from_opts): Set the
	dwarf_reader::read_context::show_unreachable_types property based
	on the options::show_all_type data member.
	(compare): Configure the read context to load all types while
	analyzing the DWARF info, depending on the options::show_all_type
	data member.
	* doc/manuals/abidiff.rst: Document the new --non-reachable-types
	option added to abidiff above.
	* doc/manuals/abipkgdiff.rst: Add documentation for the
	--non-reachable-types option.
	* tests/data/test-diff-suppr/test47-non-reachable-types-v{0,1}.c:
	Source code files of test binary input.
	* tests/data/test-diff-suppr/test47-non-reachable-types-suppr-{1,2,3,4,5}.txt:
	New test input files.
	* tests/data/test-diff-suppr/test47-non-reachable-types-report-{1,2,3,4,5,6,7,8,9,10}.txt:
	New test reference output files.
	* tests/data/test-diff-suppr/test47-non-reachable-types-v{0,1}.o.alltypes.abixml:
	New test input abixml.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.
	* tests/test-diff-suppr.cc (in_out_specs): Add the new tests above
	to this test harness.
	* tests/data/test-abidiff/test-struct1-report.txt: Adjust.
	* tests/data/test-diff-pkg/PR24690/flatpak-debuginfo-1.2.4-3.fc30.x86_64.rpm:
	New input binary RPM.
	* tests/data/test-diff-pkg/PR24690/flatpak-debuginfo-1.4.0-1.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-devel-1.2.4-3.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-devel-1.4.0-1.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-libs-1.2.4-3.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-libs-1.4.0-1.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-libs-debuginfo-1.2.4-3.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/flatpak-libs-debuginfo-1.4.0-1.fc30.x86_64.rpm:
	Likewise.
	* tests/data/test-diff-pkg/PR24690/PR24690-report-0.txt: New test
	reference output.
	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-diff-pkg.cc (in_out_specs): Add the new test material
	above to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2020-01-06 14:26:00 +01:00

2865 lines
65 KiB
C++

// -*- Mode: C++ -*-
//
// Copyright (C) 2013-2019 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
// free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 3, or (at your option) any
// later version.
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details.
// You should have received a copy of the GNU Lesser General Public
// License along with this program; see the file COPYING-LGPLV3. If
// not, see <http://www.gnu.org/licenses/>.
//
// Author: Dodji Seketeli
#ifndef __ABG_COMPARISON_H__
#define __ABG_COMPARISON_H__
/// @file
#include <ostream>
#include "abg-cxx-compat.h"
#include "abg-corpus.h"
#include "abg-diff-utils.h"
#include "abg-reporter.h"
namespace abigail
{
/// @brief utilities to compare abi artifacts
///
/// The main entry points of the namespace are the compute_diff()
/// overloads used to compute the difference between two abi artifacts.
namespace comparison
{
namespace filtering
{
struct filter_base;
typedef shared_ptr<filter_base> filter_base_sptr;
typedef std::vector<filter_base_sptr> filters;
}
// Inject types we need into this namespace.
using std::ostream;
using std::vector;
using abg_compat::unordered_map;
using abg_compat::unordered_set;
using std::pair;
using diff_utils::insertion;
using diff_utils::deletion;
using diff_utils::edit_script;
class diff;
/// Convenience typedef for a shared_ptr for the @ref diff class
typedef shared_ptr<diff> diff_sptr;
/// Convenience typedef for a weak_ptr for the @ref diff class
typedef weak_ptr<diff> diff_wptr;
/// Hasher for @ref diff_sptr.
struct diff_sptr_hasher
{
/// The actual hashing functor.
size_t
operator()(const diff_sptr& t) const
{return reinterpret_cast<size_t>(t.get());}
}; // end struct diff_sptr_hasher
/// Convenience typedef for a vector of @ref diff_sptr.
typedef vector<diff_sptr> diff_sptrs_type;
/// Convenience typedef for a vector of @ref diff*.
typedef vector<diff*> diff_ptrs_type;
/// Convenience typedef for an unoredered set of @ref diff_sptr
typedef unordered_set<diff_sptr, diff_sptr_hasher> unordered_diff_sptr_set;
class decl_diff_base;
/// Convenience typedef for a shared_ptr of @ref decl_diff_base.
typedef shared_ptr<decl_diff_base> decl_diff_base_sptr;
/// Convenience typedef for a vector of @ref decl_diff_base_sptr.
typedef vector<decl_diff_base_sptr> decl_diff_base_sptrs_type;
class type_diff_base;
/// Convenience pointer for a shared pointer to a type_diff_base
typedef shared_ptr<type_diff_base> type_diff_base_sptr;
/// Convenience typedef for a vector of @ref type_diff_base_sptr
typedef vector<type_diff_base_sptr> type_diff_base_sptrs_type;
class function_decl_diff;
/// Convenience typedef for a shared pointer to a @ref function_decl type.
typedef shared_ptr<function_decl_diff> function_decl_diff_sptr;
/// Convenience typedef for a vector of @ref function_decl_diff_sptr
typedef vector<function_decl_diff_sptr> function_decl_diff_sptrs_type;
class fn_parm_diff;
/// Convenience typedef for a shared pointer to a @ref fn_parm_diff
/// type.
typedef shared_ptr<fn_parm_diff> fn_parm_diff_sptr;
class var_diff;
/// Convenience typedef for a shared pointer to a @ref var_diff type.
typedef shared_ptr<var_diff> var_diff_sptr;
/// Convenience typedef for a vector of @ref var_diff_sptr.
typedef vector<var_diff_sptr> var_diff_sptrs_type;
class base_diff;
/// Convenience typedef for a shared pointer to a @ref base_diff type.
typedef shared_ptr<base_diff> base_diff_sptr;
/// Convenience typedef for a vector of @ref base_diff_sptr.
typedef vector<base_diff_sptr> base_diff_sptrs_type;
class class_diff;
/// Convenience typedef for a shared pointer on a @ref class_diff type.
typedef shared_ptr<class_diff> class_diff_sptr;
/// Convenience typedef for a map of pointer values. The Key is a
/// pointer value and the value is potentially another pointer value
/// associated to the first one.
typedef unordered_map<size_t, size_t> pointer_map;
/// Convenience typedef for a map which key is a string and which
/// value is a @ref decl_base_sptr.
typedef unordered_map<string, decl_base_sptr> string_decl_base_sptr_map;
/// Convenience typedef for a map which key is a string and which
/// value is a @ref type_base_sptr.
typedef unordered_map<string, type_base_sptr> string_type_base_sptr_map;
/// Convenience typedef for a map which key is an unsigned integer and
/// which value is a @ref decl_base_sptr
typedef unordered_map<unsigned, decl_base_sptr> unsigned_decl_base_sptr_map;
/// Convenience typedef for a map of string and class_decl::basse_spec_sptr.
typedef unordered_map<string, class_decl::base_spec_sptr> string_base_sptr_map;
/// Convenience typedef for a map of string and @ref base_diff_sptr.
typedef unordered_map<string, base_diff_sptr> string_base_diff_sptr_map;
/// Convenience typedef for a map which value is a changed function
/// parameter and which key is the name of the function parameter.
typedef unordered_map<string, fn_parm_diff_sptr> string_fn_parm_diff_sptr_map;
/// Convenience typedef for a map which key is an integer and which
/// value is a changed parameter.
typedef unordered_map<unsigned, fn_parm_diff_sptr>
unsigned_fn_parm_diff_sptr_map;
/// Convenience typedef for a map which key is an integer and which
/// value is a parameter.
typedef unordered_map<unsigned,
function_decl::parameter_sptr> unsigned_parm_map;
/// Convenience typedef for a map which value is a
/// type_diff_base_sptr. The key of the map is the qualified name of
/// the changed type.
typedef unordered_map<string,
type_diff_base_sptr> string_type_diff_base_sptr_map;
/// Convenience typedef for a map which value is a
/// decl_diff_base_sptr. The key of the map is the qualified name of
/// the changed type.
typedef unordered_map<string,
decl_diff_base_sptr> string_decl_diff_base_sptr_map;
/// Convenience typedef for a map which value is a diff_sptr. The key
/// of the map is the qualified name of the changed type.
typedef unordered_map<string, diff_sptr> string_diff_sptr_map;
/// Convenience typedef for a map which value is a diff*. The key of
/// the map is the qualified name of the changed type.
typedef unordered_map<string, diff*> string_diff_ptr_map;
/// Convenience typedef for a map whose key is a string and whose
/// value is a changed variable of type @ref var_diff_sptr.
typedef unordered_map<string,
var_diff_sptr> string_var_diff_sptr_map;
/// Convenience typedef for a map whose key is an unsigned int and
/// whose value is a changed variable of type @ref var_diff_sptr.
typedef unordered_map<unsigned, var_diff_sptr> unsigned_var_diff_sptr_map;
/// Convenience typedef for a map which value is a function
/// parameter. The key is the name of the function parm.
typedef unordered_map<string, function_decl::parameter_sptr> string_parm_map;
/// Convenience typedef for a map which value is an enumerator. The
/// key is the name of the enumerator.
typedef unordered_map<string, enum_type_decl::enumerator> string_enumerator_map;
/// Convenience typedef for a changed enumerator. The first element
/// of the pair is the old enumerator and the second one is the new enumerator.
typedef std::pair<enum_type_decl::enumerator,
enum_type_decl::enumerator> changed_enumerator;
/// Convenience typedef for a vector of changed enumerators.
typedef vector<changed_enumerator> changed_enumerators_type;
/// Convenience typedef for a map which value is a changed enumerator.
/// The key is the name of the changed enumerator.
typedef unordered_map<string, changed_enumerator> string_changed_enumerator_map;
/// Convenience typedef for a map which key is a string and which
/// value is a pointer to @ref decl_base.
typedef unordered_map<string, function_decl*> string_function_ptr_map;
/// Convenience typedef for a map which key is a string and which
/// value is a @ref function_decl_diff_sptr.
typedef unordered_map<string,
function_decl_diff_sptr>
string_function_decl_diff_sptr_map;
/// Convenience typedef for a pair of class_decl::member_function_sptr
/// representing a changed member function. The first element of the
/// pair is the initial member function and the second element is the
/// changed one.
typedef pair<method_decl_sptr,
method_decl_sptr> changed_member_function_sptr;
/// Convenience typedef for a hash map of strings and changed member functions.
typedef unordered_map<string,
changed_member_function_sptr>
string_changed_member_function_sptr_map;
/// Convenience typedef for a hash map of strings and member functions.
typedef unordered_map<string, method_decl_sptr> string_member_function_sptr_map;
/// Convenience typedef for a map which key is a string and which
/// value is a point to @ref var_decl.
typedef unordered_map<string, var_decl*> string_var_ptr_map;
/// Convenience typedef for a pair of pointer to @ref var_decl
/// representing a @ref var_decl change. The first member of the pair
/// represents the initial variable and the second member represents
/// the changed variable.
typedef std::pair<var_decl*, var_decl*> changed_var_ptr;
/// Convenience typedef for a map whose key is a string and whose
/// value is an @ref elf_symbol_sptr.
typedef unordered_map<string, elf_symbol_sptr> string_elf_symbol_map;
/// Convenience typedef for a map which key is a string and which
/// value is a @ref var_diff_sptr.
typedef unordered_map<string, var_diff_sptr> string_var_diff_ptr_map;
class diff_context;
/// Convenience typedef for a shared pointer of @ref diff_context.
typedef shared_ptr<diff_context> diff_context_sptr;
/// Convenience typedef for a weak pointer of @ref diff_context.
typedef weak_ptr<diff_context> diff_context_wptr;
class diff_node_visitor;
class diff_traversable_base;
/// Convenience typedef for shared_ptr on diff_traversable_base.
typedef shared_ptr<diff_traversable_base> diff_traversable_base_sptr;
/// An enum for the different ways to visit a diff tree node.
///
/// This is used by the node traversing code, to know when to avoid
/// visiting children nodes, for instance.
enum visiting_kind
{
/// The default enumerator value of this enum. It doesn't have any
/// particular meaning yet.
DEFAULT_VISITING_KIND = 0,
/// This says that the traversing code should avoid visiting the
/// children nodes of the current node being visited.
SKIP_CHILDREN_VISITING_KIND = 1,
/// This says that the traversing code should not mark visited nodes
/// as having been traversed. This is useful, for instance, for
/// visitors which have debugging purposes.
DO_NOT_MARK_VISITED_NODES_AS_VISITED = 1 << 1
};
visiting_kind
operator|(visiting_kind l, visiting_kind r);
visiting_kind
operator&(visiting_kind l, visiting_kind r);
visiting_kind
operator~(visiting_kind l);
/// The base class for the diff classes that are to be traversed.
class diff_traversable_base : public traversable_base
{
public:
virtual bool
traverse(diff_node_visitor& v);
}; // end struct diff_traversable_base
/// An enum for the different categories that a diff tree node falls
/// into, regarding the kind of changes it represents.
///
/// Note that if you add an enumerator to this enum, you need to
/// update a few spots accordingly:
///
/// * update the ACCESS_CHANGE_CATEGORY enumerator (which is the
/// last enumerator of this enum by OR-ing its initializer with
/// the new enumerator.
///
/// * update the categorize_harmless_diff_node or
/// categorize_harmful_diff_node function depending on if the new
/// enumerator classifies diff nodes as harmless or harmful.
///
/// * update the get_default_harmless_categories_bitmap or
/// get_default_harmful_categories_bitmap function as well, just
/// like above.
///
/// * update the "operator<<(ostream& o, diff_category c)" streaming
/// operator so that it can stream the new enumerator to a textual
/// output stream.
enum diff_category
{
/// This means the diff node does not carry any (meaningful) change,
/// or that it carries changes that have not yet been categorized.
NO_CHANGE_CATEGORY = 0,
/// This means the diff node (or at least one of its descendant
/// nodes) carries access related changes, e.g, a private member
/// that becomes public.
ACCESS_CHANGE_CATEGORY = 1,
/// This means the diff node (or at least one of its descendant
/// nodes) carries a change involving two compatible types. For
/// instance a type and its typedefs.
COMPATIBLE_TYPE_CHANGE_CATEGORY = 1 << 1,
/// This means that a diff node in the sub-tree carries a harmless
/// declaration name change. This is set only for name changes for
/// data members and typedefs.
HARMLESS_DECL_NAME_CHANGE_CATEGORY = 1 << 2,
/// This means that a diff node in the sub-tree carries an addition
/// or removal of a non-virtual member function.
NON_VIRT_MEM_FUN_CHANGE_CATEGORY = 1 << 3,
/// This means that a diff node in the sub-tree carries an addition
/// or removal of a static data member.
STATIC_DATA_MEMBER_CHANGE_CATEGORY = 1 << 4,
/// This means that a diff node in the sub-tree carries an addition
/// of enumerator to an enum type.
HARMLESS_ENUM_CHANGE_CATEGORY = 1 << 5,
/// This means that a diff node in the sub-tree carries an a symbol
/// alias change that is harmless.
HARMLESS_SYMBOL_ALIAS_CHANGE_CATEORY = 1 << 6,
HARMLESS_UNION_CHANGE_CATEGORY = 1 << 7,
/// This means that a diff node was marked as suppressed by a
/// user-provided suppression specification.
SUPPRESSED_CATEGORY = 1 << 8,
/// This means that a diff node was warked as being for a private
/// type. That is, the diff node is meant to be suppressed by a
/// suppression specification that was auto-generated to filter out
/// changes to private types.
PRIVATE_TYPE_CATEGORY = 1 << 9,
/// This means the diff node (or at least one of its descendant
/// nodes) carries a change that modifies the size of a type or an
/// offset of a type member. Removal or changes of enumerators in a
/// enum fall in this category too.
SIZE_OR_OFFSET_CHANGE_CATEGORY = 1 << 10,
/// This means that a diff node in the sub-tree carries an
/// incompatible change to a vtable.
VIRTUAL_MEMBER_CHANGE_CATEGORY = 1 << 11,
/// A diff node in this category is redundant. That means it's
/// present as a child of a other nodes in the diff tree.
REDUNDANT_CATEGORY = 1 << 12,
/// This means that a diff node in the sub-tree carries a class type
/// that was declaration-only and that is now defined, or vice
/// versa.
CLASS_DECL_ONLY_DEF_CHANGE_CATEGORY = 1 << 13,
/// A diff node in this category is a function parameter type which
/// top cv-qualifiers change.
FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY = 1 << 14,
/// A diff node in this category has a function parameter type with a
/// cv-qualifiers change.
FN_PARM_TYPE_CV_CHANGE_CATEGORY = 1 << 15,
/// A diff node in this category is a function return type with a
/// cv-qualifier change.
FN_RETURN_TYPE_CV_CHANGE_CATEGORY = 1 << 16,
/// A diff node in this category is for a variable which type holds
/// a cv-qualifier change.
VAR_TYPE_CV_CHANGE_CATEGORY = 1 << 17,
/// A diff node in this category carries a change from void pointer
/// to non-void pointer.
VOID_PTR_TO_PTR_CHANGE_CATEGORY = 1 << 18,
/// A diff node in this category carries a change in the size of the
/// array type of a global variable, but the ELF size of the
/// variable didn't change.
BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY = 1 << 19,
/// A special enumerator that is the logical 'or' all the
/// enumerators above.
///
/// This one must stay the last enumerator. Please update it each
/// time you add a new enumerator above.
EVERYTHING_CATEGORY =
ACCESS_CHANGE_CATEGORY
| COMPATIBLE_TYPE_CHANGE_CATEGORY
| HARMLESS_DECL_NAME_CHANGE_CATEGORY
| NON_VIRT_MEM_FUN_CHANGE_CATEGORY
| STATIC_DATA_MEMBER_CHANGE_CATEGORY
| HARMLESS_ENUM_CHANGE_CATEGORY
| HARMLESS_SYMBOL_ALIAS_CHANGE_CATEORY
| HARMLESS_UNION_CHANGE_CATEGORY
| SUPPRESSED_CATEGORY
| PRIVATE_TYPE_CATEGORY
| SIZE_OR_OFFSET_CHANGE_CATEGORY
| VIRTUAL_MEMBER_CHANGE_CATEGORY
| REDUNDANT_CATEGORY
| CLASS_DECL_ONLY_DEF_CHANGE_CATEGORY
| FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY
| FN_PARM_TYPE_CV_CHANGE_CATEGORY
| FN_RETURN_TYPE_CV_CHANGE_CATEGORY
| VAR_TYPE_CV_CHANGE_CATEGORY
| VOID_PTR_TO_PTR_CHANGE_CATEGORY
| BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY
}; // enum diff_category
diff_category
operator|(diff_category c1, diff_category c2);
diff_category&
operator|=(diff_category& c1, diff_category c2);
diff_category&
operator&=(diff_category& c1, diff_category c2);
diff_category
operator^(diff_category c1, diff_category c2);
diff_category
operator&(diff_category c1, diff_category c2);
diff_category
operator~(diff_category c);
diff_category
get_default_harmless_categories_bitmap();
diff_category
get_default_harmful_categories_bitmap();
ostream&
operator<<(ostream& o, diff_category);
class corpus_diff;
/// This type contains maps. Each map associates a type name to a
/// diff of that type. Not all kinds of diffs are present; only those
/// that carry leaf changes are, for now.
class diff_maps
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
public:
diff_maps();
const string_diff_ptr_map&
get_type_decl_diff_map() const;
string_diff_ptr_map&
get_type_decl_diff_map();
const string_diff_ptr_map&
get_enum_diff_map() const;
string_diff_ptr_map&
get_enum_diff_map();
const string_diff_ptr_map&
get_class_diff_map() const;
string_diff_ptr_map&
get_class_diff_map();
const string_diff_ptr_map&
get_union_diff_map() const;
string_diff_ptr_map&
get_union_diff_map();
const string_diff_ptr_map&
get_typedef_diff_map() const;
string_diff_ptr_map&
get_typedef_diff_map();
const string_diff_ptr_map&
get_array_diff_map() const;
string_diff_ptr_map&
get_array_diff_map();
const string_diff_ptr_map&
get_reference_diff_map() const;
string_diff_ptr_map&
get_reference_diff_map();
const string_diff_ptr_map&
get_fn_parm_diff_map() const;
string_diff_ptr_map&
get_fn_parm_diff_map();
const string_diff_ptr_map&
get_function_type_diff_map() const;
string_diff_ptr_map&
get_function_type_diff_map();
const string_diff_ptr_map&
get_function_decl_diff_map() const;
string_diff_ptr_map&
get_function_decl_diff_map();
const string_diff_ptr_map&
get_var_decl_diff_map() const;
string_diff_ptr_map&
get_var_decl_diff_map();
const string_diff_ptr_map&
get_distinct_diff_map() const;
string_diff_ptr_map&
get_distinct_diff_map();
bool
insert_diff_node(const diff *d,
const type_or_decl_base_sptr& impacted_iface);
artifact_sptr_set_type*
lookup_impacted_interfaces(const diff *d) const;
}; // end class diff_maps
/// A convenience typedef for a shared pointer to @ref corpus_diff.
typedef shared_ptr<corpus_diff> corpus_diff_sptr;
/// The context of the diff. This type holds various bits of
/// information that is going to be used throughout the diffing of two
/// entities and the reporting that follows.
class diff_context
{
struct priv;
shared_ptr<priv> priv_;
diff_sptr
has_diff_for(const type_or_decl_base_sptr first,
const type_or_decl_base_sptr second) const;
diff_sptr
has_diff_for_types(const type_base_sptr first,
const type_base_sptr second) const;
const diff*
has_diff_for(const diff* d) const;
diff_sptr
has_diff_for(const diff_sptr d) const;
void
add_diff(const type_or_decl_base_sptr first,
const type_or_decl_base_sptr second,
const diff_sptr d);
void
add_diff(const diff_sptr d);
void
add_diff(const diff* d);
void
set_canonical_diff_for(const type_or_decl_base_sptr first,
const type_or_decl_base_sptr second,
const diff_sptr);
diff_sptr
set_or_get_canonical_diff_for(const type_or_decl_base_sptr first,
const type_or_decl_base_sptr second,
const diff_sptr canonical_diff);
public:
diff_context();
void
set_corpus_diff(const corpus_diff_sptr&);
const corpus_diff_sptr&
get_corpus_diff() const;
corpus_sptr
get_first_corpus() const;
corpus_sptr
get_second_corpus() const;
reporter_base_sptr
get_reporter() const;
void
set_reporter(reporter_base_sptr&);
diff_sptr
get_canonical_diff_for(const type_or_decl_base_sptr first,
const type_or_decl_base_sptr second) const;
diff_sptr
get_canonical_diff_for(const diff_sptr d) const;
void
initialize_canonical_diff(const diff_sptr diff);
void
keep_diff_alive(diff_sptr&);
diff*
diff_has_been_visited(const diff*) const;
diff_sptr
diff_has_been_visited(const diff_sptr) const;
void
mark_diff_as_visited(const diff*);
void
forget_visited_diffs();
void
mark_last_diff_visited_per_class_of_equivalence(const diff*);
void
clear_last_diffs_visited_per_class_of_equivalence();
const diff*
get_last_visited_diff_of_class_of_equivalence(const diff*);
void
forbid_visiting_a_node_twice(bool f);
bool
visiting_a_node_twice_is_forbidden() const;
void
forbid_visiting_a_node_twice_per_interface(bool);
bool
visiting_a_node_twice_is_forbidden_per_interface() const;
diff_category
get_allowed_category() const;
void
set_allowed_category(diff_category c);
void
switch_categories_on(diff_category c);
void
switch_categories_off(diff_category c);
const filtering::filters&
diff_filters() const;
void
add_diff_filter(filtering::filter_base_sptr);
void
maybe_apply_filters(diff_sptr diff);
void
maybe_apply_filters(corpus_diff_sptr diff);
suppr::suppressions_type&
suppressions() const;
void
add_suppression(const suppr::suppression_sptr suppr);
void
add_suppressions(const suppr::suppressions_type& supprs);
void
show_leaf_changes_only(bool f);
bool
show_leaf_changes_only() const;
bool
show_hex_values() const;
void
show_hex_values(bool f);
bool
show_offsets_sizes_in_bits() const;
void
show_offsets_sizes_in_bits(bool f);
void
show_relative_offset_changes(bool f);
bool
show_relative_offset_changes(void);
void
show_stats_only(bool f);
bool
show_stats_only() const;
void
show_soname_change(bool f);
bool
show_soname_change() const;
void
show_architecture_change(bool f);
bool
show_architecture_change() const;
void
show_deleted_fns(bool f);
bool
show_deleted_fns() const;
void
show_changed_fns(bool f);
bool
show_changed_fns() const;
void
show_added_fns(bool f);
bool
show_added_fns() const;
void
show_deleted_vars(bool f);
bool
show_deleted_vars() const;
void
show_changed_vars(bool f);
bool
show_changed_vars() const;
void
show_added_vars(bool f);
bool
show_added_vars() const;
bool
show_linkage_names() const;
void
show_linkage_names(bool f);
bool
show_locs() const;
void
show_locs(bool f);
bool
show_redundant_changes() const;
void
show_redundant_changes(bool f);
bool
show_symbols_unreferenced_by_debug_info() const;
void
show_symbols_unreferenced_by_debug_info(bool f);
bool
show_added_symbols_unreferenced_by_debug_info() const;
void
show_added_symbols_unreferenced_by_debug_info(bool f);
void show_unreachable_types(bool f);
bool show_unreachable_types();
bool
show_impacted_interfaces() const;
void
show_impacted_interfaces(bool f);
void
default_output_stream(ostream*);
ostream*
default_output_stream();
void
error_output_stream(ostream*);
ostream*
error_output_stream() const;
bool
dump_diff_tree() const;
void
dump_diff_tree(bool f);
void
do_dump_diff_tree(const diff_sptr) const;
void
do_dump_diff_tree(const corpus_diff_sptr) const;
friend class_diff_sptr
compute_diff(const class_decl_sptr first,
const class_decl_sptr second,
diff_context_sptr ctxt);
};//end struct diff_context.
/// The abstraction of a change between two ABI artifacts.
///
/// Please read more about the @ref DiffNode "IR" of the comparison
/// engine to learn more about this.
///
/// This type encapsulates an edit script (a set of insertions and
/// deletions) for two constructs that are to be diff'ed. The two
/// constructs are called the "subjects" of the diff.
class diff : public diff_traversable_base
{
friend class diff_context;
struct priv;
typedef shared_ptr<priv> priv_sptr;
// Forbidden
diff();
protected:
priv_sptr priv_;
diff(type_or_decl_base_sptr first_subject,
type_or_decl_base_sptr second_subject);
diff(type_or_decl_base_sptr first_subject,
type_or_decl_base_sptr second_subject,
diff_context_sptr ctxt);
void
begin_traversing();
void
end_traversing();
virtual void
finish_diff_type();
void
set_canonical_diff(diff *);
public:
type_or_decl_base_sptr
first_subject() const;
type_or_decl_base_sptr
second_subject() const;
const vector<diff*>&
children_nodes() const;
const diff*
parent_node() const;
diff* get_canonical_diff() const;
bool
is_traversing() const;
void
append_child_node(diff_sptr);
const diff_context_sptr
context() const;
void
context(diff_context_sptr c);
bool
currently_reporting() const;
void
currently_reporting(bool f) const;
bool
reported_once() const;
void
reported_once(bool f) const;
diff_category
get_category() const;
diff_category
get_local_category() const;
diff_category
get_class_of_equiv_category() const;
diff_category
add_to_category(diff_category c);
diff_category
add_to_local_category(diff_category c);
void
add_to_local_and_inherited_categories(diff_category c);
diff_category
remove_from_category(diff_category c);
diff_category
remove_from_local_category(diff_category c);
void
set_category(diff_category c);
void
set_local_category(diff_category c);
bool
is_filtered_out() const;
bool
is_filtered_out_wrt_non_inherited_categories() const;
bool
is_suppressed() const;
bool
is_suppressed(bool &is_private_type) const;
bool
to_be_reported() const;
bool
has_local_changes_to_be_reported() const;
virtual const string&
get_pretty_representation() const;
virtual void
chain_into_hierarchy();
/// Pure interface to get the length of the changes encapsulated by
/// this diff. A length of zero means that the current instance of
/// @ref diff doesn't carry any change.
///
/// This is to be implemented by all descendants of this type.
virtual bool
has_changes() const = 0;
/// Pure interface to know if the current instance of @diff carries
/// a local change. A local change is a change that is on the @ref
/// diff object itself, as opposed to a change that is carried by
/// some of its children nodes.
///
/// This is to be implemented by all descendants of this type.
virtual enum change_kind
has_local_changes() const = 0;
/// Pure interface to report the diff in a serialized form that is
/// legible for the user.
///
/// Note that the serializd report has to leave one empty line at
/// the end of its content.
///
/// @param out the output stream to serialize the report to.
///
/// @param indent the indentation string to use.
virtual void
report(ostream& out, const string& indent = "") const = 0;
virtual bool
traverse(diff_node_visitor& v);
};// end class diff
diff_sptr
compute_diff(const decl_base_sptr,
const decl_base_sptr,
diff_context_sptr ctxt);
diff_sptr
compute_diff(const type_base_sptr,
const type_base_sptr,
diff_context_sptr ctxt);
/// The base class of diff between types.
class type_diff_base : public diff
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
type_diff_base();
protected:
type_diff_base(type_base_sptr first_subject,
type_base_sptr second_subject,
diff_context_sptr ctxt);
public:
virtual enum change_kind
has_local_changes() const = 0;
virtual ~type_diff_base();
};// end class type_diff_base
/// The base class of diff between decls.
class decl_diff_base : public diff
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
protected:
decl_diff_base(decl_base_sptr first_subject,
decl_base_sptr second_subject,
diff_context_sptr ctxt);
public:
virtual enum change_kind
has_local_changes() const = 0;
virtual ~decl_diff_base();
};// end class decl_diff_base
string
get_pretty_representation(diff*);
class distinct_diff;
/// Convenience typedef for a shared pointer to distinct_types_diff
typedef shared_ptr<distinct_diff> distinct_diff_sptr;
/// An abstraction of a diff between entities that are of a different
/// kind (disctinct).
class distinct_diff : public diff
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
protected:
distinct_diff(type_or_decl_base_sptr first,
type_or_decl_base_sptr second,
diff_context_sptr ctxt = diff_context_sptr());
virtual void
finish_diff_type();
public:
const type_or_decl_base_sptr
first() const;
const type_or_decl_base_sptr
second() const;
const diff_sptr
compatible_child_diff() const;
virtual const string&
get_pretty_representation() const;
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream& out, const string& indent = "") const;
virtual void
chain_into_hierarchy();
static bool
entities_are_of_distinct_kinds(type_or_decl_base_sptr first,
type_or_decl_base_sptr second);
friend distinct_diff_sptr
compute_diff_for_distinct_kinds(const type_or_decl_base_sptr first,
const type_or_decl_base_sptr second,
diff_context_sptr ctxt);
};// end class distinct_types_diff
distinct_diff_sptr
compute_diff_for_distinct_kinds(const type_or_decl_base_sptr,
const type_or_decl_base_sptr,
diff_context_sptr ctxt);
/// Abstracts a diff between two instances of @ref var_decl
class var_diff : public decl_diff_base
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
protected:
var_diff(var_decl_sptr first,
var_decl_sptr second,
diff_sptr type_diff,
diff_context_sptr ctxt = diff_context_sptr());
virtual void
finish_diff_type();
public:
var_decl_sptr
first_var() const;
var_decl_sptr
second_var() const;
diff_sptr
type_diff() const;
virtual void
chain_into_hierarchy();
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream& out, const string& indent = "") const;
virtual const string&
get_pretty_representation() const;
friend var_diff_sptr
compute_diff(const var_decl_sptr first,
const var_decl_sptr second,
diff_context_sptr ctxt);
};// end class var_diff
var_diff_sptr
compute_diff(const var_decl_sptr, const var_decl_sptr, diff_context_sptr);
class pointer_diff;
/// Convenience typedef for a shared pointer on a @ref
/// pointer_diff type.
typedef shared_ptr<pointer_diff> pointer_diff_sptr;
/// The abstraction of a diff between two pointers.
class pointer_diff : public type_diff_base
{
struct priv;
shared_ptr<priv> priv_;
protected:
pointer_diff(pointer_type_def_sptr first,
pointer_type_def_sptr second,
diff_sptr underlying_type_diff,
diff_context_sptr ctxt = diff_context_sptr());
virtual void
finish_diff_type();
public:
const pointer_type_def_sptr
first_pointer() const;
const pointer_type_def_sptr
second_pointer() const;
diff_sptr
underlying_type_diff() const;
void
underlying_type_diff(const diff_sptr);
virtual const string&
get_pretty_representation() const;
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream&, const string& indent = "") const;
virtual void
chain_into_hierarchy();
friend pointer_diff_sptr
compute_diff(pointer_type_def_sptr first,
pointer_type_def_sptr second,
diff_context_sptr ctxt);
};// end class pointer_diff
pointer_diff_sptr
compute_diff(pointer_type_def_sptr first,
pointer_type_def_sptr second,
diff_context_sptr ctxt);
class reference_diff;
/// Convenience typedef for a shared pointer on a @ref
/// reference_diff type.
typedef shared_ptr<reference_diff> reference_diff_sptr;
/// The abstraction of a diff between two references.
class reference_diff : public type_diff_base
{
struct priv;
shared_ptr<priv> priv_;
protected:
reference_diff(const reference_type_def_sptr first,
const reference_type_def_sptr second,
diff_sptr underlying,
diff_context_sptr ctxt = diff_context_sptr());
virtual void
finish_diff_type();
public:
reference_type_def_sptr
first_reference() const;
reference_type_def_sptr
second_reference() const;
const diff_sptr&
underlying_type_diff() const;
diff_sptr&
underlying_type_diff(diff_sptr);
virtual const string&
get_pretty_representation() const;
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream&, const string& indent = "") const;
virtual void
chain_into_hierarchy();
friend reference_diff_sptr
compute_diff(reference_type_def_sptr first,
reference_type_def_sptr second,
diff_context_sptr ctxt);
};// end class reference_diff
reference_diff_sptr
compute_diff(reference_type_def_sptr first,
reference_type_def_sptr second,
diff_context_sptr ctxt);
class array_diff;
/// Convenience typedef for a shared pointer on a @ref
/// array_diff type.
typedef shared_ptr<array_diff> array_diff_sptr;
/// The abstraction of a diff between two arrays.
class array_diff : public type_diff_base
{
struct priv;
shared_ptr<priv> priv_;
protected:
array_diff(const array_type_def_sptr first,
const array_type_def_sptr second,
diff_sptr element_type_diff,
diff_context_sptr ctxt = diff_context_sptr());
virtual void
finish_diff_type();
public:
const array_type_def_sptr
first_array() const;
const array_type_def_sptr
second_array() const;
const diff_sptr&
element_type_diff() const;
void
element_type_diff(diff_sptr);
virtual const string&
get_pretty_representation() const;
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream&, const string& indent = "") const;
virtual void
chain_into_hierarchy();
friend array_diff_sptr
compute_diff(array_type_def_sptr first,
array_type_def_sptr second,
diff_context_sptr ctxt);
};// end class array_diff
array_diff_sptr
compute_diff(array_type_def_sptr first,
array_type_def_sptr second,
diff_context_sptr ctxt);
class qualified_type_diff;
typedef class shared_ptr<qualified_type_diff> qualified_type_diff_sptr;
/// Abstraction of a diff between two qualified types.
class qualified_type_diff : public type_diff_base
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
protected:
qualified_type_diff(qualified_type_def_sptr first,
qualified_type_def_sptr second,
diff_sptr underling,
diff_context_sptr ctxt = diff_context_sptr());
virtual void
finish_diff_type();
public:
const qualified_type_def_sptr
first_qualified_type() const;
const qualified_type_def_sptr
second_qualified_type() const;
diff_sptr
underlying_type_diff() const;
void
underlying_type_diff(const diff_sptr);
diff_sptr
leaf_underlying_type_diff() const;
virtual const string&
get_pretty_representation() const;
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream&, const string& indent = "") const;
virtual void
chain_into_hierarchy();
friend qualified_type_diff_sptr
compute_diff(const qualified_type_def_sptr first,
const qualified_type_def_sptr second,
diff_context_sptr ctxt);
};// end class qualified_type_diff.
qualified_type_diff_sptr
compute_diff(const qualified_type_def_sptr first,
const qualified_type_def_sptr second,
diff_context_sptr ctxt);
class enum_diff;
typedef shared_ptr<enum_diff> enum_diff_sptr;
/// Abstraction of a diff between two enums.
class enum_diff : public type_diff_base
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
void
clear_lookup_tables();
bool
lookup_tables_empty() const;
void
ensure_lookup_tables_populated();
protected:
enum_diff(const enum_type_decl_sptr,
const enum_type_decl_sptr,
const diff_sptr,
diff_context_sptr ctxt = diff_context_sptr());
virtual void
finish_diff_type();
public:
const enum_type_decl_sptr
first_enum() const;
const enum_type_decl_sptr
second_enum() const;
diff_sptr
underlying_type_diff() const;
const string_enumerator_map&
deleted_enumerators() const;
const string_enumerator_map&
inserted_enumerators() const;
const string_changed_enumerator_map&
changed_enumerators() const;
virtual const string&
get_pretty_representation() const;
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream&, const string& indent = "") const;
virtual void
chain_into_hierarchy();
friend enum_diff_sptr
compute_diff(const enum_type_decl_sptr first,
const enum_type_decl_sptr second,
diff_context_sptr ctxt);
};//end class enum_diff;
enum_diff_sptr
compute_diff(const enum_type_decl_sptr,
const enum_type_decl_sptr,
diff_context_sptr);
/// This is the base class of @ref class_diff and @ref union_diff.
class class_or_union_diff : public type_diff_base
{
protected:
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
void
clear_lookup_tables(void);
bool
lookup_tables_empty(void) const;
void
ensure_lookup_tables_populated(void) const;
void
allocate_priv_data();
protected:
class_or_union_diff(class_or_union_sptr first_scope,
class_or_union_sptr second_scope,
diff_context_sptr ctxt = diff_context_sptr());
virtual void
finish_diff_type();
public:
const class_or_union_diff::priv_sptr&
get_priv() const;
//TODO: add change of the name of the type.
virtual ~class_or_union_diff();
class_or_union_sptr
first_class_or_union() const;
class_or_union_sptr
second_class_or_union() const;
const edit_script&
member_types_changes() const;
edit_script&
member_types_changes();
const edit_script&
data_members_changes() const;
edit_script&
data_members_changes();
const string_decl_base_sptr_map&
inserted_data_members() const;
const string_decl_base_sptr_map&
deleted_data_members() const;
const edit_script&
member_fns_changes() const;
edit_script&
member_fns_changes();
const function_decl_diff_sptrs_type&
changed_member_fns() const;
const string_member_function_sptr_map&
deleted_member_fns() const;
const string_member_function_sptr_map&
inserted_member_fns() const;
const edit_script&
member_fn_tmpls_changes() const;
edit_script&
member_fn_tmpls_changes();
const edit_script&
member_class_tmpls_changes() const;
edit_script&
member_class_tmpls_changes();
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream&, const string& indent = "") const;
virtual void
chain_into_hierarchy();
friend class default_reporter;
}; // end class_or_union_diff;
/// This type abstracts changes for a class_decl.
class class_diff : public class_or_union_diff
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
const priv_sptr& get_priv()const;
void
clear_lookup_tables(void);
bool
lookup_tables_empty(void) const;
void
ensure_lookup_tables_populated(void) const;
void
allocate_priv_data();
protected:
class_diff(class_decl_sptr first_scope,
class_decl_sptr second_scope,
diff_context_sptr ctxt = diff_context_sptr());
virtual void
finish_diff_type();
public:
//TODO: add change of the name of the type.
virtual ~class_diff();
class_decl_sptr
first_class_decl() const;
class_decl_sptr
second_class_decl() const;
const edit_script&
base_changes() const;
edit_script&
base_changes();
const string_base_sptr_map&
deleted_bases() const;
const string_base_sptr_map&
inserted_bases() const;
const base_diff_sptrs_type&
changed_bases();
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual const string&
get_pretty_representation() const;
virtual void
report(ostream&, const string& indent = "") const;
virtual void
chain_into_hierarchy();
friend class_diff_sptr
compute_diff(const class_decl_sptr first,
const class_decl_sptr second,
diff_context_sptr ctxt);
friend class default_reporter;
};// end class_diff
class_diff_sptr
compute_diff(const class_decl_sptr first,
const class_decl_sptr second,
diff_context_sptr ctxt);
class union_diff;
typedef shared_ptr<union_diff> union_diff_sptr;
class union_diff : public class_or_union_diff
{
void
clear_lookup_tables(void);
bool
lookup_tables_empty(void) const;
void
ensure_lookup_tables_populated(void) const;
void
allocate_priv_data();
protected:
union_diff(union_decl_sptr first_union,
union_decl_sptr second_union,
diff_context_sptr ctxt = diff_context_sptr());
virtual void
finish_diff_type();
public:
virtual ~union_diff();
union_decl_sptr
first_union_decl() const;
union_decl_sptr
second_union_decl() const;
virtual const string&
get_pretty_representation() const;
virtual void
report(ostream&, const string& indent = "") const;
friend union_diff_sptr
compute_diff(const union_decl_sptr first,
const union_decl_sptr second,
diff_context_sptr ctxt);
}; // end class union_diff
union_diff_sptr
compute_diff(const union_decl_sptr first,
const union_decl_sptr second,
diff_context_sptr ctxt);
/// An abstraction of a diff between two instances of class_decl::base_spec.
class base_diff : public diff
{
struct priv;
shared_ptr<priv> priv_;
protected:
base_diff(class_decl::base_spec_sptr first,
class_decl::base_spec_sptr second,
class_diff_sptr underlying,
diff_context_sptr ctxt = diff_context_sptr());
virtual void
finish_diff_type();
public:
class_decl::base_spec_sptr
first_base() const;
class_decl::base_spec_sptr
second_base() const;
const class_diff_sptr
get_underlying_class_diff() const;
void
set_underlying_class_diff(class_diff_sptr d);
virtual const string&
get_pretty_representation() const;
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream&, const string& indent = "") const;
virtual void
chain_into_hierarchy();
friend base_diff_sptr
compute_diff(const class_decl::base_spec_sptr first,
const class_decl::base_spec_sptr second,
diff_context_sptr ctxt);
};// end class base_diff
base_diff_sptr
compute_diff(const class_decl::base_spec_sptr first,
const class_decl::base_spec_sptr second,
diff_context_sptr ctxt);
class scope_diff;
/// Convenience typedef for a shared pointer on a @ref scope_diff.
typedef shared_ptr<scope_diff> scope_diff_sptr;
/// An abstractions of the changes between two scopes.
class scope_diff : public diff
{
struct priv;
shared_ptr<priv> priv_;
bool
lookup_tables_empty() const;
void
clear_lookup_tables();
void
ensure_lookup_tables_populated();
protected:
scope_diff(scope_decl_sptr first_scope,
scope_decl_sptr second_scope,
diff_context_sptr ctxt = diff_context_sptr());
virtual void
finish_diff_type();
public:
friend scope_diff_sptr
compute_diff(const scope_decl_sptr first,
const scope_decl_sptr second,
scope_diff_sptr d,
diff_context_sptr ctxt);
friend scope_diff_sptr
compute_diff(const scope_decl_sptr first_scope,
const scope_decl_sptr second_scope,
diff_context_sptr ctxt);
const scope_decl_sptr
first_scope() const;
const scope_decl_sptr
second_scope() const;
const edit_script&
member_changes() const;
edit_script&
member_changes();
const decl_base_sptr
deleted_member_at(unsigned index) const;
const decl_base_sptr
deleted_member_at(vector<deletion>::const_iterator) const;
const decl_base_sptr
inserted_member_at(unsigned i);
const decl_base_sptr
inserted_member_at(vector<unsigned>::const_iterator i);
const diff_sptrs_type&
changed_types() const;
const diff_sptrs_type&
changed_decls() const;
const string_decl_base_sptr_map&
removed_types() const;
const string_decl_base_sptr_map&
removed_decls() const;
const string_decl_base_sptr_map&
added_types() const;
const string_decl_base_sptr_map&
added_decls() const;
virtual const string&
get_pretty_representation() const;
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream& out, const string& indent = "") const;
virtual void
chain_into_hierarchy();
friend class default_reporter;
friend class leaf_reporter;
};// end class scope_diff
scope_diff_sptr
compute_diff(const scope_decl_sptr first,
const scope_decl_sptr second,
scope_diff_sptr d,
diff_context_sptr ctxt);
scope_diff_sptr
compute_diff(const scope_decl_sptr first_scope,
const scope_decl_sptr second_scope,
diff_context_sptr ctxt);
/// Abstraction of a diff between two function parameters.
class fn_parm_diff : public decl_diff_base
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
virtual void
finish_diff_type();
fn_parm_diff(const function_decl::parameter_sptr first,
const function_decl::parameter_sptr second,
diff_context_sptr ctxt);
public:
friend fn_parm_diff_sptr
compute_diff(const function_decl::parameter_sptr first,
const function_decl::parameter_sptr second,
diff_context_sptr ctxt);
const function_decl::parameter_sptr
first_parameter() const;
const function_decl::parameter_sptr
second_parameter() const;
diff_sptr
type_diff() const;
virtual const string&
get_pretty_representation() const;
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream&, const string& indent = "") const;
virtual void
chain_into_hierarchy();
}; // end class fn_parm_diff
fn_parm_diff_sptr
compute_diff(const function_decl::parameter_sptr first,
const function_decl::parameter_sptr second,
diff_context_sptr ctxt);
class function_type_diff;
/// A convenience typedef for a shared pointer to @ref
/// function_type_type_diff
typedef shared_ptr<function_type_diff> function_type_diff_sptr;
/// Abstraction of a diff between two function types.
class function_type_diff: public type_diff_base
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
void
ensure_lookup_tables_populated();
const function_decl::parameter_sptr
deleted_parameter_at(int i) const;
const function_decl::parameter_sptr
inserted_parameter_at(int i) const;
protected:
function_type_diff(const function_type_sptr first,
const function_type_sptr second,
diff_context_sptr ctxt);
virtual void
finish_diff_type();
public:
friend function_type_diff_sptr
compute_diff(const function_type_sptr first,
const function_type_sptr second,
diff_context_sptr ctxt);
const function_type_sptr
first_function_type() const;
const function_type_sptr
second_function_type() const;
const diff_sptr
return_type_diff() const;
const string_fn_parm_diff_sptr_map&
subtype_changed_parms() const;
const string_parm_map&
removed_parms() const;
const string_parm_map&
added_parms() const;
virtual const string&
get_pretty_representation() const;
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream&, const string& indent = "") const;
virtual void
chain_into_hierarchy();
friend class default_reporter;
friend class leaf_reporter;
};// end class function_type_diff
function_type_diff_sptr
compute_diff(const function_type_sptr first,
const function_type_sptr second,
diff_context_sptr ctxt);
/// Abstraction of a diff between two function_decl.
class function_decl_diff : public decl_diff_base
{
struct priv;
shared_ptr<priv> priv_;
void
ensure_lookup_tables_populated();
protected:
function_decl_diff(const function_decl_sptr first,
const function_decl_sptr second,
diff_context_sptr ctxt);
virtual void
finish_diff_type();
public:
friend function_decl_diff_sptr
compute_diff(const function_decl_sptr first,
const function_decl_sptr second,
diff_context_sptr ctxt);
const function_decl_sptr
first_function_decl() const;
const function_decl_sptr
second_function_decl() const;
const function_type_diff_sptr
type_diff() const;
virtual const string&
get_pretty_representation() const;
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream&, const string& indent = "") const;
virtual void
chain_into_hierarchy();
}; // end class function_decl_diff
function_decl_diff_sptr
compute_diff(const function_decl_sptr first,
const function_decl_sptr second,
diff_context_sptr ctxt);
class type_decl_diff;
/// Convenience typedef for a shared pointer on a @ref type_decl_diff type.
typedef shared_ptr<type_decl_diff> type_decl_diff_sptr;
/// Abstraction of a diff between two basic type declarations.
class type_decl_diff : public type_diff_base
{
type_decl_diff();
protected:
type_decl_diff(const type_decl_sptr first,
const type_decl_sptr second,
diff_context_sptr ctxt = diff_context_sptr());
virtual void
finish_diff_type();
public:
friend type_decl_diff_sptr
compute_diff(const type_decl_sptr first,
const type_decl_sptr second,
diff_context_sptr ctxt);
const type_decl_sptr
first_type_decl() const;
const type_decl_sptr
second_type_decl() const;
virtual const string&
get_pretty_representation() const;
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream& out, const string& indent = "") const;
};// end type_decl_diff
type_decl_diff_sptr
compute_diff(const type_decl_sptr,
const type_decl_sptr,
diff_context_sptr);
class typedef_diff;
/// Convenience typedef for a shared pointer on a typedef_diff type.
typedef shared_ptr<typedef_diff> typedef_diff_sptr;
/// Abstraction of a diff between two typedef_decl.
class typedef_diff : public type_diff_base
{
struct priv;
shared_ptr<priv> priv_;
typedef_diff();
protected:
typedef_diff(const typedef_decl_sptr first,
const typedef_decl_sptr second,
const diff_sptr underlying_type_diff,
diff_context_sptr ctxt = diff_context_sptr());
virtual void
finish_diff_type();
public:
friend typedef_diff_sptr
compute_diff(const typedef_decl_sptr first,
const typedef_decl_sptr second,
diff_context_sptr ctxt);
const typedef_decl_sptr
first_typedef_decl() const;
const typedef_decl_sptr
second_typedef_decl() const;
const diff_sptr
underlying_type_diff() const;
void
underlying_type_diff(const diff_sptr);
virtual const string&
get_pretty_representation() const;
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream&, const string& indent = "") const;
virtual void
chain_into_hierarchy();
};// end class typedef_diff
typedef_diff_sptr
compute_diff(const typedef_decl_sptr,
const typedef_decl_sptr,
diff_context_sptr ctxt);
const diff*
get_typedef_diff_underlying_type_diff(const diff* diff);
class translation_unit_diff;
/// Convenience typedef for a shared pointer on a
/// @ref translation_unit_diff type.
typedef shared_ptr<translation_unit_diff> translation_unit_diff_sptr;
/// An abstraction of a diff between two translation units.
class translation_unit_diff : public scope_diff
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
protected:
translation_unit_diff(translation_unit_sptr first,
translation_unit_sptr second,
diff_context_sptr ctxt = diff_context_sptr());
public:
const translation_unit_sptr
first_translation_unit() const;
const translation_unit_sptr
second_translation_unit() const;
friend translation_unit_diff_sptr
compute_diff(const translation_unit_sptr first,
const translation_unit_sptr second,
diff_context_sptr ctxt);
virtual bool
has_changes() const;
virtual enum change_kind
has_local_changes() const;
virtual void
report(ostream& out, const string& indent = "") const;
};//end class translation_unit_diff
translation_unit_diff_sptr
compute_diff(const translation_unit_sptr first,
const translation_unit_sptr second,
diff_context_sptr ctxt = diff_context_sptr());
/// An abstraction of a diff between between two abi corpus.
class corpus_diff
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
protected:
corpus_diff(corpus_sptr first,
corpus_sptr second,
diff_context_sptr ctxt = diff_context_sptr());
void
finish_diff_type();
public:
class diff_stats;
virtual ~corpus_diff() {}
/// A convenience typedef for a shared pointer to @ref diff_stats
typedef shared_ptr<diff_stats> diff_stats_sptr;
corpus_sptr
first_corpus() const;
corpus_sptr
second_corpus() const;
const vector<diff*>&
children_nodes() const;
void
append_child_node(diff_sptr);
edit_script&
function_changes() const;
edit_script&
variable_changes() const;
bool
soname_changed() const;
bool
architecture_changed() const;
const string_function_ptr_map&
deleted_functions() const;
const string_function_ptr_map&
added_functions();
const string_function_decl_diff_sptr_map&
changed_functions();
const function_decl_diff_sptrs_type&
changed_functions_sorted();
const string_var_ptr_map&
deleted_variables() const;
const string_var_ptr_map&
added_variables() const;
const string_var_diff_sptr_map&
changed_variables();
const var_diff_sptrs_type&
changed_variables_sorted();
const string_elf_symbol_map&
deleted_unrefed_function_symbols() const;
const string_elf_symbol_map&
added_unrefed_function_symbols() const;
const string_elf_symbol_map&
deleted_unrefed_variable_symbols() const;
const string_elf_symbol_map&
added_unrefed_variable_symbols() const;
const string_type_base_sptr_map&
deleted_unreachable_types() const;
const vector<type_base_sptr>&
deleted_unreachable_types_sorted() const;
const string_type_base_sptr_map&
added_unreachable_types() const;
const vector<type_base_sptr>&
added_unreachable_types_sorted() const;
const string_diff_sptr_map&
changed_unreachable_types() const;
const vector<diff_sptr>&
changed_unreachable_types_sorted() const;
const diff_context_sptr
context() const;
const string&
get_pretty_representation() const;
bool
has_changes() const;
bool
has_incompatible_changes() const;
bool
has_net_subtype_changes() const;
bool
has_net_changes() const;
const diff_stats&
apply_filters_and_suppressions_before_reporting();
void
mark_leaf_diff_nodes();
diff_maps&
get_leaf_diffs();
const diff_maps&
get_leaf_diffs() const;
virtual void
report(ostream& out, const string& indent = "") const;
virtual bool
traverse(diff_node_visitor& v);
virtual void
chain_into_hierarchy();
friend corpus_diff_sptr
compute_diff(const corpus_sptr f,
const corpus_sptr s,
diff_context_sptr ctxt);
friend void
apply_suppressions(const corpus_diff* diff_tree);
friend void
maybe_report_unreachable_type_changes(const corpus_diff& d,
const corpus_diff::diff_stats &s,
const string& indent,
ostream& out);
friend class default_reporter;
friend class leaf_reporter;
}; // end class corpus_diff
corpus_diff_sptr
compute_diff(const corpus_sptr,
const corpus_sptr,
diff_context_sptr = diff_context_sptr());
corpus_diff_sptr
compute_diff(const corpus_group_sptr&,
const corpus_group_sptr&,
diff_context_sptr ctxt);
/// This is a document class that aims to capture statistics about the
/// changes carried by a @ref corpus_diff type.
///
/// Its values are populated by the member function
/// corpus_diff::apply_filters_and_suppressions_before_reporting()
class corpus_diff::diff_stats
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
diff_stats();
public:
diff_stats(diff_context_sptr);
size_t num_func_removed() const;
void num_func_removed(size_t);
size_t num_removed_func_filtered_out() const;
void num_removed_func_filtered_out(size_t);
size_t net_num_func_removed() const;
size_t num_func_added() const;
void num_func_added(size_t);
size_t num_added_func_filtered_out() const;
void num_added_func_filtered_out(size_t);
size_t net_num_func_added() const;
size_t num_func_changed() const;
void num_func_changed(size_t);
size_t num_changed_func_filtered_out() const;
void num_changed_func_filtered_out(size_t);
size_t num_func_with_virtual_offset_changes() const;
void num_func_with_virtual_offset_changes(size_t);
size_t net_num_func_changed() const;
size_t num_vars_removed() const;
void num_vars_removed(size_t);
size_t num_removed_vars_filtered_out() const;
void num_removed_vars_filtered_out(size_t) const;
size_t net_num_vars_removed() const;
size_t num_vars_added() const;
void num_vars_added(size_t);
size_t num_added_vars_filtered_out() const;
void num_added_vars_filtered_out(size_t);
size_t net_num_vars_added() const;
size_t num_vars_changed() const;
void num_vars_changed(size_t);
size_t num_changed_vars_filtered_out() const;
void num_changed_vars_filtered_out(size_t);
size_t net_num_vars_changed() const;
size_t num_func_syms_removed() const;
void num_func_syms_removed(size_t);
size_t num_removed_func_syms_filtered_out() const;
void num_removed_func_syms_filtered_out(size_t);
size_t num_func_syms_added() const;
void num_func_syms_added(size_t);
size_t num_added_func_syms_filtered_out() const;
void num_added_func_syms_filtered_out(size_t);
size_t net_num_removed_func_syms() const;
size_t net_num_added_func_syms() const;
size_t num_var_syms_removed() const;
void num_var_syms_removed(size_t);
size_t num_removed_var_syms_filtered_out() const;
void num_removed_var_syms_filtered_out(size_t);
size_t num_var_syms_added() const;
void num_var_syms_added(size_t);
size_t num_added_var_syms_filtered_out() const;
void num_added_var_syms_filtered_out(size_t);
size_t net_num_removed_var_syms() const;
size_t net_num_added_var_syms() const;
size_t num_leaf_changes() const;
void num_leaf_changes(size_t);
size_t num_leaf_changes_filtered_out() const;
void num_leaf_changes_filtered_out(size_t);
size_t net_num_leaf_changes() const;
size_t num_leaf_type_changes() const;
void num_leaf_type_changes(size_t);
size_t num_leaf_type_changes_filtered_out() const;
void num_leaf_type_changes_filtered_out(size_t);
size_t net_num_leaf_type_changes() const;
size_t num_leaf_func_changes() const;
void num_leaf_func_changes(size_t);
size_t num_leaf_func_changes_filtered_out() const;
void num_leaf_func_changes_filtered_out(size_t);
size_t net_num_leaf_func_changes() const;
size_t num_leaf_var_changes() const;
void num_leaf_var_changes(size_t);
size_t num_leaf_var_changes_filtered_out() const;
void num_leaf_var_changes_filtered_out(size_t);
size_t net_num_leaf_var_changes() const;
size_t num_added_unreachable_types() const;
void num_added_unreachable_types(size_t);
size_t num_added_unreachable_types_filtered_out() const;
void num_added_unreachable_types_filtered_out(size_t);
size_t net_num_added_unreachable_types() const;
size_t num_removed_unreachable_types() const;
void num_removed_unreachable_types(size_t);
size_t num_removed_unreachable_types_filtered_out() const;
void num_removed_unreachable_types_filtered_out(size_t);
size_t net_num_removed_unreachable_types() const;
size_t num_changed_unreachable_types() const;
void num_changed_unreachable_types(size_t);
size_t num_changed_unreachable_types_filtered_out() const;
void num_changed_unreachable_types_filtered_out(size_t);
size_t net_num_changed_unreachable_types() const;
}; // end class corpus_diff::diff_stats
/// The base class for the node visitors. These are the types used to
/// visit each node traversed by the diff_traversable_base::traverse() method.
class diff_node_visitor : public node_visitor_base
{
protected:
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
public:
diff_node_visitor();
virtual ~diff_node_visitor() {}
diff_node_visitor(visiting_kind k);
visiting_kind
get_visiting_kind() const;
void
set_visiting_kind(visiting_kind v);
void
or_visiting_kind(visiting_kind v);
void
set_current_topmost_iface_diff(diff*);
diff*
get_current_topmost_iface_diff() const;
virtual void
visit_begin(diff*);
virtual void
visit_begin(corpus_diff*);
virtual void
visit_end(diff*);
virtual void
visit_end(corpus_diff*);
virtual bool
visit(diff*, bool);
virtual bool
visit(distinct_diff*, bool);
virtual bool
visit(var_diff*, bool);
virtual bool
visit(pointer_diff*, bool);
virtual bool
visit(reference_diff*, bool);
virtual bool
visit(qualified_type_diff*, bool);
virtual bool
visit(enum_diff*, bool);
virtual bool
visit(class_diff*, bool);
virtual bool
visit(base_diff*, bool);
virtual bool
visit(scope_diff*, bool);
virtual bool
visit(function_decl_diff*, bool);
virtual bool
visit(type_decl_diff*, bool);
virtual bool
visit(typedef_diff*, bool);
virtual bool
visit(translation_unit_diff*, bool);
virtual bool
visit(corpus_diff*, bool);
}; // end struct diff_node_visitor
void
propagate_categories(diff* diff_tree);
void
propagate_categories(diff_sptr diff_tree);
void
propagate_categories(corpus_diff* diff_tree);
void
propagate_categories(corpus_diff_sptr diff_tree);
void
apply_suppressions(diff* diff_tree);
void
apply_suppressions(const corpus_diff* diff_tree);
void
apply_suppressions(diff_sptr diff_tree);
void
apply_suppressions(corpus_diff_sptr diff_tree);
void
print_diff_tree(diff* diff_tree, std::ostream&);
void
print_diff_tree(corpus_diff* diff_tree,
std::ostream&);
void
print_diff_tree(diff_sptr diff_tree,
std::ostream&);
void
print_diff_tree(corpus_diff_sptr diff_tree,
std::ostream&);
void
categorize_redundancy(diff* diff_tree);
void
categorize_redundancy(diff_sptr diff_tree);
void
categorize_redundancy(corpus_diff* diff_tree);
void
categorize_redundancy(corpus_diff_sptr diff_tree);
void
clear_redundancy_categorization(diff* diff_tree);
void
clear_redundancy_categorization(diff_sptr diff_tree);
void
clear_redundancy_categorization(corpus_diff* diff_tree);
void
clear_redundancy_categorization(corpus_diff_sptr diff_tree);
void
apply_filters(corpus_diff_sptr diff_tree);
bool
is_diff_of_variadic_parameter_type(const diff*);
bool
is_diff_of_variadic_parameter_type(const diff_sptr&);
bool
is_diff_of_variadic_parameter(const diff*);
bool
is_diff_of_variadic_parameter(const diff_sptr&);
const type_diff_base*
is_type_diff(const diff* diff);
const decl_diff_base*
is_decl_diff(const diff* diff);
const type_decl_diff*
is_diff_of_basic_type(const diff* diff);
const type_decl_diff*
is_diff_of_basic_type(const diff* diff, bool);
const class_or_union_diff*
is_diff_of_class_or_union_type(const diff *d);
bool
has_basic_type_change_only(const diff* diff);
const enum_diff*
is_enum_diff(const diff *diff);
const class_diff*
is_class_diff(const diff* diff);
const union_diff*
is_union_diff(const diff* diff);
const class_or_union_diff*
is_class_or_union_diff(const diff* d);
const class_or_union_diff*
is_anonymous_class_or_union_diff(const diff* d);
const array_diff*
is_array_diff(const diff* diff);
const function_type_diff*
is_function_type_diff(const diff* diff);
const function_type_diff*
is_function_type_diff_with_local_changes(const diff* diff);
const typedef_diff*
is_typedef_diff(const diff *diff);
const var_diff*
is_var_diff(const diff* diff);
const function_decl_diff*
is_function_decl_diff(const diff* diff);
const pointer_diff*
is_pointer_diff(const diff* diff);
const reference_diff*
is_reference_diff(const diff* diff);
const qualified_type_diff*
is_qualified_type_diff(const diff* diff);
bool
is_reference_or_pointer_diff(const diff* diff);
bool
is_reference_or_pointer_diff_to_non_basic_distinct_types(const diff* diff);
const fn_parm_diff*
is_fn_parm_diff(const diff* diff);
const base_diff*
is_base_diff(const diff* diff);
const distinct_diff*
is_distinct_diff(const diff *diff);
bool
is_child_node_of_function_parm_diff(const diff* diff);
bool
is_child_node_of_base_diff(const diff* diff);
const corpus_diff*
is_corpus_diff(const diff* diff);
const diff*
peel_typedef_diff(const diff* dif);
const diff*
peel_pointer_diff(const diff* dif);
const diff*
peel_reference_diff(const diff* dif);
const diff*
peel_qualified_diff(const diff* dif);
const diff*
peel_pointer_or_qualified_type_diff(const diff* dif);
const diff*
peel_typedef_or_qualified_type_diff(const diff* dif);
}// end namespace comparison
}// end namespace abigail
#endif //__ABG_COMPARISON_H__