mirror of
git://sourceware.org/git/libabigail.git
synced 2025-03-05 22:27:34 +00:00
In leaf mode, libabigail fails to report changes to the underlying type of a typedef. At its core, this is due to the fact that changes to the underlying type of a typedef are not considered local. As the leaf reporter only reports local changes (as opposed to non-local changes which are changes to sub-types) it doesn't detect those non-local typedef changes. To handle this, this patch makes changes to the underlying type of a typedef be considered as local changes. This is like what we already do for pointer and qualified types. Now that we have another set of changes to report in the leaf reporter, we need to handle how to propagate the category and redundancy status of those changes. The patch does this too. Also, just like we do pointer and qualified type changes, the patch avoids marking the diff node carrying the typedef change as being a leaf change. That way, only existing leaf changes carrying that typedef diff node will be reported. For instance, a function whose parameter has a typedef change will be reported because that change to the function is considered a leaf change. Otherwise, reporting the typedef (or the pointer or qualified) type change on its own is not useful unless it impacts those leaf changes that we deem useful. The patch adds the example given in problem report to the testsuite. * src/abg-ir.cc (equals): In the overload for typedef_decls, report changes to the underlying type as being local of kind LOCAL_TYPE_CHANGE_KIND. * src/abg-comparison.cc (leaf_diff_node_marker_visitor::visit_begin): Do not mark typedef diff node as leaf node. (suppression_categorization_visitor::visit_end): Propagate the 'suppressed' category of the underlying type to the parent typedef unless the later has a local non-type change. (redundancy_marking_visitor::visit_end): Likewise for the 'redundant' category. * include/abg-reporter.h (report_non_type_typedef_changes): Rename ... * src/abg-default-reporter.cc (report_non_type_typedef_changes): ... report_local_typedef_changes into this. * src/abg-leaf-reporter.cc (leaf_reporter::report): Make the leaf reporter invoke the reporting method of the default reporter for typedefs as all typedef changes are now local. * tests/data/test-diff-filter/test-PR26309-report-0.txt: Add new test reference output. * tests/data/test-diff-filter/test-PR26309-v{0,1}.o: Add new test binary input. * tests/data/test-diff-filter/test-PR26309-v{0,1}.c: Add source code for new test binary input. * tests/data/Makefile.am: Add the new text material above to source distribution. * tests/test-diff-filter.cc (in_out_specs): Add the new test input above to this test harness. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-3.txt: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
348 lines
9.2 KiB
C++
348 lines
9.2 KiB
C++
// -*- Mode: C++ -*-
|
|
//
|
|
// Copyright (C) 2017-2020 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
|
|
///
|
|
/// The declaration of the reporting types of libabigail's diff
|
|
/// engine.
|
|
|
|
#ifndef __ABG_REPORTER_H__
|
|
#define __ABG_REPORTER_H__
|
|
|
|
#include <ostream>
|
|
#include <string>
|
|
#include "abg-cxx-compat.h"
|
|
|
|
namespace abigail
|
|
{
|
|
|
|
using abg_compat::shared_ptr;
|
|
|
|
namespace comparison
|
|
{
|
|
class diff;
|
|
class type_decl_diff;
|
|
class enum_diff;
|
|
class typedef_diff;
|
|
class qualified_type_diff;
|
|
class distinct_diff;
|
|
class pointer_diff;
|
|
class reference_diff;
|
|
class array_diff;
|
|
class base_diff;
|
|
class class_or_union_diff;
|
|
class class_diff;
|
|
class union_diff;
|
|
class scope_diff;
|
|
class fn_parm_diff;
|
|
class function_type_diff;
|
|
class function_decl_diff;
|
|
class var_diff;
|
|
class translation_unit_diff;
|
|
class corpus_diff;
|
|
class diff_maps;
|
|
class reporter_base;
|
|
|
|
/// A convenience typedef for a shared pointer to a @ref
|
|
/// reporter_base.
|
|
typedef shared_ptr<reporter_base> reporter_base_sptr;
|
|
|
|
/// The base class of all the reporting classes.
|
|
class reporter_base
|
|
{
|
|
public:
|
|
|
|
virtual bool diff_to_be_reported(const diff *d) const;
|
|
|
|
virtual bool diff_has_net_changes(const corpus_diff *d) const = 0;
|
|
|
|
virtual void
|
|
report(const type_decl_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const enum_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const typedef_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const qualified_type_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const distinct_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const pointer_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const reference_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const array_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const base_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const class_or_union_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const class_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const union_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const scope_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const fn_parm_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const function_type_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const function_decl_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const var_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const translation_unit_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual void
|
|
report(const corpus_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const = 0;
|
|
|
|
virtual ~reporter_base() {}
|
|
}; //end class reporter_base
|
|
|
|
class default_reporter;
|
|
|
|
/// A convenience typedef for a shared_ptr to a @ref default_reporter.
|
|
typedef shared_ptr<default_reporter> default_reporter_sptr;
|
|
|
|
/// The default, initial, reporter of the libabigail comparison engine.
|
|
class default_reporter : public reporter_base
|
|
{
|
|
public:
|
|
|
|
virtual bool diff_has_net_changes(const corpus_diff *d) const;
|
|
|
|
virtual void
|
|
report(const type_decl_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const enum_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
void
|
|
report_non_type_typedef_changes(const typedef_diff &d,
|
|
std::ostream& out,
|
|
const std::string& indent) const;
|
|
|
|
virtual void
|
|
report(const typedef_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
bool
|
|
report_local_qualified_type_changes(const qualified_type_diff& d,
|
|
std::ostream& out,
|
|
const std::string& indent) const;
|
|
|
|
virtual void
|
|
report(const qualified_type_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const pointer_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
void
|
|
report_local_reference_type_changes(const reference_diff& d,
|
|
std::ostream& out,
|
|
const std::string& indent) const;
|
|
|
|
virtual void
|
|
report(const reference_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const fn_parm_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
void
|
|
report_local_function_type_changes(const function_type_diff& d,
|
|
std::ostream& out,
|
|
const std::string& indent) const;
|
|
|
|
virtual void
|
|
report(const function_type_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const array_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const base_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const scope_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const class_or_union_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const class_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const union_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const distinct_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const function_decl_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const var_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const translation_unit_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const corpus_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
}; // end class default_reporter
|
|
|
|
/// A reporter that only reports leaf changes
|
|
class leaf_reporter : public default_reporter
|
|
{
|
|
public:
|
|
|
|
virtual bool diff_to_be_reported(const diff *d) const;
|
|
|
|
virtual bool diff_has_net_changes(const corpus_diff *d) const;
|
|
|
|
void
|
|
report_changes_from_diff_maps(const diff_maps&, std::ostream& out,
|
|
const std::string& indent) const;
|
|
|
|
virtual void
|
|
report(const typedef_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const qualified_type_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const pointer_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const reference_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const fn_parm_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const function_type_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const array_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const scope_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const class_or_union_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const class_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const union_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const distinct_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const function_decl_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const var_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const translation_unit_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
|
|
virtual void
|
|
report(const corpus_diff& d, std::ostream& out,
|
|
const std::string& indent = "") const;
|
|
}; // end class leaf_reporter
|
|
|
|
} // end namespace comparison
|
|
} // end namespace abigail
|
|
|
|
#endif // __ABG_REPORTER_H__
|