mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-14 22:14:35 +00:00
76d832115d
When a class is forward-declared, resolving it to a definition that appears later in the same translation unit or in another translation is an interesting problem. Until now, the declaration would be resolved to the definition of that class found in the binary. The problem is that there can be different such definitions, especially in C where there is no "One Definition Rule". In that case, the definition chosen is random. This patch resolves that randomness. For a given class declaration, if there is just one possible definition in the binary, then the declaration is resolved to that definition. If there is one definition for that declaration in the same translation unit, then the declaration is resolved to that definition. If there are more than one definitions in translation units that are not the one of the declaration, then the declaration is left unresolved. This is what I call "selective class declaration resolution". Note that an unresolved class declaration now compares different to a definition of a class of the same name. This is so that we can have an unresolved class be present in the resulting .abi file, alongside an (incompatible) definition of the same class. The change from a class declaration to its definition is filtered out by default, though. * include/abg-fwd.h (type_base_wptrs_type) (istring_type_base_wptrs_map_type): Define new typedefs. (lookup_class_types): Declare new functions. * include/abg-ir.h (environment::decl_only_class_equals_definition): Declare new accessor. (type_maps::{*_types}): Make these accessors return istring_type_base_wptrs_map_type& instead of istring_type_base_wptr_map_type&. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes): Implement the new selective declaration resolution scheme. * src/abg-ir.cc (type_maps::priv::{*_types_}): Change the type of these data members from istring_type_base_wptr_map_type to istring_type_base_wptrs_map_type. (type_maps::{*_types}): Make these accessors definitions return istring_type_base_wptrs_map_type& instead of istring_type_base_wptr_map_type&. (translation_unit::bind_function_type_life_time): Adjust. (environment::priv::decl_only_class_equals_definition_): New data member. (environment::priv::priv): Initialize it. By default, a decl-only class is now considered different from its definition. (environment::decl_only_class_equals_definition): Define new accessor. (lookup_types_in_map, lookup_class_types): Define new functions. (lookup_type_in_map, lookup_union_type_per_location) (lookup_basic_type, lookup_basic_type_per_location) (lookup_class_type, lookup_class_type_per_location) (lookup_union_type, lookup_enum_type) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, lookup_qualified_type) (lookup_pointer_type, lookup_reference_type, lookup_array_type) (lookup_function_type, maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Adjust. (type_base::get_canonical_type_for): When doing type comparison here, we can now consider that an unresolved class declaration compares different to an incompatible class definition of the same name. So no need to look through decl-only classes in that case. (equals): In the overload for class_or_union, if environment::decl_only_class_equals_definition() is false, then an unresolved class declaration of name "N" compares different to a class definition named "N". * tests/data/test-annotate/test15-pr18892.so.abi: Adjust. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust * tests/data/test-read-dwarf/test12-pr18844.so.abi: Adjust. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Adjust. * tests/data/test-diff-dwarf/test28-vtable-changes-report-0.txt: Adjust. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Adjust. * tests/data/test-diff-filter/test38/Makefile: New test material. * tests/data/test-diff-filter/test38/test38-a.c: Likewise. * tests/data/test-diff-filter/test38/test38-b.c: Likewise. * tests/data/test-diff-filter/test38/test38-c.c: Likewise. * tests/data/test-diff-filter/test38/test38-report-0.txt: Likewise. * tests/data/test-diff-filter/test38/test38-v0: Likewise. * tests/data/test-diff-filter/test38/test38-v1: Likewise. * tests/data/test-diff-filter/test38/test38.h: Likewise. * tests/data/test-diff-filter/test39/Makefile: Likewise. * tests/data/test-diff-filter/test39/test39-a-v0.c: Likewise. * tests/data/test-diff-filter/test39/test39-a-v1.c: Likewise. * tests/data/test-diff-filter/test39/test39-b-v0.c: Likewise. * tests/data/test-diff-filter/test39/test39-b-v1.c: Likewise. * tests/data/test-diff-filter/test39/test39-c-v0.c: Likewise. * tests/data/test-diff-filter/test39/test39-c-v1.c: Likewise. * tests/data/test-diff-filter/test39/test39-main.c: Likewise. * tests/data/test-diff-filter/test39/test39-report-0.txt: Likewise. * tests/data/test-diff-filter/test39/test39-v0: Likewise. * tests/data/test-diff-filter/test39/test39-v1: Likewise. * tests/data/test-diff-filter/test39/test39.h: Likewise. * tests/data/Makefile.am: Add the new test material above to the source distribution. * tests/test-diff-filter.cc (in_out_specs): Add the new test inputs above to the test harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
114 lines
3.3 KiB
C++
114 lines
3.3 KiB
C++
// -*- Mode: C++ -*-
|
|
//
|
|
// Copyright (C) 2013-2016 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);
|
|
|
|
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__
|