mirror of
git://sourceware.org/git/libabigail.git
synced 2025-02-10 10:37:01 +00:00
This patch allows abidiff to take the --leaf-changes-only option and then to display only the changes that are local to any given type. That means the reporting agent won't follow pointers when displaying changes. That gives less context to the ABI change reports but then they are less cluttered. To do this, the patch introduces a new reporting agent to libabigail: abigail::comparison::leaf_reporter. When given a graph of diff nodes, this agent only reports about the leaf (local) changes. That is, it will *NOT* follow pointers, references, underlying types of qualified and typedef types and things like that. It will just report about changes that are local to a given type. This reporting agent is then used (in lieu of the default abigail::comparison::default_reporter agent) when the --leaf-changes-only option is provided by the user on the command line of abidiff. Note that abidiff also takes the --impacted-interfaces option to so that the leaf reporter shows the set of interfaces impacted by each leaf change. * doc/manuals/abidiff.rst: Add documentation the new --leaf-changes-only and --impacted-interfaces options. * src/abg-leaf-reporter.cc: New file. * src/Makefile.am: Add the new src/abg-leaf-reporter.cc file to source distribution. * include/abg-fwd.h (get_var_size_in_bits) (function_decl_is_less_than): Declare new functions. (get_name): Add new overload for type_or_decl_base*. * include/abg-ir.h (struct type_or_decl_hash, type_or_decl_equal) (type_or_decl_base_comp): Define new types. (artifact_sptr_set_type, artifact_ptr_set_type): Define new typedefs. * include/abg-comp-filter.h: Update copyright year. (has_basic_type_name_change): Add new function declaration. * src/abg-comp-filter.cc (decl_name_changed): Take a type_or_decl_base rather than just a decl. Add an overload for diff*. (has_basic_type_name_change): Define new function. * include/abg-comparison.h: Update copyright year. (string_diff_ptr_map): Define this new typedef. (class diff_maps): Define this new class. (diff_context::{set_corpora}): Remove this member function. (diff_context::{set_corpus_diff, get_corpus_diff, show_leaf_changes_only, show_impacted_interfaces, forbid_visiting_a_node_twice_per_interface}): Declare these new member functions. (diff_node_visitor::priv_): Add a new pimpl data member. (diff_node_visitor::{diff_node_visitor, get_visiting_kind, set_visiting_kind}): Turn these into out-of-line member functions. (diff_node_visitor::{set,get}_current_topmost_iface_diff): Add new member functions. (class {scope_diff, function_type_diff, corpus_diff}): Add class leaf_reporter as a friend. (corpus_diff::mark_leaf_diff_nodes, get_leaf_diffs): Declare new member functions. (diff::{visiting_a_node_twice_is_forbidden_per_interface, parent_interface_node}): Define new member functions. (is_diff_of_basic_type): Return a type_decl_diff* rather than just a bool. (is_enum_diff, is_array_diff, is_function_type, is_typedef_diff) (is_corpus_diff): Declare new functions. (corpus_diff::diff_stats::{num_leaf_changes, num_leaf_changes_filtered_out, net_num_leaf_changes}): Add new member functions. (is_distinct_diff): Declare new function. * include/abg-reporter.h: Forward-declare "class diff_maps". (reporter_base::diff_to_be_reported): Declare a new virtual member function. (reporter_base::{report_local_typedef_changes, report_local_reference_type_changes, report_local_function_type_changes}): Declare new member functions. (class leaf_reporter): Define new type. * src/abg-comparison-priv.h (struct diff_hash, diff_equal): Define new types. (diff_artifact_set_map_type): Define new typedef. (diff_context::priv::{first_corpus_, second_corpus_}): Remove these data members. (diff_context::priv::{corpus_diff_, leaf_changes_only_, reset_visited_diffs_for_each_interface_, show_impacted_interfaces_}): Add new data members. (diff_context::priv::priv): Adjust. (corpus_diff::priv::{leaf_diffs_, parent_interface_}): Add new data member. (corpus_diff::diff_stats::priv::{num_leaf_changes, num_leaf_changes_filtered_out}): Add new data members. (corpus_diff::priv::count_leaf_changes): Define new member function. (sort_artifacts_set, get_fn_decl_or_var_decl_diff_ancestor) (is_diff_of_global_decls): Declare new functions. (function_comp::operator()): Factorize this out into the new function abigail::ir::function_decl_is_less_than. * src/abg-ir.cc (get_var_size_in_bits) (function_decl_is_less_than): Define new functions. (get_name): Define new overload for type_or_decl_base*. * src/abg-comparison.cc (is_enum_diff, is_typedef_diff) (is_array_diff, is_function_type_diff, is_corpus_diff) (is_distinct_diff, sort_artifacts_set, is_diff_of_global_decls): Define new functions. (is_union_diff): Fix comment. (diff_context::forbid_visiting_a_node_twice_per_interface): Define new member functions. (diff_context::set_corpus_diff, get_corpus_diff) (diff_context::show_leaf_changes_only) (diff_context::visiting_a_node_twice_is_forbidden_per_interface) (diff_context::show_impacted_interfaces): Define new member functions. (diff_context::get_reporter): Create the reporter that matches what diff_context::show_leaf_changes_only says. (diff_node_visitor::priv): Define a new type. (diff_node_visitor::{diff_node_visitor, get_visiting_kind, set_visiting_kind, or_visiting_kind, set_current_topmost_iface_diff, get_current_topmost_iface_diff}): Define new out-of-line member functions. (struct diff_maps::priv): Define new type. (diff_maps::{diff_maps, get_type_decl_diff_map, get_type_decl_diff_map, get_enum_diff_map, get_class_diff_map, get_union_diff_map, get_typedef_diff_map, get_array_diff_map, get_function_type_diff_map, get_function_decl_diff_map, get_var_decl_diff_map, get_reference_diff_map, get_fn_parm_diff_map, get_distinct_diff_map, insert_diff_node, lookup_impacted_interfaces}): Define member functions. (corpus_diff::{mark_leaf_diff_nodes, get_leaf_diffs}): Define new member functions. (struct leaf_diff_node_marker_visitor): Define new type. (corpus_diff::apply_filters_and_suppressions_before_reporting): Mark diff nodes in here. (corpus_diff::traverse): Appropriately set the current topmost interface into the visitor before visiting a diff node. (compute_diff): In the overload for corpus_sptr, adjust to reflect that we are now storing the corpus_diff in the diff context. (is_diff_of_basic_type): Return a type_decl_diff*, not just a bool. (corpus_diff::priv::count_leaf_changes): Define a new member function. (corpus_diff::diff_stats::{num_leaf_changes, num_leaf_changes_filtered_out, net_num_leaf_changes}): Define new member functions. (corpus_diff::priv::apply_filters_and_compute_diff_stats): Use the new corpus_diff::priv::count_leaf_changes to compute the number of leaf changes. (corpus_diff::priv::emit_diff_stats): Emit the report about leaf type changes when necessary. * src/abg-reporter-priv.h (report_mem_header): Declare new overload. (maybe_show_relative_offset_change,): Pass the var_diff_sptr parameter by const reference. (represent): Pass the var_diff_sptr parameter by const reference and take a new "local-only" flag. (maybe_show_relative_size_change) (maybe_report_interfaces_impacted_by_diff): Declare new functions. * src/abg-default-reporter.cc: Adjust copyright year. (default_reporter::{report_local_typedef_changes, report_local_qualified_type_changes, report_local_reference_type_changes, report_local_function_type_changes}): Define new member functions. (default_reporter::report): Adjust. Add an overload for function_type_diff&. In the overload for qualified_type_diff, if the name of the underlying type changed, do not detail the changes any further. In the overload for function_decl_diff, Adjust to use the new diff_context::get_{first, second}_corpus member function. In the overload for enum_diff, call the new maybe_report_interfaces_impacted_by_diff that is advertised below. * src/abg-reporter-priv.cc (represent): Adjust the overload for var_diff_sptr. (report_mem_header): Define new overload. (maybe_show_relative_size_change) (maybe_report_interfaces_impacted_by_diff): Define new functions. (reporter_base::diff_to_be_reported): Define new member function. (maybe_show_relative_offset_change): Pass the var_diff_sptr parameter by const reference. (represent): In the overload for var_diff_sptr, pass the var_diff_sptr parameter by reference. Take a 'local_only' flag. Iisplay type changes only if we are not displaying "local changes only". Display size changes of data members too, when in "local-only" mode. * src/abg-suppression.cc (sonames_of_binaries_match) (names_of_binaries_match): Adjust. * tools/abidiff.cc (options::{leaf_changes_only, show_impacted_interfaces}): Add new data members. (display_usage): Emit usage string for the new --leaf-changes-only and --impacted-interfaces options. (parse_command_line): Parse the new --leaf-changes-only and the --impacted-interfaces options. (set_diff_context_from_opts): Set the 'show-leaf-changes' and the 'show-impacted-interfaces' flags. * tests/data/test-diff-filter/libtest42-leaf-report-v{0,1}.so: New test input. * tests/data/test-diff-filter/test42-leaf-report-output-0.txt: New test reference output. * tests/data/test-diff-filter/test42-leaf-report-v{0,1}.cc: Source code of the new test inputs. * tests/test-diff-filter.cc (in_out_specs): Use the new test inputs above in this harness. * tests/data/test-diff-suppr/libtest35-leaf-v0.so: New test input. * tests/data/test-diff-suppr/test35-leaf-report-0.txt: New test reference output. * tests/data/test-diff-suppr/test35-leaf-v{0,1}.cc: Source code of the new test inputs. * tests/data/test-diff-suppr/test35-leaf.suppr: Suppression specification to use for the test35 test. * tests/data/test-diff-suppr/libtest36-leaf-v0.so: New test input. * tests/data/test-diff-suppr/libtest36-leaf-v1.so: Likewise. * tests/data/test-diff-suppr/test36-leaf-report-0.txt: New reference test output. * tests/data/test-diff-suppr/test36-leaf-v0.cc: Source code of test input above. * tests/data/test-diff-suppr/test36-leaf-v1.cc: Likewise. * tests/test-diff-suppr.cc (in_out_specs): Use the new test inputs above in this harness. * tests/data/Makefile.am: Add the new test inputs above to source distribution. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
117 lines
3.3 KiB
C++
117 lines
3.3 KiB
C++
// -*- Mode: C++ -*-
|
|
//
|
|
// Copyright (C) 2013-2017 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
|
|
|
|
/// @file
|
|
///
|
|
/// This header declares filters for the diff trees resulting from
|
|
/// comparing ABI Corpora.
|
|
|
|
#ifndef __ABG_COMP_FILTER_H__
|
|
#define __ABG_COMP_FILTER_H__
|
|
|
|
#include "abg-comparison.h"
|
|
|
|
namespace abigail
|
|
{
|
|
namespace comparison
|
|
{
|
|
/// Facilities to walk, categorize and possibly filter nodes of the
|
|
/// diff tree.
|
|
namespace filtering
|
|
{
|
|
|
|
bool
|
|
has_harmless_name_change(const decl_base_sptr& f, const decl_base_sptr& s);
|
|
|
|
bool
|
|
has_virtual_mem_fn_change(const function_decl_diff* diff);
|
|
|
|
bool
|
|
has_class_decl_only_def_change(const class_or_union_sptr& first,
|
|
const class_or_union_sptr& second);
|
|
|
|
bool
|
|
has_basic_type_name_change(const diff *);
|
|
|
|
struct filter_base;
|
|
/// Convenience typedef for a shared pointer to filter_base
|
|
typedef shared_ptr<filter_base> filter_base_sptr;
|
|
/// Convenience typedef for a vector of filter_base_sptr
|
|
typedef std::vector<filter_base_sptr> filters;
|
|
|
|
/// The base class for the diff tree node filter.
|
|
///
|
|
/// It's intended to walk a tree of diff nodes and tag each relevant
|
|
/// name into one or several categories depending on well choosen
|
|
/// properties of the diff nodes.
|
|
struct filter_base : public diff_node_visitor
|
|
{
|
|
friend void
|
|
apply_filter(filter_base_sptr f, diff_sptr deef);
|
|
}; //end class filter_base
|
|
|
|
void
|
|
apply_filter(filter_base& filter, diff_sptr d);
|
|
|
|
void
|
|
apply_filter(filter_base& filter, corpus_diff_sptr d);
|
|
|
|
void
|
|
apply_filter(filter_base_sptr filter, diff_sptr d);
|
|
|
|
class harmless_filter;
|
|
/// Convenience typedef for a shared pointer to a harmless_filter.
|
|
typedef shared_ptr<harmless_filter> harmless_filter_sptr;
|
|
|
|
/// A filter that walks the diff nodes tree and tags relevant diff
|
|
/// nodes into categories considered to represent harmless changes.
|
|
class harmless_filter : public filter_base
|
|
{
|
|
virtual bool
|
|
visit(diff*, bool);
|
|
|
|
virtual void
|
|
visit_end(diff*);
|
|
}; // end class harmless_filter
|
|
|
|
class harmless_harmful_filter;
|
|
/// A convenience typedef for a shared pointer to harmful_filter.
|
|
typedef shared_ptr<harmless_harmful_filter> harmful_harmless_filter_sptr;
|
|
|
|
/// A filter that walks the diff nodes tree and tags relevant diff
|
|
/// nodes into categories considered to represent potentially harmless
|
|
/// or harmful changes.
|
|
class harmless_harmful_filter : public filter_base
|
|
{
|
|
virtual bool
|
|
visit(diff*, bool);
|
|
|
|
virtual void
|
|
visit_end(diff*);
|
|
}; // end class harmless_harmful_filter
|
|
|
|
} // end namespace filtering
|
|
} // end namespace comparison
|
|
} // end namespace abigail
|
|
|
|
#endif // __ABG_COMP_FILTER_H__
|