mirror of
git://sourceware.org/git/libabigail.git
synced 2025-01-07 01:39:36 +00:00
89ab39de78
In the past, it was common to have a "fake flex array" at the end of a structure. Like this: Nowadays, with improved compiler support, it's more common to use a real flex array. As this is a common change which changes ABI representation in a compatible way, we should have a suppression for it. For example, if you have a change like this: struct foo { int x; int flex[1]; }; ... struct foo { int x; int flex[]; }; abidiff reports: [C] 'struct foo' changed: type size changed from 64 to 32 (in bits) 1 data member change: type of 'int flex[1]' changed: type name changed from 'int[1]' to 'int[]' array type size changed from 32 to 'unknown' array type subrange 1 changed length from 1 to 'unknown' With a new has_strict_flexible_array_data_member_conversion property, users can specify a suppression which stops abidiff from emitting this diff for any "fake" flex arrays being converted to real ones: [suppress_type] type_kind = struct has_size_change = true has_strict_flexible_array_data_member_conversion = true * include/abg-comp-filter.h (has_strict_fam_conversion): Declare new functions. * include/abg-fwd.h (ir::has_fake_flexible_array_data_member): Declare new accessor functions. * include/abg-suppression.h (type_suppression::{,set_}has_strict_fam_conversion): Declare new accessor functions. * src/abg-comp-filter.cc (has_strict_fam_conversion): Define new functions. * src/abg-ir.cc (ir::has_fake_flexible_array_data_member): Define new accessor functions. * src/abg-suppression-priv.h (type_suppression::priv::has_strict_fam_conv_): Define new data member. * src/abg-suppression.cc (type_suppression::{,set_}has_strict_fam_conversion): Define new accessor functions. (type_suppression::suppresses_diff): For a type suppression to match a fake flex array conversion, either the size of the type hasn't change or has_size_change must be true and then the type must change from a fake flex array to a real flex array. (read_type_suppression): Parse the new 'has_strict_flexible_array_data_member_conversion' property to set the type_suppression::set_has_strict_fam_conversion property. * doc/manuals/libabigail-concepts.rst: Add an entry for the new 'has_strict_flexible_array_data_member_conversion' property. * tests/data/test-diff-suppr/test-has-strict-flexible-array-data-member-conversion-{1,2}.suppr: Add new test suppression files. * tests/data/test-diff-suppr/test-has-strict-flexible-array-data-member-conversion-report-{1,2}.txt: Add new test reference output files. * tests/data/test-diff-suppr/test-has-strict-flexible-array-data-member-conversion-v{0,1}.c: Add source code for new binary test input files. * tests/data/test-diff-suppr/test-has-strict-flexible-array-data-member-conversion-v{0,1}.o: Add new binary test input files. * tests/data/Makefile.am: Add the new test files to the source distribution. * tests/test-diff-suppr.cc (in_out_specs): Add the new test input files to this test harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com> Signed-off-by: John Moon <quic_johmoo@quicinc.com>
1029 lines
25 KiB
C++
1029 lines
25 KiB
C++
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
// -*- Mode: C++ -*-
|
|
//
|
|
// Copyright (C) 2016-2023 Red Hat, Inc.
|
|
//
|
|
// Author: Dodji Seketeli
|
|
|
|
#ifndef __ABG_SUPPRESSION_H__
|
|
#define __ABG_SUPPRESSION_H__
|
|
|
|
#include <unordered_set>
|
|
|
|
#include "abg-ini.h"
|
|
#include "abg-ir.h"
|
|
|
|
namespace abigail
|
|
{
|
|
|
|
class fe_iface;
|
|
|
|
/// @brief an engine to suppress the parts of the result of comparing
|
|
/// two sets of ABI artifacts.
|
|
///
|
|
/// The user specifies the kind of changes between ABI artefact she
|
|
/// wants to see suppressed. That suppression specification is done
|
|
/// in an INI format.
|
|
///
|
|
/// That INI file is parsed and represented internally using the types
|
|
/// that are defined in this namespace.
|
|
namespace suppr
|
|
{
|
|
using std::unordered_set;
|
|
using std::string;
|
|
using std::shared_ptr;
|
|
using std::vector;
|
|
using comparison::diff;
|
|
using comparison::diff_context_sptr;
|
|
|
|
/// Base type of a direct suppression specifications types.
|
|
///
|
|
/// This abstracts a suppression specification. It's a way to specify
|
|
/// how to drop reports about a particular diff node on the floor, if
|
|
/// it matches the supppression specification.
|
|
///
|
|
/// Note that a direct suppression specification suppresses (for
|
|
/// reporting purposes) the diff node that it matches. A negated
|
|
/// suppression specification, however, suppresses a diff node that it
|
|
/// DOES NOT match. A Negated suppression specification is abstracted
|
|
/// by the class @ref negated_suppression_base.
|
|
class suppression_base
|
|
{
|
|
public:
|
|
class priv; // declare publicly to allow subclasses to reuse the priv
|
|
private:
|
|
// Forbid default constructor
|
|
suppression_base();
|
|
|
|
public:
|
|
std::unique_ptr<priv> priv_;
|
|
|
|
suppression_base(const string& label);
|
|
|
|
suppression_base(const string& label,
|
|
const string& file_name_regex_str,
|
|
const string& file_name_not_regex_str);
|
|
|
|
bool
|
|
get_drops_artifact_from_ir() const;
|
|
|
|
void
|
|
set_drops_artifact_from_ir(bool);
|
|
|
|
bool
|
|
get_is_artificial() const;
|
|
|
|
void
|
|
set_is_artificial(bool);
|
|
|
|
const string
|
|
get_label() const;
|
|
|
|
void
|
|
set_label(const string&);
|
|
|
|
void
|
|
set_file_name_regex_str(const string& regexp);
|
|
|
|
const string&
|
|
get_file_name_regex_str() const;
|
|
|
|
void
|
|
set_file_name_not_regex_str(const string& regexp);
|
|
|
|
const string&
|
|
get_file_name_not_regex_str() const;
|
|
|
|
bool
|
|
has_file_name_related_property() const;
|
|
|
|
void
|
|
set_soname_regex_str(const string& regexp);
|
|
|
|
const string&
|
|
get_soname_regex_str() const;
|
|
|
|
void
|
|
set_soname_not_regex_str(const string& regexp);
|
|
|
|
const string&
|
|
get_soname_not_regex_str() const;
|
|
|
|
bool
|
|
has_soname_related_property() const;
|
|
|
|
virtual bool
|
|
suppresses_diff(const diff*) const = 0;
|
|
|
|
virtual ~suppression_base();
|
|
|
|
friend bool
|
|
suppression_matches_soname(const string& soname,
|
|
const suppression_base& suppr);
|
|
|
|
friend bool
|
|
suppression_matches_soname_or_filename(const string& soname,
|
|
const string& filename,
|
|
const suppression_base& suppr);
|
|
}; // end class suppression_base
|
|
|
|
/// Convenience typedef for a shared pointer to a @ref suppression.
|
|
typedef shared_ptr<suppression_base> suppression_sptr;
|
|
|
|
/// Convenience typedef for a vector of @ref suppression_sptr
|
|
typedef vector<suppression_sptr> suppressions_type;
|
|
|
|
void
|
|
read_suppressions(std::istream& input,
|
|
suppressions_type& suppressions);
|
|
|
|
void
|
|
read_suppressions(const string& file_path,
|
|
suppressions_type& suppressions);
|
|
|
|
class type_suppression;
|
|
|
|
/// Convenience typedef for a shared pointer to type_suppression.
|
|
typedef shared_ptr<type_suppression> type_suppression_sptr;
|
|
|
|
/// Convenience typedef for vector of @ref type_suppression_sptr.
|
|
typedef vector<type_suppression_sptr> type_suppressions_type;
|
|
|
|
/// The base class of suppression specifications that are defined by
|
|
/// the negation of matching clauses.
|
|
///
|
|
/// A direct suppression specification suppresses (for reporting
|
|
/// purposes) the diff node that it matches. A negated suppression
|
|
/// specification suppresses a diff node that it DOES NOT match.
|
|
class negated_suppression_base
|
|
{
|
|
public:
|
|
negated_suppression_base();
|
|
|
|
virtual ~negated_suppression_base();
|
|
}; // end class negated_suppression_base.
|
|
|
|
/// A convenience typedef for a shared pointer to @ref
|
|
/// negated_suppression_base.
|
|
typedef shared_ptr<negated_suppression_base> negated_suppression_sptr;
|
|
|
|
/// Convenience typedef for a vector of @ref negated_suppression_sptr
|
|
typedef vector<negated_suppression_sptr> negated_suppressions_type;
|
|
|
|
bool
|
|
is_negated_suppression(const suppression_base&);
|
|
|
|
const negated_suppression_base*
|
|
is_negated_suppression(const suppression_base*);
|
|
|
|
negated_suppression_sptr
|
|
is_negated_suppression(const suppression_sptr&);
|
|
|
|
/// Abstraction of a type suppression specification.
|
|
///
|
|
/// Specifies under which condition reports about a type diff node
|
|
/// should be dropped on the floor.
|
|
class type_suppression : public suppression_base
|
|
{
|
|
class priv;
|
|
|
|
// Forbid this;
|
|
type_suppression();
|
|
|
|
public:
|
|
std::unique_ptr<priv> priv_;
|
|
|
|
/// The kind of the type the current type suppression is supposed to
|
|
/// be about.
|
|
enum type_kind
|
|
{
|
|
UNKNOWN_TYPE_KIND,
|
|
CLASS_TYPE_KIND,
|
|
STRUCT_TYPE_KIND,
|
|
UNION_TYPE_KIND,
|
|
ENUM_TYPE_KIND,
|
|
ARRAY_TYPE_KIND,
|
|
TYPEDEF_TYPE_KIND,
|
|
BUILTIN_TYPE_KIND
|
|
}; // end enum type_kind
|
|
|
|
/// The different ways through which the type diff has been reached.
|
|
enum reach_kind
|
|
{
|
|
/// The type diff has been reached (from a function or variable
|
|
/// change) directly.
|
|
DIRECT_REACH_KIND = 0,
|
|
|
|
/// The type diff has been reached (from a function or variable
|
|
/// change) through a pointer.
|
|
POINTER_REACH_KIND,
|
|
|
|
/// The type diff has been reached (from a function or variable
|
|
/// change) through a reference; you know, like a c++ reference..
|
|
REFERENCE_REACH_KIND,
|
|
|
|
/// The type diff has been reached (from a function or variable
|
|
/// change) through either a reference or a pointer.
|
|
REFERENCE_OR_POINTER_REACH_KIND
|
|
}; // end enum reach_kind
|
|
|
|
class insertion_range;
|
|
/// A convenience typedef for a shared pointer to @ref
|
|
/// insertion_range.
|
|
typedef shared_ptr<insertion_range> insertion_range_sptr;
|
|
/// A convenience typedef for a vector of @ref insertion_range_sptr.
|
|
typedef vector<insertion_range_sptr> insertion_ranges;
|
|
|
|
type_suppression(const string& label,
|
|
const string& type_name_regexp,
|
|
const string& type_name);
|
|
|
|
virtual ~type_suppression();
|
|
|
|
void
|
|
set_type_name_regex_str(const string& name_regex_str);
|
|
|
|
const string&
|
|
get_type_name_regex_str() const;
|
|
|
|
void
|
|
set_type_name_not_regex_str(const string& name_regex_str);
|
|
|
|
const string&
|
|
get_type_name_not_regex_str() const;
|
|
|
|
void
|
|
set_type_name(const string& name);
|
|
|
|
const string&
|
|
get_type_name() const;
|
|
|
|
bool
|
|
get_consider_type_kind() const;
|
|
|
|
void
|
|
set_consider_type_kind(bool f);
|
|
|
|
void
|
|
set_type_kind(type_kind k);
|
|
|
|
type_kind
|
|
get_type_kind() const;
|
|
|
|
bool
|
|
get_consider_reach_kind() const;
|
|
|
|
void
|
|
set_consider_reach_kind(bool f);
|
|
|
|
reach_kind
|
|
get_reach_kind() const;
|
|
|
|
void
|
|
set_reach_kind(reach_kind k);
|
|
|
|
bool
|
|
get_has_size_change() const;
|
|
|
|
void
|
|
set_has_size_change(bool flag);
|
|
|
|
const string_set_type&
|
|
get_potential_data_member_names() const;
|
|
|
|
void
|
|
set_potential_data_member_names(const string_set_type&) const;
|
|
|
|
const string&
|
|
get_potential_data_member_names_regex_str() const;
|
|
|
|
void
|
|
set_potential_data_member_names_regex_str(const string&) const;
|
|
|
|
void
|
|
set_data_member_insertion_ranges(const insertion_ranges& r);
|
|
|
|
const insertion_ranges&
|
|
get_data_member_insertion_ranges() const;
|
|
|
|
insertion_ranges&
|
|
get_data_member_insertion_ranges();
|
|
|
|
const unordered_set<string>&
|
|
get_source_locations_to_keep() const;
|
|
|
|
unordered_set<string>&
|
|
get_source_locations_to_keep();
|
|
|
|
void
|
|
set_source_locations_to_keep(const unordered_set<string>&);
|
|
|
|
const string&
|
|
get_source_location_to_keep_regex_str() const;
|
|
|
|
void
|
|
set_source_location_to_keep_regex_str(const string&);
|
|
|
|
const vector<string>&
|
|
get_changed_enumerator_names() const;
|
|
|
|
void
|
|
set_changed_enumerator_names(const vector<string>&);
|
|
|
|
const vector<regex::regex_t_sptr>&
|
|
get_changed_enumerators_regexp() const;
|
|
|
|
void
|
|
set_changed_enumerators_regexp(const vector<regex::regex_t_sptr>&);
|
|
|
|
bool
|
|
has_strict_fam_conversion () const;
|
|
|
|
void
|
|
set_has_strict_fam_conversion(bool);
|
|
|
|
virtual bool
|
|
suppresses_diff(const diff* diff) const;
|
|
|
|
bool
|
|
suppresses_type(const type_base_sptr& type,
|
|
const diff_context_sptr& ctxt) const;
|
|
|
|
bool
|
|
suppresses_type(const type_base_sptr& type) const;
|
|
|
|
bool
|
|
suppresses_type(const type_base_sptr& type,
|
|
const scope_decl* type_scope) const;
|
|
}; // end type_suppression
|
|
|
|
type_suppression_sptr
|
|
is_type_suppression(const suppression_sptr);
|
|
|
|
/// The abstraction of a range of offsets in which a member of a type
|
|
/// might get inserted.
|
|
class type_suppression::insertion_range
|
|
{
|
|
struct priv;
|
|
std::unique_ptr<priv> priv_;
|
|
|
|
public:
|
|
|
|
class boundary;
|
|
class integer_boundary;
|
|
class fn_call_expr_boundary;
|
|
class named_boundary;
|
|
|
|
/// Convenience typedef for a shared_ptr to @ref boundary
|
|
typedef shared_ptr<boundary> boundary_sptr;
|
|
|
|
/// Convenience typedef for a shared_ptr to a @ref integer_boundary
|
|
typedef shared_ptr<integer_boundary> integer_boundary_sptr;
|
|
|
|
/// Convenience typedef for a shared_ptr to a @ref
|
|
/// fn_call_expr_boundary
|
|
typedef shared_ptr<fn_call_expr_boundary> fn_call_expr_boundary_sptr;
|
|
|
|
/// Convenience typedef for a shared_ptr to a @ref
|
|
/// named_boundary
|
|
typedef shared_ptr<named_boundary> named_boundary_sptr;
|
|
|
|
insertion_range();
|
|
|
|
insertion_range(boundary_sptr begin, boundary_sptr end);
|
|
|
|
boundary_sptr
|
|
begin() const;
|
|
|
|
boundary_sptr
|
|
end() const;
|
|
|
|
static insertion_range::integer_boundary_sptr
|
|
create_integer_boundary(int value);
|
|
|
|
static insertion_range::fn_call_expr_boundary_sptr
|
|
create_fn_call_expr_boundary(ini::function_call_expr_sptr);
|
|
|
|
static insertion_range::fn_call_expr_boundary_sptr
|
|
create_fn_call_expr_boundary(const string&);
|
|
|
|
static insertion_range::named_boundary_sptr
|
|
create_named_boundary(const string&);
|
|
|
|
static bool
|
|
eval_boundary(const boundary_sptr boundary,
|
|
const class_or_union* context,
|
|
uint64_t& value);
|
|
|
|
static bool
|
|
boundary_value_is_end(uint64_t value);
|
|
}; // end class insertion_range
|
|
|
|
type_suppression::insertion_range::integer_boundary_sptr
|
|
is_integer_boundary(type_suppression::insertion_range::boundary_sptr);
|
|
|
|
type_suppression::insertion_range::fn_call_expr_boundary_sptr
|
|
is_fn_call_expr_boundary(type_suppression::insertion_range::boundary_sptr);
|
|
|
|
type_suppression::insertion_range::named_boundary_sptr
|
|
is_named_boundary(type_suppression::insertion_range::boundary_sptr);
|
|
|
|
/// The abstraction of the boundary of an @ref insertion_range, in the
|
|
/// context of a @ref type_suppression
|
|
class type_suppression::insertion_range::boundary
|
|
{
|
|
struct priv;
|
|
std::unique_ptr<priv> priv_;
|
|
|
|
public:
|
|
boundary();
|
|
virtual ~boundary();
|
|
};// end class type_suppression::insertion_range::boundary
|
|
|
|
/// An @ref insertion_range boundary that is expressed as an integer
|
|
/// value. That integer value is usually a bit offset.
|
|
class type_suppression::insertion_range::integer_boundary
|
|
: public type_suppression::insertion_range::boundary
|
|
{
|
|
struct priv;
|
|
std::unique_ptr<priv> priv_;
|
|
|
|
integer_boundary();
|
|
|
|
public:
|
|
integer_boundary(uint64_t value);
|
|
uint64_t as_integer() const;
|
|
operator uint64_t () const;
|
|
~integer_boundary();
|
|
}; //end class type_suppression::insertion_range::integer_boundary
|
|
|
|
/// An @ref insertion_range boundary that is expressed as function
|
|
/// call expression. The (integer) value of that expression is
|
|
/// usually a bit offset.
|
|
class type_suppression::insertion_range::fn_call_expr_boundary
|
|
: public type_suppression::insertion_range::boundary
|
|
{
|
|
struct priv;
|
|
std::unique_ptr<priv> priv_;
|
|
|
|
fn_call_expr_boundary();
|
|
|
|
public:
|
|
fn_call_expr_boundary(ini::function_call_expr_sptr expr);
|
|
ini::function_call_expr_sptr as_function_call_expr() const;
|
|
operator ini::function_call_expr_sptr () const;
|
|
~fn_call_expr_boundary();
|
|
}; //end class type_suppression::insertion_range::fn_call_expr_boundary
|
|
|
|
/// An @ref insertion_range boundary that is expressed as a named
|
|
/// constant that is to be evaluated later in the context of a given
|
|
/// type and resolved to a bit offset.
|
|
class type_suppression::insertion_range::named_boundary
|
|
: public type_suppression::insertion_range::boundary
|
|
{
|
|
struct priv;
|
|
std::unique_ptr<priv> priv_;
|
|
|
|
named_boundary();
|
|
|
|
public:
|
|
named_boundary(const string& name);
|
|
const string& get_name() const;
|
|
}; //end class type_suppression::insertion_range::named_boundary
|
|
|
|
/// Abstraction of a negated type suppression specification.
|
|
///
|
|
/// A negated type suppression suppresses a type if the negation of
|
|
/// the equivalent propositions for a @ref type_suppression are valid.
|
|
class negated_type_suppression : virtual public type_suppression,
|
|
virtual public negated_suppression_base
|
|
{
|
|
|
|
public:
|
|
|
|
negated_type_suppression(const string& label,
|
|
const string& type_name_regexp,
|
|
const string& type_name);
|
|
|
|
virtual bool
|
|
suppresses_diff(const diff* diff) const;
|
|
|
|
bool
|
|
suppresses_type(const type_base_sptr& type,
|
|
const diff_context_sptr& ctxt) const;
|
|
|
|
bool
|
|
suppresses_type(const type_base_sptr& type) const;
|
|
|
|
bool
|
|
suppresses_type(const type_base_sptr& type,
|
|
const scope_decl* type_scope) const;
|
|
|
|
virtual ~negated_type_suppression();
|
|
};// end class negated_type_suppression
|
|
|
|
class function_suppression;
|
|
|
|
/// Convenience typedef for a shared pointer to function_suppression.
|
|
typedef shared_ptr<function_suppression> function_suppression_sptr;
|
|
|
|
/// Convenience typedef for a vector of @ref function_suppression_sptr.
|
|
typedef vector<function_suppression_sptr> function_suppressions_type;
|
|
|
|
/// Abstraction of a function suppression specification.
|
|
///
|
|
/// Specifies under which condition reports about a @ref
|
|
/// function_decl_diff diff node should be dropped on the floor for
|
|
/// the purpose of reporting.
|
|
class function_suppression : public suppression_base
|
|
{
|
|
struct priv;
|
|
|
|
public:
|
|
|
|
std::unique_ptr<priv> priv_;
|
|
class parameter_spec;
|
|
|
|
/// Convenience typedef for shared_ptr of @ref parameter_spec.
|
|
typedef shared_ptr<parameter_spec> parameter_spec_sptr;
|
|
|
|
/// Convenience typedef for vector of @ref parameter_spec_sptr.
|
|
typedef vector<parameter_spec_sptr> parameter_specs_type;
|
|
|
|
/// The kind of change the current function suppression should apply
|
|
/// to.
|
|
enum change_kind
|
|
{
|
|
UNDEFINED_CHANGE_KIND,
|
|
/// A change in a sub-type of the function.
|
|
FUNCTION_SUBTYPE_CHANGE_KIND = 1,
|
|
/// The function was added to the second subject of the diff.
|
|
ADDED_FUNCTION_CHANGE_KIND = 1 << 1,
|
|
/// The function was deleted from the second subject of the diff.
|
|
DELETED_FUNCTION_CHANGE_KIND = 1 << 2,
|
|
/// This represents all the changes possibly described by this
|
|
/// enum. It's a logical 'OR' of all the change enumerators
|
|
/// above.
|
|
ALL_CHANGE_KIND = (FUNCTION_SUBTYPE_CHANGE_KIND
|
|
| ADDED_FUNCTION_CHANGE_KIND
|
|
| DELETED_FUNCTION_CHANGE_KIND)
|
|
};
|
|
|
|
function_suppression();
|
|
|
|
function_suppression(const string& label,
|
|
const string& name,
|
|
const string& name_regex,
|
|
const string& return_type_name,
|
|
const string& return_type_regex,
|
|
parameter_specs_type& parm_specs,
|
|
const string& symbol_name,
|
|
const string& symbol_name_regex,
|
|
const string& symbol_version,
|
|
const string& symbol_version_regex_str);
|
|
|
|
virtual ~function_suppression();
|
|
|
|
static change_kind
|
|
parse_change_kind(const string&);
|
|
|
|
change_kind
|
|
get_change_kind() const;
|
|
|
|
void
|
|
set_change_kind(change_kind k);
|
|
|
|
const string&
|
|
get_name() const;
|
|
|
|
void
|
|
set_name(const string&);
|
|
|
|
const string&
|
|
get_name_regex_str() const;
|
|
|
|
void
|
|
set_name_regex_str(const string&);
|
|
|
|
const string&
|
|
get_name_not_regex_str() const;
|
|
|
|
void
|
|
set_name_not_regex_str(const string&);
|
|
|
|
const string&
|
|
get_return_type_name() const;
|
|
|
|
void
|
|
set_return_type_name(const string&);
|
|
|
|
const string&
|
|
get_return_type_regex_str() const;
|
|
|
|
void
|
|
set_return_type_regex_str(const string& r);
|
|
|
|
const parameter_specs_type&
|
|
get_parameter_specs() const;
|
|
|
|
void
|
|
set_parameter_specs(parameter_specs_type&);
|
|
|
|
void
|
|
append_parameter_specs(const parameter_spec_sptr);
|
|
|
|
const string&
|
|
get_symbol_name() const;
|
|
|
|
void
|
|
set_symbol_name(const string& n);
|
|
|
|
const string&
|
|
get_symbol_name_regex_str() const;
|
|
|
|
void
|
|
set_symbol_name_regex_str(const string&);
|
|
|
|
const string&
|
|
get_symbol_name_not_regex_str() const;
|
|
|
|
void
|
|
set_symbol_name_not_regex_str(const string&);
|
|
|
|
const string&
|
|
get_symbol_version() const;
|
|
|
|
void
|
|
set_symbol_version(const string&);
|
|
|
|
const string&
|
|
get_symbol_version_regex_str() const;
|
|
|
|
void
|
|
set_symbol_version_regex_str(const string&);
|
|
|
|
bool
|
|
get_allow_other_aliases() const;
|
|
|
|
void
|
|
set_allow_other_aliases(bool f);
|
|
|
|
virtual bool
|
|
suppresses_diff(const diff* diff) const;
|
|
|
|
bool
|
|
suppresses_function(const function_decl* fn,
|
|
change_kind k,
|
|
const diff_context_sptr ctxt) const;
|
|
|
|
bool
|
|
suppresses_function(const function_decl_sptr fn,
|
|
change_kind k,
|
|
const diff_context_sptr ctxt) const;
|
|
|
|
bool
|
|
suppresses_function_symbol(const elf_symbol* sym,
|
|
change_kind k,
|
|
const diff_context_sptr ctxt);
|
|
|
|
bool
|
|
suppresses_function_symbol(const elf_symbol_sptr sym,
|
|
change_kind k,
|
|
const diff_context_sptr ctxt);
|
|
}; // end class function_suppression.
|
|
|
|
function_suppression_sptr
|
|
is_function_suppression(const suppression_sptr);
|
|
|
|
function_suppression::change_kind
|
|
operator&(function_suppression::change_kind l,
|
|
function_suppression::change_kind r);
|
|
|
|
function_suppression::change_kind
|
|
operator|(function_suppression::change_kind l,
|
|
function_suppression::change_kind r);
|
|
|
|
/// Abstraction of the specification of a function parameter in a
|
|
/// function suppression specification.
|
|
class function_suppression::parameter_spec
|
|
{
|
|
friend class function_suppression;
|
|
|
|
class priv;
|
|
std::unique_ptr<priv> priv_;
|
|
|
|
// Forbid this.
|
|
parameter_spec();
|
|
|
|
public:
|
|
parameter_spec(size_t index,
|
|
const string& type_name,
|
|
const string& type_name_regex);
|
|
|
|
size_t
|
|
get_index() const;
|
|
|
|
void
|
|
set_index(size_t);
|
|
|
|
const string&
|
|
get_parameter_type_name() const;
|
|
|
|
void
|
|
set_parameter_type_name(const string&);
|
|
|
|
const string&
|
|
get_parameter_type_name_regex_str() const;
|
|
|
|
void
|
|
set_parameter_type_name_regex_str(const string&);
|
|
};// end class function_suppression::parameter_spec
|
|
|
|
class variable_suppression;
|
|
|
|
/// A convenience typedef for a shared pointer to @ref
|
|
/// variable_suppression.
|
|
typedef shared_ptr<variable_suppression> variable_suppression_sptr;
|
|
|
|
/// A convenience typedef for a vector of @ref
|
|
/// variable_suppression_sptr.
|
|
typedef vector<variable_suppression_sptr> variable_suppressions_type;
|
|
|
|
/// The abstraction of a variable suppression specification.
|
|
///
|
|
/// It specifies under which condition reports about a @ref var_diff
|
|
/// diff node should be dropped on the floor for the purpose of
|
|
/// reporting.
|
|
class variable_suppression : public suppression_base
|
|
{
|
|
public:
|
|
|
|
/// The kind of change the current variable suppression should apply
|
|
/// to.
|
|
enum change_kind
|
|
{
|
|
UNDEFINED_CHANGE_KIND,
|
|
/// A change in a sub-type of the variable.
|
|
VARIABLE_SUBTYPE_CHANGE_KIND = 1,
|
|
/// The variable was added to the second second subject of the
|
|
/// diff.
|
|
ADDED_VARIABLE_CHANGE_KIND = 1 << 1,
|
|
/// The variable was deleted from the second subject of the diff.
|
|
DELETED_VARIABLE_CHANGE_KIND = 1 << 2,
|
|
/// This represents all the changes possibly described by this
|
|
/// enum. It's a logical 'OR' of all the change enumerators
|
|
/// above.
|
|
ALL_CHANGE_KIND = (VARIABLE_SUBTYPE_CHANGE_KIND
|
|
| ADDED_VARIABLE_CHANGE_KIND
|
|
| DELETED_VARIABLE_CHANGE_KIND)
|
|
};
|
|
|
|
private:
|
|
struct priv;
|
|
|
|
public:
|
|
std::unique_ptr<priv> priv_;
|
|
|
|
variable_suppression(const string& label = "",
|
|
const string& name = "",
|
|
const string& name_regex_str = "",
|
|
const string& symbol_name = "",
|
|
const string& symbol_name_regex_str = "",
|
|
const string& symbol_version = "",
|
|
const string& symbol_version_regex_str = "",
|
|
const string& type_name = "",
|
|
const string& type_name_regex_str = "");
|
|
|
|
virtual ~variable_suppression();
|
|
|
|
static change_kind
|
|
parse_change_kind(const string&);
|
|
|
|
change_kind
|
|
get_change_kind() const;
|
|
|
|
void
|
|
set_change_kind(change_kind k);
|
|
|
|
const string&
|
|
get_name() const;
|
|
|
|
void
|
|
set_name(const string&);
|
|
|
|
const string&
|
|
get_name_regex_str() const;
|
|
|
|
void
|
|
set_name_regex_str(const string&);
|
|
|
|
const string&
|
|
get_name_not_regex_str() const;
|
|
|
|
void
|
|
set_name_not_regex_str(const string&);
|
|
|
|
const string&
|
|
get_symbol_name() const;
|
|
|
|
void
|
|
set_symbol_name(const string&);
|
|
|
|
const string&
|
|
get_symbol_name_regex_str() const;
|
|
|
|
void
|
|
set_symbol_name_regex_str(const string&);
|
|
|
|
const string&
|
|
get_symbol_name_not_regex_str() const;
|
|
|
|
void
|
|
set_symbol_name_not_regex_str(const string&);
|
|
|
|
const string&
|
|
get_symbol_version() const;
|
|
|
|
void
|
|
set_symbol_version(const string&);
|
|
|
|
const string&
|
|
get_symbol_version_regex_str() const;
|
|
|
|
void
|
|
set_symbol_version_regex_str(const string&);
|
|
|
|
const string&
|
|
get_type_name() const;
|
|
|
|
void
|
|
set_type_name(const string&);
|
|
|
|
const string&
|
|
get_type_name_regex_str() const;
|
|
|
|
void
|
|
set_type_name_regex_str(const string&);
|
|
|
|
bool
|
|
suppresses_diff(const diff* d) const;
|
|
|
|
bool
|
|
suppresses_variable(const var_decl* var,
|
|
change_kind k,
|
|
const diff_context_sptr cxt) const;
|
|
|
|
bool
|
|
suppresses_variable(const var_decl_sptr var,
|
|
change_kind k,
|
|
const diff_context_sptr cxt) const;
|
|
|
|
bool
|
|
suppresses_variable_symbol(const elf_symbol* sym,
|
|
change_kind k,
|
|
const diff_context_sptr cxt) const;
|
|
|
|
bool
|
|
suppresses_variable_symbol(const elf_symbol_sptr fn,
|
|
change_kind k,
|
|
const diff_context_sptr cxt) const;
|
|
}; // end class variable_suppression
|
|
|
|
variable_suppression_sptr
|
|
is_variable_suppression(const suppression_sptr);
|
|
|
|
variable_suppression::change_kind
|
|
operator&(variable_suppression::change_kind l,
|
|
variable_suppression::change_kind r);
|
|
|
|
variable_suppression::change_kind
|
|
operator|(variable_suppression::change_kind l,
|
|
variable_suppression::change_kind r);
|
|
|
|
class file_suppression;
|
|
|
|
/// A convenience typedef for a shared_ptr to @ref file_suppression
|
|
typedef shared_ptr<file_suppression> file_suppression_sptr;
|
|
|
|
/// Abstraction of a suppression specification to avoid loading a
|
|
/// file.
|
|
///
|
|
/// This can be used by a tool that loads (binary) files, to know
|
|
/// which file it has to avoid loading.
|
|
class file_suppression: public suppression_base
|
|
{
|
|
std::unique_ptr<priv> priv_;
|
|
|
|
// Forbid this
|
|
file_suppression();
|
|
|
|
public:
|
|
|
|
file_suppression(const string& label,
|
|
const string& file_name_regex,
|
|
const string& file_name_not_regex);
|
|
|
|
virtual bool
|
|
suppresses_diff(const diff* diff) const;
|
|
|
|
bool
|
|
suppresses_file(const string& file_path);
|
|
|
|
virtual ~file_suppression();
|
|
}; // end file_suppression
|
|
|
|
file_suppression_sptr
|
|
is_file_suppression(const suppression_sptr);
|
|
|
|
file_suppression_sptr
|
|
file_is_suppressed(const string& file_path,
|
|
const suppressions_type& suppressions);
|
|
|
|
bool
|
|
suppression_matches_soname(const string& soname,
|
|
const suppression_base& suppr);
|
|
|
|
bool
|
|
suppression_matches_soname_or_filename(const string& soname,
|
|
const string& filename,
|
|
const suppression_base& suppr);
|
|
|
|
const char*
|
|
get_private_types_suppr_spec_label();
|
|
|
|
bool
|
|
is_private_type_suppr_spec(const type_suppression&);
|
|
|
|
bool
|
|
is_private_type_suppr_spec(const suppression_sptr& s);
|
|
|
|
bool
|
|
suppression_can_match(const fe_iface&,
|
|
const suppression_base&);
|
|
|
|
bool
|
|
suppression_matches_function_name(const fe_iface&,
|
|
const suppr::function_suppression&,
|
|
const string&);
|
|
|
|
bool
|
|
suppression_matches_function_sym_name(const fe_iface&,
|
|
const suppr::function_suppression& s,
|
|
const string& fn_linkage_name);
|
|
|
|
bool
|
|
suppression_matches_variable_name(const fe_iface&,
|
|
const suppr::variable_suppression& s,
|
|
const string& var_name);
|
|
|
|
bool
|
|
suppression_matches_variable_sym_name(const fe_iface&,
|
|
const suppr::variable_suppression&,
|
|
const string&);
|
|
|
|
bool
|
|
suppression_matches_type_name_or_location(const fe_iface&,
|
|
const suppr::type_suppression&,
|
|
const string&,
|
|
const location&);
|
|
|
|
bool
|
|
is_elf_symbol_suppressed(const fe_iface&,
|
|
const elf_symbol_sptr& symbol);
|
|
|
|
bool
|
|
is_elf_symbol_suppressed(const fe_iface&,
|
|
const string& sym_name,
|
|
elf_symbol::type sym_type);
|
|
|
|
bool
|
|
is_function_suppressed(const fe_iface& fe,
|
|
const string& fn_name,
|
|
const string& fn_linkage_name,
|
|
bool require_drop_property = false);
|
|
|
|
bool
|
|
is_variable_suppressed(const fe_iface& fe,
|
|
const string& var_name,
|
|
const string& var_linkage_name,
|
|
bool require_drop_property = false);
|
|
|
|
bool
|
|
is_type_suppressed(const fe_iface& fe,
|
|
const string& type_name,
|
|
const location& type_location,
|
|
bool& type_is_private,
|
|
bool require_drop_property = false);
|
|
|
|
bool
|
|
is_data_member_offset_in_range(const var_decl_sptr&,
|
|
const type_suppression::insertion_range_sptr&,
|
|
const class_or_union*);
|
|
|
|
} // end namespace suppr
|
|
|
|
|
|
} // end namespace abigail
|
|
|
|
#endif //__ABG_SUPPRESSION_H__
|