libabigail/include/abg-fwd.h

1368 lines
32 KiB
C
Raw Normal View History

// -*- Mode: C++ -*-
//
Update copyright year to 2020 We are in February 2020 so this is long overdue. * include/abg-comp-filter.h: Update copyright year to 2020. * include/abg-comparison.h: Likewise. * include/abg-config.h: Likewise. * include/abg-corpus.h: Likewise. * include/abg-cxx-compat.h: Likewise. * include/abg-diff-utils.h: Likewise. * include/abg-dwarf-reader.h: Likewise. * include/abg-fwd.h: Likewise. * include/abg-hash.h: Likewise. * include/abg-ini.h: Likewise. * include/abg-interned-str.h: Likewise. * include/abg-ir.h: Likewise. * include/abg-libxml-utils.h: Likewise. * include/abg-libzip-utils.h: Likewise. * include/abg-reader.h: Likewise. * include/abg-reporter.h: Likewise. * include/abg-sptr-utils.h: Likewise. * include/abg-suppression.h: Likewise. * include/abg-tools-utils.h: Likewise. * include/abg-traverse.h: Likewise. * include/abg-viz-common.h: Likewise. * include/abg-viz-dot.h: Likewise. * include/abg-viz-svg.h: Likewise. * include/abg-workers.h: Likewise. * include/abg-writer.h: Likewise. * src/abg-comp-filter.cc: Likewise. * src/abg-comparison-priv.h: Likewise. * src/abg-comparison.cc: Likewise. * src/abg-config.cc: Likewise. * src/abg-corpus-priv.h: Likewise. * src/abg-corpus.cc: Likewise. * src/abg-default-reporter.cc: Likewise. * src/abg-diff-utils.cc: Likewise. * src/abg-dwarf-reader.cc: Likewise. * src/abg-hash.cc: Likewise. * src/abg-ini.cc: Likewise. * src/abg-internal.h: Likewise. * src/abg-ir-priv.h: Likewise. * src/abg-ir.cc: Likewise. * src/abg-leaf-reporter.cc: Likewise. * src/abg-libxml-utils.cc: Likewise. * src/abg-libzip-utils.cc: Likewise. * src/abg-reader.cc: Likewise. * src/abg-reporter-priv.cc: Likewise. * src/abg-reporter-priv.h: Likewise. * src/abg-sptr-utils.cc: Likewise. * src/abg-suppression-priv.h: Likewise. * src/abg-suppression.cc: Likewise. * src/abg-tools-utils.cc: Likewise. * src/abg-traverse.cc: Likewise. * src/abg-viz-common.cc: Likewise. * src/abg-viz-dot.cc: Likewise. * src/abg-viz-svg.cc: Likewise. * src/abg-workers.cc: Likewise. * src/abg-writer.cc: Likewise. * tests/print-diff-tree.cc: Likewise. * tests/test-abicompat.cc: Likewise. * tests/test-abidiff-exit.cc: Likewise. * tests/test-abidiff.cc: Likewise. * tests/test-alt-dwarf-file.cc: Likewise. * tests/test-core-diff.cc: Likewise. * tests/test-diff-dwarf-abixml.cc: Likewise. * tests/test-diff-dwarf.cc: Likewise. * tests/test-diff-filter.cc: Likewise. * tests/test-diff-pkg.cc: Likewise. * tests/test-diff-suppr.cc: Likewise. * tests/test-diff2.cc: Likewise. * tests/test-dot.cc: Likewise. * tests/test-ini.cc: Likewise. * tests/test-ir-walker.cc: Likewise. * tests/test-lookup-syms.cc: Likewise. * tests/test-read-dwarf.cc: Likewise. * tests/test-read-write.cc: Likewise. * tests/test-svg.cc: Likewise. * tests/test-tools-utils.cc: Likewise. * tests/test-types-stability.cc: Likewise. * tests/test-utils.cc: Likewise. * tests/test-utils.h: Likewise. * tests/test-write-read-archive.cc: Likewise. * tools/abiar.cc: Likewise. * tools/abicompat.cc: Likewise. * tools/abidiff.cc: Likewise. * tools/abidw.cc: Likewise. * tools/abilint.cc: Likewise. * tools/abipkgdiff.cc: Likewise. * tools/abisym.cc: Likewise. * tools/binilint.cc: Likewise. * tools/kmidiff.cc: Likewise. * update-copyright.sh: Fix the updating script to handle not just "Red Hat, Inc." Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2020-02-21 15:42:35 +00:00
// Copyright (C) 2013-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/>.
/// @file
#ifndef __ABG_IRFWD_H__
#define __ABG_IRFWD_H__
#include <stdint.h>
Support virtual member functions with vtable offset not yet set When reading C++ class informatin DWARF, it can happen that a given virtual member function does not yet have a vtable offset. Right now, that offset is set to zero. Just like a virtual member function which actual vtable offset is zero. So we don't make a difference between a virtual function with no vtable offset and a virtual function with a vtable offset set to zero. This can lead to confusions during class comparison. This patch fixes that problem by setting the default vtable offset to -1. So whenever a vtable offset is -1 it means that the virtual member function doesn't yet have a vtable offset. * include/abg-fwd.h (member_function_has_vtable_offset): Declare new function. (get_member_function_vtable_offset): Return a ssize_t, not a size_t. (set_member_function_vtable_offset): Take a ssize_t, not a size_t. * include/abg-ir.h (class_decl::virtual_mem_fn_map_type): Adjust the map typedef to make it take ssize_t as the type of the key. (mem_fn_context_rel::vtable_offset_in_bits_): Make this data member be of ssize_t type, not size_t. (mem_fn_context_rel::mem_fn_context_rel): Initialize the vtable_offset_in_bits_ data member to -1. * src/abg-ir.cc (member_function_has_vtable_offset): Define new function. (get_member_function_vtable_offset): Return a ssize_t, not a size_t. (set_member_function_vtable_offset): Take a ssize_t, not a size_t. * src/abg-dwarf-reader.cc (die_virtual_function_index): Take an int64_t& rather than a uint64_t&. (finish_member_function_reading): Don't set the vtable offset if it's -1. * src/abg-reader.cc (build_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 12:40:47 +00:00
#include <cstdlib>
#include <cstddef>
#include <list>
#include <vector>
#include <string>
#include <typeinfo>
#include <utility> // for std::rel_ops, at least.
#include <ostream>
Add compatibility layer for C++11 mode Introduce a compatibility layer for C++11 code by adding include/abg-cxx-compat.h. abg-cxx-compat defines a new namespace abg_compat and defines abg_compat::hash abg_compat::shared_ptr abg_compat::weak_ptr abg_compat::dynamic_pointer_cast abg_compat::static_pointer_cast abg_compat::unordered_map abg_compat::unordered_set based on definitions from std::tr1 (std=gnu++98) or std:: (std=gnu++11). I decided for introducing abg_compat:: rather than polluting abigail:: to allow an easier transition to C++11 at a later time and to not subtly break existing code. As the shared_ptr in C++11 defines shared_ptr::operator bool() explicit, some locations where a shared_ptr is assigned to boolean, needed to be adjusted to explicitly cast to bool. * include/abg-cxx-compat.h: new file introducing the abg_compat namespace to provide C++11 functionality from either std::tr1 or std:: * include/Makefile.am: Add the new abg-cxx-compat.h to source distribution. * include/abg-comparison.h: replace std::tr1 usage by abg_compat and adjust includes accordingly: likewise * include/abg-diff-utils.h: likewise * include/abg-fwd.h: likewise * include/abg-ini.h: likewise * include/abg-interned-str.h: likewise * include/abg-ir.h: likewise * include/abg-libxml-utils.h: likewise * include/abg-libzip-utils.h: likewise * include/abg-reporter.h: likewise * include/abg-sptr-utils.h: likewise * include/abg-suppression.h: likewise * include/abg-tools-utils.h: likewise * include/abg-workers.h: likewise * src/abg-comp-filter.cc: likewise * src/abg-comparison-priv.h: likewise * src/abg-corpus.cc: likewise * src/abg-dwarf-reader.cc: likewise * src/abg-hash.cc: likewise * src/abg-ir.cc: likewise * src/abg-reader.cc: likewise * src/abg-suppression.cc: likewise * src/abg-tools-utils.cc: likewise * src/abg-writer.cc: likewise * tests/test-diff-filter.cc: likewise * tests/test-diff-pkg.cc: likewise * tests/test-read-dwarf.cc: likewise * tests/test-read-write.cc: likewise * tests/test-types-stability.cc: likewise * tests/test-write-read-archive.cc: likewise * tools/abicompat.cc: likewise * tools/abidiff.cc: likewise * tools/abidw.cc: likewise * tools/abilint.cc: likewise * tools/abipkgdiff.cc: likewise Signed-off-by: Matthias Maennich <maennich@google.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-05 11:00:23 +00:00
#include "abg-cxx-compat.h"
Implement string interning for Libabigail This patch implements string interning optimization. One can read about the principles of this optimization at https://en.wikipedia.org/wiki/String_interning. The patch introduces an abigail::interned_string type, as well as an abigail::interned_string_pool type. Each environment type owns a string pool and strings are interned in that pool for all types and decls of that environments. The interned_string has methods to interact seemingly with std::string including a hashing function. Of course hashing and comparing interned_string is faster than for std::string. To enable ABI artifacts to intern strings, each constructor of ABI artifacts now takes the environment it's constructed in as parameter. From the environment, it can thus use the interned string pool. The patch then changes declaration names to be of type interned_string, and performs the necessary adjustments. The hash maps that hash strings coming from those declaration names are adjusted to hash interned_string. * include/Makefile.am: Add the new abg-interned-str.h file to source distribution. * include/abg-corpus.h (corpus::corpus): Re-arrange the order of * src/abg-corpus.cc (corpus::exported_decls_builder::priv::get_id): Return interned_string rather than std::string. (corpus::corpus): Re-arrange the order of parameters: take an environment as first parameter. parameters: take an environment as first parameter. * include/abg-dwarf-reader.h (lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Likewise. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab) (lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab) (lookup_symbol_from_elf, lookup_public_function_symbol_from_elf) (lookup_public_variable_symbol_from_elf, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Take an environment as first parameter and adjust. (build_translation_unit_and_add_to_ir) (build_namespace_decl_and_add_to_ir, build_type_decl) (build_enum_type, finish_member_function_reading) (build_class_type_and_add_to_ir, build_function_type) (read_debug_info_into_corpus, read_corpus_from_elf): Adjust. * include/abg-fwd.h: Include abg-interned-str.h (get_type_name, get_function_type_name, get_method_type_name): Return a interned_string, rather than a std::string. * include/abg-interned-str.h: New declarations for interned strings and their pool. * include/abg-ir.h (environment::intern): Declare new method. (elf_symbol::{g,s}et_environment): Likewise. (type_or_decl_base::type_or_decl_base): Make the default constructor private. ({translation, type_or_decl_base}::set_environment) (set_environment_for_artifact): Take a const environment*. (elf_symbol::elf_symbol) (elf_symbol::create) (type_or_decl_base::type_or_decl_base) (translation::translation, decl_base::decl_base) (scope_decl::scope_decl, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator) (function_type::function_type, method_type::method_type) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl, class_decl::class_decl): Take an environment. (type_or_decl_base::operator=) (enum_type_decl::enumerator::get_environment): Declare new method. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_qualified_name, get_name, get_qualified_parent_name, get_linkage_name}, qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::{get_name, get_qualified_name}) ({var,function}_decl::get_id) (function_decl::parameter::{get_type_name, get_name_id}): Return an interned_string, rather than a std::string. (decl_base::{set_qualified_name, set_temporary_qualified_name, get_qualified_name, set_linkage_name}) (qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string, rather than a std::string. (class_decl::member_{class,function}_template::member_{class,function}_template): Adjust. * src/abg-ir.cc (environment_setter::env_): Make this be a pointer to const environment. (environment_setter::visit_begin): Adjust. (interned_string_pool::priv): Define new type. (interned_string_pool::*): Define the method declared in abg-interned-str. h. (operator==, operator!=, operator+): Define operator for interned_string and std::string (operator<<): Define for interned_string. (translation_unit::priv::env_): Make this be a pointer to const environment. (translation_unit::priv::priv): Take a pointer to const environment. (elf_symbol::priv::env_): New data member. (elf_symbol::priv::priv): Adjust. Make an overoad take an environment. (translation_unit::{g,s}et_environment): Adjust. (interned_string_bool_map_type): New typedef. (environment::priv::classes_being_compared_): Make this hastable of string be a hashtable of interned_string. (environment::priv::string_pool_): New data member. (environment::{get_void_type_decl, get_variadic_parameter_type_decl}): Adjust. (type_or_decl_base::priv::env_): Make this be a pointer to const environment. (type_or_decl::base::priv::priv): Adjust. (type_or_decl_base::set_environment) (set_environment_for_artifact): Take a pointer to const environment. (elf_symbol::{g,s}et_environment, environment::intern) (type_or_decl_base::operator=): Define new methods. (decl_base::priv::{name_, qualified_parent_name_, temporary_qualified_name_, qualified_name_, linkage_name_}): Make these data member be of tpe interned_string. (decl_base::priv::priv): Make this take an environment. Adjust. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_linkage_name, get_qualified_parent_name, get_name, get_qualified_name}, get_type_name, get_function_type_name) (get_method_type_name, get_node_name) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::get_qualified_name) (var_decl::get_id, function_decl::get_id) (function_decl::parameter::get_{name_id, type_name}): Return an interned_string. (decl_base::{set_qualified_name, set_temporary_qualified_name}) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string. (decl_base::{set_name, set_linkage_name}): Intern the std::string passed in parameter. (equals): In the overload for decl_base, adjust for a little speed optimization that is justified by profiling. (pointer_type_def::priv::{internal_qualified_name_, temp_internal_qualified_name_}): Make these data member be interned_string. (enum_type_decl::enumerator::priv::env_): New data member. (enum_type_decl::enumerator::priv::{name_, qualified_name}): Make these data member be of type interned_string. (enum_type_decl::enumerator::get_environment): New method. (enum_type_decl::enumerator::priv::priv) Adjust. (typedef_decl::operator==): Implement a little speed optimization. (var_decl::priv::nake_type_): New data member. (var_decl::priv::id_): Make this data member be of type interned_string. (equals): In the overload for var_decl, function_type, function_decl, adjust for the use of interned_string. (function_decl::priv::id_): Make this be of type interned_string. (scope_decl::{add_member_decl, insert_member_decl}) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit, lookup_node_in_scope) (lookup_type_in_scope, scope_decl::scope_decl) (qualified_type_def::qualified_type_def) (qualified_type_def::get_qualified_name) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def) (array_type_def::array_type_def, array_type_def::append_subrange) (array_type_def::get_qualified_name) (enum_type_decl::enum_type_decl) (enum_type_decl::enumerator::get_qualified_name) (enum_type_decl::enumerator::set_name) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter) (class_decl::priv::comparison_started) (class_decl::add_base_specifier) (class_decl::base_spec::base_spec) (class_decl::method_decl::method_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, class_tdecl::class_tdecl) (qualified_name_setter::do_update): Adjust. (translation_unit::translation_unit, elf_symbol::elf_symbol) (elf_symbol::create, type_or_decl_base::type_or_decl_base) (decl_base::decl_base, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator, class_decl::class_decl) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Take an environment. * src/abg-comparison.cc (function_suppression::suppresses_function): Adjust. * src/abg-reader.cc (read_translation_unit) (read_corpus_from_input, build_namespace_decl, build_elf_symbol) (build_function_parameter, build_function_decl, build_type_decl) (build_function_type, build_enum_type_decl, build_enum_type_decl) (build_class_decl, build_function_tdecl, build_class_tdecl) (read_corpus_from_native_xml): Likewise. * src/abg-writer.cc (id_manager::m_cur_id): Make this mutable. (id_manager::m_env): New data member. (id_manager::id_manager): Adjust. (id_manager::get_environment): New method. (id_manager::{get_id, get_id_with_prefix}): Return an interned_string. (type_ptr_map): Make this be a hash map of type_base* -> interned_string, rather a type_base* -> string. (write_context::m_env): New data member. (write_context::m_type_id_map): Make this data member be mutable. (write_context::m_emitted_type_id_map): Make this be a hash map of interned_string -> bool, rather than string -> bool. (write_context::write_context): Take an environment and adjust. (write_context::get_environment): New method. (write_context::get_id_manager): New const overload. (write_context::get_id_for_type): Return an interned_string; adjust. (write_context::{record_type_id_as_emitted, record_type_as_referenced}): Adjust. (write_context::type_id_is_emitted): Take an interned_string. (write_context::{type_is_emitted, record_decl_only_type_as_emitted}): Adjust. (write_translation_unit, write_corpus_to_native_xml, dump): Adjust. * tools/abisym.cc (main): Adjust. * tests/data/test-read-write/test22.xml: Adjust. * tests/data/test-read-write/test23.xml: Adjust. * tests/data/test-read-write/test26.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-24 06:44:29 +00:00
#include "abg-interned-str.h"
#include "abg-hash.h"
/// Toplevel namespace for libabigail.
namespace abigail
{
/**
@mainpage libabigail
This is the API documentation of the Application Binary
Interface Generic Analysis and Instrumentation Library, aka,
<em>libabigail</em>.
Check out <a href="http://sourceware.org/libabigail"> the project
homepage</a>!
The current libabigail source code can be browsed at
http://sourceware.org/git/gitweb.cgi?p=libabigail.git
It can be checked out with:
<em>git clone git://sourceware.org/git/libabigail.git</em>
The mailing list to send messages and patches to is
libabigail@sourceware.org.
You can hang out with libabigail developers and users on irc at
irc://irc.oftc.net\#libabigail.
*/
// Inject some types.
Add compatibility layer for C++11 mode Introduce a compatibility layer for C++11 code by adding include/abg-cxx-compat.h. abg-cxx-compat defines a new namespace abg_compat and defines abg_compat::hash abg_compat::shared_ptr abg_compat::weak_ptr abg_compat::dynamic_pointer_cast abg_compat::static_pointer_cast abg_compat::unordered_map abg_compat::unordered_set based on definitions from std::tr1 (std=gnu++98) or std:: (std=gnu++11). I decided for introducing abg_compat:: rather than polluting abigail:: to allow an easier transition to C++11 at a later time and to not subtly break existing code. As the shared_ptr in C++11 defines shared_ptr::operator bool() explicit, some locations where a shared_ptr is assigned to boolean, needed to be adjusted to explicitly cast to bool. * include/abg-cxx-compat.h: new file introducing the abg_compat namespace to provide C++11 functionality from either std::tr1 or std:: * include/Makefile.am: Add the new abg-cxx-compat.h to source distribution. * include/abg-comparison.h: replace std::tr1 usage by abg_compat and adjust includes accordingly: likewise * include/abg-diff-utils.h: likewise * include/abg-fwd.h: likewise * include/abg-ini.h: likewise * include/abg-interned-str.h: likewise * include/abg-ir.h: likewise * include/abg-libxml-utils.h: likewise * include/abg-libzip-utils.h: likewise * include/abg-reporter.h: likewise * include/abg-sptr-utils.h: likewise * include/abg-suppression.h: likewise * include/abg-tools-utils.h: likewise * include/abg-workers.h: likewise * src/abg-comp-filter.cc: likewise * src/abg-comparison-priv.h: likewise * src/abg-corpus.cc: likewise * src/abg-dwarf-reader.cc: likewise * src/abg-hash.cc: likewise * src/abg-ir.cc: likewise * src/abg-reader.cc: likewise * src/abg-suppression.cc: likewise * src/abg-tools-utils.cc: likewise * src/abg-writer.cc: likewise * tests/test-diff-filter.cc: likewise * tests/test-diff-pkg.cc: likewise * tests/test-read-dwarf.cc: likewise * tests/test-read-write.cc: likewise * tests/test-types-stability.cc: likewise * tests/test-write-read-archive.cc: likewise * tools/abicompat.cc: likewise * tools/abidiff.cc: likewise * tools/abidw.cc: likewise * tools/abilint.cc: likewise * tools/abipkgdiff.cc: likewise Signed-off-by: Matthias Maennich <maennich@google.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-05 11:00:23 +00:00
using abg_compat::shared_ptr;
using abg_compat::weak_ptr;
using abg_compat::unordered_map;
using std::string;
Support reading namespaces * include/abg-fwd.h (get_global_scope): Return a const global_scope. Add a new overload that takes a naked pointer as parm. (insert_decl_into_scope, get_top_most_scope_under): Declare new entry points. * include/abg-ir.h (class decl_base, class scope_decl): Add insert_decl_into_scope as a friend of these classes. (scope_decl::{insert_decl_into_scope, find_iterator_for_member}): Declare new member. (scope_decl::get_member_decls): New non-const overload. * src/abg-dwarf-reader.cc (build_translation_unit): Remove the "recurse" parameter. Adjust the call to build_ir_node_from_die to read just public decls that are at namespace scope. Anything else should be dropped unless it's needed to emitting the public namespace-level decls. (build_namespace_decl_and_add_to_ir) (canonicalize_and_insert_type_into_ir): Define new static functions. (build_corpus): Adjust ad build_translation_unit doesn't have the "recurse" parameter anymore. (canonicalize_and_add_type_to_ir): Make this static. Fix comments. (build_ir_node_from_die): Take a new "only_public_decl" parameter. For DW_TAG_base_type case, use the new canonicalize_and_insert_type_into_ir to insert the type at the right place in the global scope making sure it is seen before the current scope. For pointer, references and qualified types, use canonicalize_and_insert_type_into_ir to add the type at the same scope as its underlying type. Handle DW_TAG_{namespace,module} using the new build_namespace_decl_and_add_to_ir function. Add some vertical spaces and some assertions. * src/abg-ir.cc (scope_decl::add_member_decl): Use scope_decl_sptr typedef. (scope_decl::{insert_member_decl,find_iterator_for_member}): Define new methods. (insert_decl_into_scope, get_top_most_scope_under): Define new functions. (get_global_scope): Constify the return type. (get_translation_unit): Adjust as get_global_scope now returns a const. * src/abg-reader.cc (get_translation_unit): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2013-12-12 14:40:52 +00:00
using std::vector;
// Pull in relational operators.
using namespace std::rel_ops;
namespace ir
{
// Forward declarations for corpus.
class corpus;
Create a Corpus Group API extension To support the upcomping analysis of the Linux kernel and its modules, we need a way to represent a union of corpora. The first corpus loaded would be the one representing the vmlinux binary. Subsequent corpora loaded would be those representing the modules. This patch provides the new abigail::ir::corpus_group type that represents such a corpus group. * include/abg-corpus.h (corpus::{find_translation_unit, get_type_per_loc_map}): Declare new member functions. (corpus::{get_architecture_name, is_empty}): Make these member functions const. (corpus::{get_sorted_fun_symbols, get_functions, get_variables, get_unreferenced_function_symbols, get_unreferenced_variable_symbols}): Make these member functions virtual. (class corpus_group): Declare a new type. * include/abg-fwd.h (corpus_sptr, corpus_group_sptr) (string_tu_map_type, istring_var_decl_ptr_map_type) (istring_function_decl_ptr_map_type): Define new typedefs. * src/abg-corpus-priv.h (corpus_priv::{path_tu_map, type_per_loc_map_}): Add new data members. * src/abg-corpus.cc (corpus_add): Complete the function comment. Assert that at most one translation unit of a given path can be added to the corpus. (corpus::{find_translation_unit, get_type_per_loc_map}): Define new member functions. (corpus::{get_architecture_name}): Make this member function const. (struct corpus_group::priv): Define new type. (corpus_group::{corpus_group, ~corpus_group, add_corpus, get_corpora, is_empty, get_functions, get_variables, get_var_symbol_map, get_fun_symbol_map, get_sorted_fun_symbols, get_sorted_var_symbols, get_unreferenced_function_symbols, get_unreferenced_variable_symbols}): Define member functions of the new corpus_group type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-30 10:51:32 +00:00
typedef shared_ptr<corpus> corpus_sptr;
class corpus_group;
typedef shared_ptr<corpus_group> corpus_group_sptr;
// Forward declarations for ir.
class ir_node_visitor;
struct ir_traversable_base;
/// Convenience typedef for a shared pointer to @ref
/// ir_traversable_base.
typedef shared_ptr<ir_traversable_base> ir_traversable_base_sptr;
Introduce the concept of environment There are resources needed by the type system and other artifacts of libabigail. Today, when the life time of those resources need to be greater than all of artifacts of Abigail, then said resources are made global. But then global resources are not great, if anything because they complicate the future use of the library in concurrent computing setups. As I was in the need to add one resource to be used by the type system, I decided to sit down and first overhaul how these long lived resources needed to be handled. And here comes the concept of "environment". An environment is a place where one can put resources that need to live longer than all the other artifacts of the Abigail system. And so, the code that creates Abigail artifacts needs and environment of for said artifacts to use. In other words, artifacts now use an environment. This has interesting and strong implications. We can only compare two artifacts if they use the same environment. This is quite a strong requirement. But then when this requirement is fulfilled, comparing two types amounts to just comparing two pointer values; hash values for types can also be cached. Now *that* is great for speed of comparison, is it not? This patch introduce the concept environment (which is basically a new abigail::ir::environment type), removes the global variables and uses the environment instead. Each ABI artifact (either type or decl) now has a ::get_environment() member function to get its environment. This patch also disables the caching of hash values because the caching must happen only *after* all types have been canonicalized. We were not respecting that requirement until now, and that introduces wrong hash values. A subsequent patch is going to re-introduce hash value caching again, once the infrastructure is in place to set a flag in the environment (hah!) once type canonicalization is done, and then later read that flag when some client code requests a hash value, to know if we should look in the hash value cache or not. The patch obviously changes the output of numerous regression tests (if anything b/c it disables hash value caching) so 'make check' yields regressions. But then, it's only the subsequent patch that updates the tests. * include/abg-ir.h: Adjust note about memory management. (class environment): Declare new class. (translation_unit::translation_unit): Take an environment in parameter. (translation_unit::{g,s}et_environment): Declare new member functions. (type_or_decl_base::{g,s}et_environment): Likewise. (type_or_decl_base::{get_cached_hash_value, set_cached_hash_value}): Change the name of decl_base::peek_hash_value() and decl_base::set_hash() here into these and move them here. (type_or_decl_base::hashing_started): Move decl_base::hashing_started() here. ({g,s}et_environment_for_artifact): Declare new functions. (class decl_base): Move member functions hashing_started(), peek_hash_value() and set_hash() on to the type_or_decl_base base class. (scope_decl::scope_decl): Initialize the virtual member type_or_decl_base(). (type_decl::{get_void_type_decl, get_variadic_parameter_type_decl}): Remove these static member functions. They are now non-static member functions of the new environment type. * src/abg-ir.cc (class environment_setter): New internal class. (get_canonical_types_map): Remove. This now becomes a member function of the environment type. (class usage_watchdog): Remove. (usage_watchdog_{s,w}ptr): Remove these typedefs. (get_usage_watchdog_wptr, ref_usage_watchdog) (maybe_cleanup_type_system_data): Remove these functions. (translation_unit::priv::usage_watchdog_): Remove data member. (translation_unit::priv::env_): New data member. (translation_unit::priv::priv): Take an environment and initialize the new env_ data member. Do not initialize the removed usage_watchdog_. (translation_unit::translation_unit): Take an environment parameter. (translation_unit::get_global_scope): Set the environment of a new global scope. (translation_unit::{g,s}et_environment): New accessors. (translation_unit::bind_function_type_life_time): Set the environment of the function type. (struct environment::priv): New class. (environment::{environment, ~environment, get_canonical_types_map, get_variadic_parameter_type_decl, canonicalization_is_done}): New member functions. (struct type_or_decl_base::priv): New class. (type_or_decl_base::{type_or_decl_base, hashing_started, get_cached_hash_value, set_cached_hash_value, set_environment, get_environment, traverse}): New member functions. ({s,g}get_environment_for_artifact): New functions. (decl_base::priv::{hash_, hashing_started}): Remove. (decl_base::priv::priv): Adjust. (decl_base::decl_base): In the copy constructor, initialize the virtual base type_or_decl_base. Do not initialize hash_ and hashing_started data member that got removed. (decl_base::{hashing_started, peek_hash_value, set_hash}): Remove member functions. (strip_typedef): Set the environment of the new type which has its typedefs stripped off. Adjust the call to type_or_void(). (scope_decl::{add, insert}_member_decl): Set the environment of the new member decl to the environment of its scope. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Set the environment for the newly synthesized type. Adjust calls to type_or_void(). (type_or_void): Take an environment in parameter. Get the void type from the environment. (get_canonical_types_map): Remove. (type_base::get_canonical_type_for): Get the canonical types map from the environment, not from a global variable. (type_decl::{get_void_type_decl, get_variadic_parameter_type_decl}): Remove. (pointer_type_def::pointer_type_def): Adjust call to type_or_void. (reference_type_def::reference_type_def): Likewise. (function_decl::parameter::get_pretty_representation): Get the variadic parameter type decl from the environment. (class_decl::priv::classes_being_compared_): Remove static data member. (class_decl::priv::{mark_as_being_compared, unmark_as_being_compared, comparison_started): Use the "classes being compared" map from the environment. (class_decl::base_spec::get_hash): Adjust. (keep_type_alive): Get the alive types array from the environment) not from a global variable anymore. (get_next_string): Put the counter in thread-local storage. * src/abg-hash.cc (scope_decl::hash::operator()) (function_decl::hash::operator()): Do not handle caching (here). * include/abg-corpus.h (corpus::{g,s}et_environment): Declare new accessors. * src/abg-corpus.cc (corpus::priv::env): New data member. (corpus::priv::priv): Initialize it. (corpus::corpus): Take an environment in parameter. (corpus::{g,s}et_environment): Define new member functions (corpus::add): Set the environment of the newly added translation unit, if it's not set already set. In any case, assert that the translation unit must use the same environment as the corpus. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take an environment parameter. ({s,g}et_debug_info_root_path, {s,g}et_environment): Declare new functions. * src/abg-dwarf-reader.cc (read_context::{env_, offline_callbacks_}): New data members. (read_context::read_context): Initialize them. (read_context::clear_per_translation_unit_data): Do not touch the void type declaration, it doesn't belong to the translation unit. (read_context::{env, offline_callbacks}): New accessors. (read_context::{create_default_dwfl}): New member function. (read_context::dwfl_handle): Add a setter overload. ({s,g}et_debug_info_root_path): Define new accessors. (create_default_dwfl, create_dwfl_sptr, create_default_dwfl_sptr): Remove these. (build_translation_unit_and_add_to_ir): Adjust to pass the environment to the newly created translation unit. (build_function_decl): Adjust to pass the environment to the created function and parameter types. Get variadic parameter type node from the current environment, not from a global variable. And do not try to canonicalize function types here. (read_debug_info_into_corpus): Set the environment of the newly created corpus. (build_ir_node_for_void_type): Get the void type node from the current environment, rather than from a global variable. (create_read_context): Take the environment in parameter. Create the default dwarf front end library handle using the new member function of the read context. Set the current environment used by the reader. (read_corpus_from_elf): Take an environment in parameter. Overhaul. This is now simpler. (has_alt_debug_info): Adjust the call to create_read_context() to make it pass an empty environment. * include/abg-fwd.h (class environment): Forward declare. * include/abg-reader.h (read_translation_unit_from_file) (read_translation_unit_from_buffer) (read_translation_unit_from_istream) (read_corpus_from_native_xml): Take an environment in parameter. * src/abg-reader.cc (read_context::m_env): New data member. (read_context::read_context): Initialize it. (read_context::{get_environment, set_environment}): New data member. (read_translation_unit): Set environment of the new translation unit. (read_corpus_from_input): Set the environment of the new corpus. (read_translation_unit_from_file) (read_translation_unit_from_buffer) (read_translation_unit_from_istream, read_corpus_from_native_xml): Take an environment in parameter. (build_function_parameter): Get variadic parameter type from the environment. * src/abg-comparison.cc (compute_diff): Add asserts in all the overloads to ensure that the artifact being compared come from the same environment. * tests/print-diff-tree.cc (main): Create an env for the ABI artifacts to use. * tests/test-abidiff.cc (main): Likewise. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-ir-walker.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/test-read-write.cc (main): Likewise. * tools/abicompat.cc (main): Likewise. * tools/abidiff.cc (main): Likewise. * tools/abidw.cc (main): Likewise. * tools/abilint.cc (main): Likewise. * tools/abipkgdiff.cc (main): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-07 20:27:50 +00:00
class environment;
/// Convenience typedef for a shared pointer to an @ref environment
typedef shared_ptr<environment> environment_sptr;
class location;
class location_manager;
class type_or_decl_base;
/// A convenience typedef for a shared_ptr to @ref type_or_decl_base.
typedef shared_ptr<type_or_decl_base> type_or_decl_base_sptr;
class type_base;
// Convenience typedef for a shared pointer on a @ref type_base
typedef shared_ptr<type_base> type_base_sptr;
/// Convenience typedef for a weak pointer on a @ref type_base
typedef weak_ptr<type_base> type_base_wptr;
/// Convenience typedef for a weak pointer to a @ref corpus.
typedef weak_ptr<corpus> corpus_wptr;
class translation_unit;
/// Convenience typedef for a shared pointer on a @ref
/// translation_unit type.
typedef shared_ptr<translation_unit> translation_unit_sptr;
/// Convenience typedef for a vector of @ref translation_unit_sptr.
typedef std::vector<translation_unit_sptr> translation_units;
Create a Corpus Group API extension To support the upcomping analysis of the Linux kernel and its modules, we need a way to represent a union of corpora. The first corpus loaded would be the one representing the vmlinux binary. Subsequent corpora loaded would be those representing the modules. This patch provides the new abigail::ir::corpus_group type that represents such a corpus group. * include/abg-corpus.h (corpus::{find_translation_unit, get_type_per_loc_map}): Declare new member functions. (corpus::{get_architecture_name, is_empty}): Make these member functions const. (corpus::{get_sorted_fun_symbols, get_functions, get_variables, get_unreferenced_function_symbols, get_unreferenced_variable_symbols}): Make these member functions virtual. (class corpus_group): Declare a new type. * include/abg-fwd.h (corpus_sptr, corpus_group_sptr) (string_tu_map_type, istring_var_decl_ptr_map_type) (istring_function_decl_ptr_map_type): Define new typedefs. * src/abg-corpus-priv.h (corpus_priv::{path_tu_map, type_per_loc_map_}): Add new data members. * src/abg-corpus.cc (corpus_add): Complete the function comment. Assert that at most one translation unit of a given path can be added to the corpus. (corpus::{find_translation_unit, get_type_per_loc_map}): Define new member functions. (corpus::{get_architecture_name}): Make this member function const. (struct corpus_group::priv): Define new type. (corpus_group::{corpus_group, ~corpus_group, add_corpus, get_corpora, is_empty, get_functions, get_variables, get_var_symbol_map, get_fun_symbol_map, get_sorted_fun_symbols, get_sorted_var_symbols, get_unreferenced_function_symbols, get_unreferenced_variable_symbols}): Define member functions of the new corpus_group type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-30 10:51:32 +00:00
/// Convenience typedef for a map that associates a string to a
/// translation unit.
typedef unordered_map<string, translation_unit_sptr> string_tu_map_type;
Allow selective resolution of class declaration 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>
2017-05-17 08:19:30 +00:00
/// A convenience typedef for a vector of type_base_wptr.
typedef vector<type_base_wptr> type_base_wptrs_type;
/// A convenience typedef for a map which key is an interned_string
/// and which value is a vector of type_base_wptr.
typedef unordered_map<interned_string,
type_base_wptrs_type,
hash_interned_string> istring_type_base_wptrs_map_type;
class decl_base;
// Convenience typedef for a smart pointer on @ref decl_base.
typedef shared_ptr<decl_base> decl_base_sptr;
class type_decl;
/// Convenience typedef for a shared pointer on a @ref type_decl.
typedef shared_ptr<type_decl> type_decl_sptr;
class typedef_decl;
/// Convenience typedef for a shared pointer on a @ref typedef_decl.
typedef shared_ptr<typedef_decl> typedef_decl_sptr;
/// Convenience typedef for a weak pointer on a @ref typedef_decl.
typedef weak_ptr<typedef_decl> typedef_decl_wptr;
class enum_type_decl;
/// Convenience typedef for shared pointer on enum_type_decl.
typedef shared_ptr<enum_type_decl> enum_type_decl_sptr;
Support union types This patch makes Libabigail understand C and C++ union types. It defines a new class abigail::ir::union_decl to represent the declaration of a union type. It also defines a new type abigail::comparison::union_diff to represent the changes between two union types. The patch then adds facilities to read union types from DWARF and abixml and also to write union types into the abixml format. As union types and class types have a lot in common, the patch tries very hard to share code between the abigail::ir::class_decl and abigail::ir::union_decl. To do so, a new class abigail::ir::class_or_union is created. It's the base class for both abigai::ir::class_decl and abigail::ir::union_decl. Its data members and methods represent the set of data and behaviour that are common to classes and unions. A lot of code and data that were initially in abigail::ir::class_decl got moved into the new abigail::ir::class_or_union class. Similary, the patch creates a new class abigail::comparison::class_or_union_diff that is a base class for both the existing class abigail::comparison::class_diff and the newly created class abigail::comparison::union_diff. The new class abigail::comparison::class_or_union_diff contains data and behaviour that are common to both union_diff and class_diff and that were previously in class_diff. The rest of the patch is mostly adjustment so that code that was supposed to work with class class_decl only can now work with class class_or_union when it makes sense. Similarly for class_diff and class_or_union_diff. The patch adds regression tests into the test suite and adjust many existing tests involving binaries that contain union types; the reference output of those tests now take union types into account. * include/abg-fwd.h (class_or_union, union_decl): Forward-declare new types. (is_class_or_union_type, is_union_type): Declare new functions. * include/abg-ir.h (method_type::class_type_): Make this be of class_or_union_wptr type. (method_type::method_type): Make the class_type parameter be of class_or_union_wptr type. (method_type::{g,s}et_class_type): Take or return a class_or_union_sptr. (member_base, method_decl, member_function_template) (member_class_template, member_base::hash) (member_function_template::hash, member_class_template::hash): Take these class types out of the class_decl scope. (is_method_decl): Adjust. (operator==, opertor!=): Adjust overloads for member_function_template_sptr and member_class_template_sptr. (class class_or_union): Declare new type. (class class_decl): Make this class inherit class_or_union class. (class_decl::{add_member_decl, insert_member_decl, remove_member_decl, set_size_in_bits, get_size_in_bits, get_alignment_in_bits, set_alignment_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, insert_member_type, add_member_type, remove_member_type, get_member_type, find_member_type, add_data_member, get_data_members, find_data_member, get_non_static_data_members, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates): Move these to the parent class class_or_union. (copy_member_function, equals): Add overloads for class_or_union. (struct class_or_union::hash): Declare new type. (class union_decl): Declare new type. (equals, copy_member_function): New overloads for class union_decl type. (ir_node_visitor::visit): Add new overloads for union_decl* and class_or_union*. * src/abg-ir.cc (get_member_function_is_ctor) (set_member_function_is_ctor, get_member_function_is_dtor) (set_member_function_is_dtor, get_member_function_is_const) (set_member_function_is_const, get_member_function_vtable_offset) (set_member_function_vtable_offset) (get_member_function_is_virtual, set_member_function_is_virtual) (maybe_update_types_lookup_map, get_location) (get_method_type_name, is_at_global_scope, is_at_class_scope): Adjust. (is_class_or_union_type, is_union_type): Define new functions. (type_base::get_canonical_type_for, maybe_adjust_canonical_type) (method_type::method_type, method_type::set_class_type) (function_decl::get_pretty_representation) (function_decl::get_first_non_implicit_parm) (function_decl::clone): Adjust. (equals): Adjust the overload for function_type. (struct class_or_union::priv): Define new type. (class::priv::{declaration_, definition_of_declaration_, member_types_, data_members_, non_static_data_members_, member_functions_, mem_fns_map_, member_function_templates_, member_class_templates_, is_declaration_only_}): Move these data member into class_or_union::priv. (class_priv::{mark_as_being_compared, unmark_as_being_compared, comparison_started}): Moved these member functions to class_or_union::priv. (class_or_union::{class_or_union, traverse, ~class_or_union, add_member_decl, remove_member_decl, insert_member_type, add_member_type, get_size_in_bits, remove_member_type, get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, get_member_types, find_member_type, add_data_member, get_data_member, find_data_member, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates, has_no_member, insert_member_decl, operator==}): Define new member functions. (class_decl::{add_member_decl, remove_member_decl, insert_member_type, add_member_type, get_size_in_bits, remove_member_type, get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, get_member_types, find_member_type, add_data_member, get_data_member, find_data_member, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates): Move these member functions into class_or_union. (class_decl::{class_decl, get_definition_of_declaration, insert_member_decl, add_member_function, has_no_base_nor_member}): Adjust. (equals, copy_member_function): Define new overloads for class_or_union. (equals): Adjust the overload for class_decl. (method_decl::{method_decl, set_linkage_name, ~method_decl, get_type, set_scope}): Remove from the class_decl scope. (member_base::operator==, member_function_template::operator==): Likewise. (member_function_template::traverse) (member_class_template::operator==) (member_class_template::traverse): Likewise. (operator==, operator!=): Adjust the overlod for member_function_template_sptr. (is_method_decl, fixup_virtual_member_function) (set_member_is_static): Adjust. (virtual_member_function_less_than::operator()): Likewise. (union_decl::{union_decl, get_pretty_representation, operator==, traverse}): Define new member functions. (equals, copy_member_function): Define new overloads for union_decl. (hash_type_or_decl): Adjust. (ir_node_visitor::visit_{begin, end}): Adjust. Add new overloads for class_or_union* and union_decl*. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust these typedefs. (class class_or_union_diff): Declare new type. (class_diff): Adjust to make this inherit the new class_or_union_diff type. (class_diff::{get_priv, member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes}): These member functions got moved into -- and shared with -- class_or_union_diff class. (class union_diff): Declare new type. (typedef union_diff_sptr): New typedef. (compute_diff): New overload for union_diff (is_class_diff, is_union_diff): Declare new functions. * src/abg-comparison.cc (is_class_diff, is_union_diff): Define new functions. (compute_diff_for_types): Support union_decl. (represent): Adjust. (represent_data_member): Do not show offset information for data members of unions as all union data members are at offset 0. (struct class_or_union_diff::priv): New type. (class_or_union_diff::priv::{member_type_has_changed, subtype_changed_dm, member_class_tmpl_has_changed, get_deleted_non_static_data_members_number, get_inserted_non_static_data_members_number, count_filtered_subtype_changed_dm, count_filtered_changed_dm, count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns}): Define new member functions. (class_or_union_diff::{class_or_union_diff, finish_diff_type, lookup_tables_empty, lookup_tables_empty, ensure_lookup_tables_populated, allocate_priv_data, get_priv, ~class_or_union_diff, first_class_or_union, second_class_or_union, member_types_changes, member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fns_changes, changed_member_fns, member_fns_changes, inserted_member_fns, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes, member_class_tmpls_changes, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new member functions. (class_diff::priv::{member_types_changes_, data_members_changes, member_fn_tmpls_changes_, member_class_tmpls_changes_, deleted_member_types_, inserted_member_types_, changed_member_types_, sorted_changed_member_types_, deleted_data_members_, deleted_dm_by_offset_, inserted_data_members_, inserted_dm_by_offset_, subtype_changed_dm_, sorted_subtype_changed_dm_, changed_dm_, sorted_changed_dm_, deleted_member_functions_, inserted_member_functions_, changed_member_functions_, sorted_changed_member_functions_, deleted_member_class_tmpls_, inserted_member_class_tmpls_, changed_member_class_tmpls_, sorted_changed_member_class_tmpls_}): Move these data members into class_or_union_diff::priv. (class_diff::{clear_lookup_tables, lookup_tables_empty, ensure_lookup_tables_populate}): Adjust. (class_diff::allocate_priv_data): Define new function. (class_diff::priv::{count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns, chain_into_hierarchy, class_diff}): Likewise. (class_diff::{member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes}): These are deleted as they got moved to class_or_union_diff. (class_diff::report): Adjust. (union_diff::{clear_lookup_tables, lookup_tables_empty, ensure_lookup_tables_populated, allocate_priv_data, union_diff, finish_diff_type, first_union_decl, second_union_decl, get_pretty_representation, report}): Define new functions. (compute_diff): Define an overload for union_decl_sptr. (function_decl_diff::report): Adjust. (corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars): Adjust. (corpus_diff::report): Adjust. * src/abg-hash.cc (member_base::hash::operator) (member_function_template::hash::operator) (member_class_template::hash::operator): Move these out of the class_decl scope. (class_or_union::hash::operator): Define new member function. (class_decl::hash::operator): Adjust. (type_base::dynamic_hash::operator): Support hashing of union_decl. Adjust. * src/abg-suppression.cc (type_suppression::suppresses_diff): Adjust. * src/abg-dwarf-reader.cc (typedef die_class_or_union_map_type): Define new typedef. (read_context::{die_wip_classes_map_, alternate_die_wip_classes_map_, type_unit_die_wip_classes_map_): Make these data member have type die_class_or_union_map_type. (read_context::{lookup_type_from_die_offset, die_wip_classes_map, is_wip_class_die_offset, resolve_declaration_only_classes}): Adjust. (finish_member_function_reading, build_class_type_and_add_to_ir) (build_function_type, build_function_decl, build_reference_type) (type_is_suppressed, build_function_decl) (maybe_canonicalize_type, maybe_set_member_type_access_specifier): Adjust. (build_union_type_and_add_to_ir): Define new static function. (build_ir_node_from_die): Support DW_TAG_union_type DIE tag. * src/abg-reader.cc (handle_element_node): Handle union_decl. (build_function_decl, build_function_decl_if_not_suppressed): Adjust. (build_union_decl_if_not_suppressed, build_union_decl) (handle_union_decl): Define new functions. (build_class_decl): Adjust. * src/abg-writer.cc (record_decl_only_type_as_emitted): Adjust. (write_decl): Adjust. Support writting union_decl type. p (write_class_decl_opening_tag, write_class_decl): Adjust. Call the new write_class_or_union_is_declaration_only. (write_union_decl_opening_tag, write_union_decl): Define new static functions. (write_member_tpe): Support writting union decl. * tests/test-diff-dwarf.cc (in_out_specs): Add new tests for this union type support. * tests/data/test-diff-dwarf/libtest37-union-v0.so: New test input. * tests/data/test-diff-dwarf/libtest37-union-v1.so: Likewise. * tests/data/test-diff-dwarf/libtest38-union-v0.so: Likewise. * tests/data/test-diff-dwarf/libtest38-union-v1.so: Likewise. * tests/data/test-diff-dwarf/libtest39-union-v0.so: Likewise. * tests/data/test-diff-dwarf/libtest39-union-v1.so: Likewise. * tests/data/test-diff-dwarf/test37-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test38-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test39-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test37-union-v0.cc: Source code for new test input. * tests/data/test-diff-dwarf/test37-union-v1.cc: Likewise. * tests/data/test-diff-dwarf/test38-union-v0.cc: Likewise. * tests/data/test-diff-dwarf/test38-union-v1.cc: Likewise. * tests/data/test-diff-dwarf/test39-union-v0.cc: Likewise. * tests/data/test-diff-dwarf/test39-union-v1.cc: Likewise. * tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi: Update test reference. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-read-dwarf/libtest23.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-15 00:16:46 +00:00
class class_or_union;
typedef shared_ptr<class_or_union> class_or_union_sptr;
typedef weak_ptr<class_or_union> class_or_union_wptr;
class scope_type_decl;
class class_decl;
/// Convenience typedef for a shared pointer on a @ref class_decl
typedef shared_ptr<class_decl> class_decl_sptr;
/// Convenience typedef for a vector of @ref class_decl_sptr
typedef vector<class_decl_sptr> classes_type;
/// Convenience typedef for a weak pointer on a @ref class_decl.
typedef weak_ptr<class_decl> class_decl_wptr;
Support union types This patch makes Libabigail understand C and C++ union types. It defines a new class abigail::ir::union_decl to represent the declaration of a union type. It also defines a new type abigail::comparison::union_diff to represent the changes between two union types. The patch then adds facilities to read union types from DWARF and abixml and also to write union types into the abixml format. As union types and class types have a lot in common, the patch tries very hard to share code between the abigail::ir::class_decl and abigail::ir::union_decl. To do so, a new class abigail::ir::class_or_union is created. It's the base class for both abigai::ir::class_decl and abigail::ir::union_decl. Its data members and methods represent the set of data and behaviour that are common to classes and unions. A lot of code and data that were initially in abigail::ir::class_decl got moved into the new abigail::ir::class_or_union class. Similary, the patch creates a new class abigail::comparison::class_or_union_diff that is a base class for both the existing class abigail::comparison::class_diff and the newly created class abigail::comparison::union_diff. The new class abigail::comparison::class_or_union_diff contains data and behaviour that are common to both union_diff and class_diff and that were previously in class_diff. The rest of the patch is mostly adjustment so that code that was supposed to work with class class_decl only can now work with class class_or_union when it makes sense. Similarly for class_diff and class_or_union_diff. The patch adds regression tests into the test suite and adjust many existing tests involving binaries that contain union types; the reference output of those tests now take union types into account. * include/abg-fwd.h (class_or_union, union_decl): Forward-declare new types. (is_class_or_union_type, is_union_type): Declare new functions. * include/abg-ir.h (method_type::class_type_): Make this be of class_or_union_wptr type. (method_type::method_type): Make the class_type parameter be of class_or_union_wptr type. (method_type::{g,s}et_class_type): Take or return a class_or_union_sptr. (member_base, method_decl, member_function_template) (member_class_template, member_base::hash) (member_function_template::hash, member_class_template::hash): Take these class types out of the class_decl scope. (is_method_decl): Adjust. (operator==, opertor!=): Adjust overloads for member_function_template_sptr and member_class_template_sptr. (class class_or_union): Declare new type. (class class_decl): Make this class inherit class_or_union class. (class_decl::{add_member_decl, insert_member_decl, remove_member_decl, set_size_in_bits, get_size_in_bits, get_alignment_in_bits, set_alignment_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, insert_member_type, add_member_type, remove_member_type, get_member_type, find_member_type, add_data_member, get_data_members, find_data_member, get_non_static_data_members, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates): Move these to the parent class class_or_union. (copy_member_function, equals): Add overloads for class_or_union. (struct class_or_union::hash): Declare new type. (class union_decl): Declare new type. (equals, copy_member_function): New overloads for class union_decl type. (ir_node_visitor::visit): Add new overloads for union_decl* and class_or_union*. * src/abg-ir.cc (get_member_function_is_ctor) (set_member_function_is_ctor, get_member_function_is_dtor) (set_member_function_is_dtor, get_member_function_is_const) (set_member_function_is_const, get_member_function_vtable_offset) (set_member_function_vtable_offset) (get_member_function_is_virtual, set_member_function_is_virtual) (maybe_update_types_lookup_map, get_location) (get_method_type_name, is_at_global_scope, is_at_class_scope): Adjust. (is_class_or_union_type, is_union_type): Define new functions. (type_base::get_canonical_type_for, maybe_adjust_canonical_type) (method_type::method_type, method_type::set_class_type) (function_decl::get_pretty_representation) (function_decl::get_first_non_implicit_parm) (function_decl::clone): Adjust. (equals): Adjust the overload for function_type. (struct class_or_union::priv): Define new type. (class::priv::{declaration_, definition_of_declaration_, member_types_, data_members_, non_static_data_members_, member_functions_, mem_fns_map_, member_function_templates_, member_class_templates_, is_declaration_only_}): Move these data member into class_or_union::priv. (class_priv::{mark_as_being_compared, unmark_as_being_compared, comparison_started}): Moved these member functions to class_or_union::priv. (class_or_union::{class_or_union, traverse, ~class_or_union, add_member_decl, remove_member_decl, insert_member_type, add_member_type, get_size_in_bits, remove_member_type, get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, get_member_types, find_member_type, add_data_member, get_data_member, find_data_member, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates, has_no_member, insert_member_decl, operator==}): Define new member functions. (class_decl::{add_member_decl, remove_member_decl, insert_member_type, add_member_type, get_size_in_bits, remove_member_type, get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, get_member_types, find_member_type, add_data_member, get_data_member, find_data_member, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates): Move these member functions into class_or_union. (class_decl::{class_decl, get_definition_of_declaration, insert_member_decl, add_member_function, has_no_base_nor_member}): Adjust. (equals, copy_member_function): Define new overloads for class_or_union. (equals): Adjust the overload for class_decl. (method_decl::{method_decl, set_linkage_name, ~method_decl, get_type, set_scope}): Remove from the class_decl scope. (member_base::operator==, member_function_template::operator==): Likewise. (member_function_template::traverse) (member_class_template::operator==) (member_class_template::traverse): Likewise. (operator==, operator!=): Adjust the overlod for member_function_template_sptr. (is_method_decl, fixup_virtual_member_function) (set_member_is_static): Adjust. (virtual_member_function_less_than::operator()): Likewise. (union_decl::{union_decl, get_pretty_representation, operator==, traverse}): Define new member functions. (equals, copy_member_function): Define new overloads for union_decl. (hash_type_or_decl): Adjust. (ir_node_visitor::visit_{begin, end}): Adjust. Add new overloads for class_or_union* and union_decl*. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust these typedefs. (class class_or_union_diff): Declare new type. (class_diff): Adjust to make this inherit the new class_or_union_diff type. (class_diff::{get_priv, member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes}): These member functions got moved into -- and shared with -- class_or_union_diff class. (class union_diff): Declare new type. (typedef union_diff_sptr): New typedef. (compute_diff): New overload for union_diff (is_class_diff, is_union_diff): Declare new functions. * src/abg-comparison.cc (is_class_diff, is_union_diff): Define new functions. (compute_diff_for_types): Support union_decl. (represent): Adjust. (represent_data_member): Do not show offset information for data members of unions as all union data members are at offset 0. (struct class_or_union_diff::priv): New type. (class_or_union_diff::priv::{member_type_has_changed, subtype_changed_dm, member_class_tmpl_has_changed, get_deleted_non_static_data_members_number, get_inserted_non_static_data_members_number, count_filtered_subtype_changed_dm, count_filtered_changed_dm, count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns}): Define new member functions. (class_or_union_diff::{class_or_union_diff, finish_diff_type, lookup_tables_empty, lookup_tables_empty, ensure_lookup_tables_populated, allocate_priv_data, get_priv, ~class_or_union_diff, first_class_or_union, second_class_or_union, member_types_changes, member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fns_changes, changed_member_fns, member_fns_changes, inserted_member_fns, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes, member_class_tmpls_changes, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new member functions. (class_diff::priv::{member_types_changes_, data_members_changes, member_fn_tmpls_changes_, member_class_tmpls_changes_, deleted_member_types_, inserted_member_types_, changed_member_types_, sorted_changed_member_types_, deleted_data_members_, deleted_dm_by_offset_, inserted_data_members_, inserted_dm_by_offset_, subtype_changed_dm_, sorted_subtype_changed_dm_, changed_dm_, sorted_changed_dm_, deleted_member_functions_, inserted_member_functions_, changed_member_functions_, sorted_changed_member_functions_, deleted_member_class_tmpls_, inserted_member_class_tmpls_, changed_member_class_tmpls_, sorted_changed_member_class_tmpls_}): Move these data members into class_or_union_diff::priv. (class_diff::{clear_lookup_tables, lookup_tables_empty, ensure_lookup_tables_populate}): Adjust. (class_diff::allocate_priv_data): Define new function. (class_diff::priv::{count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns, chain_into_hierarchy, class_diff}): Likewise. (class_diff::{member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes}): These are deleted as they got moved to class_or_union_diff. (class_diff::report): Adjust. (union_diff::{clear_lookup_tables, lookup_tables_empty, ensure_lookup_tables_populated, allocate_priv_data, union_diff, finish_diff_type, first_union_decl, second_union_decl, get_pretty_representation, report}): Define new functions. (compute_diff): Define an overload for union_decl_sptr. (function_decl_diff::report): Adjust. (corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars): Adjust. (corpus_diff::report): Adjust. * src/abg-hash.cc (member_base::hash::operator) (member_function_template::hash::operator) (member_class_template::hash::operator): Move these out of the class_decl scope. (class_or_union::hash::operator): Define new member function. (class_decl::hash::operator): Adjust. (type_base::dynamic_hash::operator): Support hashing of union_decl. Adjust. * src/abg-suppression.cc (type_suppression::suppresses_diff): Adjust. * src/abg-dwarf-reader.cc (typedef die_class_or_union_map_type): Define new typedef. (read_context::{die_wip_classes_map_, alternate_die_wip_classes_map_, type_unit_die_wip_classes_map_): Make these data member have type die_class_or_union_map_type. (read_context::{lookup_type_from_die_offset, die_wip_classes_map, is_wip_class_die_offset, resolve_declaration_only_classes}): Adjust. (finish_member_function_reading, build_class_type_and_add_to_ir) (build_function_type, build_function_decl, build_reference_type) (type_is_suppressed, build_function_decl) (maybe_canonicalize_type, maybe_set_member_type_access_specifier): Adjust. (build_union_type_and_add_to_ir): Define new static function. (build_ir_node_from_die): Support DW_TAG_union_type DIE tag. * src/abg-reader.cc (handle_element_node): Handle union_decl. (build_function_decl, build_function_decl_if_not_suppressed): Adjust. (build_union_decl_if_not_suppressed, build_union_decl) (handle_union_decl): Define new functions. (build_class_decl): Adjust. * src/abg-writer.cc (record_decl_only_type_as_emitted): Adjust. (write_decl): Adjust. Support writting union_decl type. p (write_class_decl_opening_tag, write_class_decl): Adjust. Call the new write_class_or_union_is_declaration_only. (write_union_decl_opening_tag, write_union_decl): Define new static functions. (write_member_tpe): Support writting union decl. * tests/test-diff-dwarf.cc (in_out_specs): Add new tests for this union type support. * tests/data/test-diff-dwarf/libtest37-union-v0.so: New test input. * tests/data/test-diff-dwarf/libtest37-union-v1.so: Likewise. * tests/data/test-diff-dwarf/libtest38-union-v0.so: Likewise. * tests/data/test-diff-dwarf/libtest38-union-v1.so: Likewise. * tests/data/test-diff-dwarf/libtest39-union-v0.so: Likewise. * tests/data/test-diff-dwarf/libtest39-union-v1.so: Likewise. * tests/data/test-diff-dwarf/test37-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test38-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test39-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test37-union-v0.cc: Source code for new test input. * tests/data/test-diff-dwarf/test37-union-v1.cc: Likewise. * tests/data/test-diff-dwarf/test38-union-v0.cc: Likewise. * tests/data/test-diff-dwarf/test38-union-v1.cc: Likewise. * tests/data/test-diff-dwarf/test39-union-v0.cc: Likewise. * tests/data/test-diff-dwarf/test39-union-v1.cc: Likewise. * tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi: Update test reference. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-read-dwarf/libtest23.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-15 00:16:46 +00:00
class union_decl;
typedef shared_ptr<union_decl> union_decl_sptr;
class function_type;
/// Convenience typedef for a shared pointer on a @ref function_type
typedef shared_ptr<function_type> function_type_sptr;
/// Convenience typedef fo a vector of @ref function_type_sptr
typedef vector<function_type_sptr> function_types_type;
/// Convenience typedef for a weak pointer on a @ref function_type
typedef weak_ptr<function_type> function_type_wptr;
class method_type;
/// Convenience typedef for shared pointer to @ref method_type.
typedef shared_ptr<method_type> method_type_sptr;
class pointer_type_def;
/// Convenience typedef for a shared pointer on a @ref pointer_type_def
typedef shared_ptr<pointer_type_def> pointer_type_def_sptr;
class qualified_type_def;
typedef shared_ptr<qualified_type_def> qualified_type_def_sptr;
class reference_type_def;
/// Convenience typedef for a shared pointer on a @ref reference_type_def
typedef shared_ptr<reference_type_def> reference_type_def_sptr;
class array_type_def;
/// Convenience typedef for a shared pointer on a @ref array_type_def
typedef shared_ptr<array_type_def> array_type_def_sptr;
class subrange_type;
class dm_context_rel;
/// A convenience typedef for a shared pointer to dm_context_rel.
typedef shared_ptr<dm_context_rel> dm_context_rel_sptr;
class var_decl;
/// Convenience typedef for a shared pointer on a @ref var_decl
typedef shared_ptr<var_decl> var_decl_sptr;
Create a Corpus Group API extension To support the upcomping analysis of the Linux kernel and its modules, we need a way to represent a union of corpora. The first corpus loaded would be the one representing the vmlinux binary. Subsequent corpora loaded would be those representing the modules. This patch provides the new abigail::ir::corpus_group type that represents such a corpus group. * include/abg-corpus.h (corpus::{find_translation_unit, get_type_per_loc_map}): Declare new member functions. (corpus::{get_architecture_name, is_empty}): Make these member functions const. (corpus::{get_sorted_fun_symbols, get_functions, get_variables, get_unreferenced_function_symbols, get_unreferenced_variable_symbols}): Make these member functions virtual. (class corpus_group): Declare a new type. * include/abg-fwd.h (corpus_sptr, corpus_group_sptr) (string_tu_map_type, istring_var_decl_ptr_map_type) (istring_function_decl_ptr_map_type): Define new typedefs. * src/abg-corpus-priv.h (corpus_priv::{path_tu_map, type_per_loc_map_}): Add new data members. * src/abg-corpus.cc (corpus_add): Complete the function comment. Assert that at most one translation unit of a given path can be added to the corpus. (corpus::{find_translation_unit, get_type_per_loc_map}): Define new member functions. (corpus::{get_architecture_name}): Make this member function const. (struct corpus_group::priv): Define new type. (corpus_group::{corpus_group, ~corpus_group, add_corpus, get_corpora, is_empty, get_functions, get_variables, get_var_symbol_map, get_fun_symbol_map, get_sorted_fun_symbols, get_sorted_var_symbols, get_unreferenced_function_symbols, get_unreferenced_variable_symbols}): Define member functions of the new corpus_group type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-30 10:51:32 +00:00
typedef unordered_map<interned_string,
var_decl*,
hash_interned_string> istring_var_decl_ptr_map_type;
class scope_decl;
/// Convenience typedef for a shared pointer on a @ref scope_decl.
typedef shared_ptr<scope_decl> scope_decl_sptr;
class function_decl;
/// Convenience typedef for a shared pointer on a @ref function_decl
typedef shared_ptr<function_decl> function_decl_sptr;
Create a Corpus Group API extension To support the upcomping analysis of the Linux kernel and its modules, we need a way to represent a union of corpora. The first corpus loaded would be the one representing the vmlinux binary. Subsequent corpora loaded would be those representing the modules. This patch provides the new abigail::ir::corpus_group type that represents such a corpus group. * include/abg-corpus.h (corpus::{find_translation_unit, get_type_per_loc_map}): Declare new member functions. (corpus::{get_architecture_name, is_empty}): Make these member functions const. (corpus::{get_sorted_fun_symbols, get_functions, get_variables, get_unreferenced_function_symbols, get_unreferenced_variable_symbols}): Make these member functions virtual. (class corpus_group): Declare a new type. * include/abg-fwd.h (corpus_sptr, corpus_group_sptr) (string_tu_map_type, istring_var_decl_ptr_map_type) (istring_function_decl_ptr_map_type): Define new typedefs. * src/abg-corpus-priv.h (corpus_priv::{path_tu_map, type_per_loc_map_}): Add new data members. * src/abg-corpus.cc (corpus_add): Complete the function comment. Assert that at most one translation unit of a given path can be added to the corpus. (corpus::{find_translation_unit, get_type_per_loc_map}): Define new member functions. (corpus::{get_architecture_name}): Make this member function const. (struct corpus_group::priv): Define new type. (corpus_group::{corpus_group, ~corpus_group, add_corpus, get_corpora, is_empty, get_functions, get_variables, get_var_symbol_map, get_fun_symbol_map, get_sorted_fun_symbols, get_sorted_var_symbols, get_unreferenced_function_symbols, get_unreferenced_variable_symbols}): Define member functions of the new corpus_group type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-30 10:51:32 +00:00
typedef unordered_map<interned_string,
function_decl*,
hash_interned_string> istring_function_decl_ptr_map_type;
class method_decl;
typedef shared_ptr<method_decl> method_decl_sptr;
class mem_fn_context_rel;
/// A convenience typedef for a shared pointer to @ref
/// mem_fn_context_rel.
typedef shared_ptr<mem_fn_context_rel> mem_fn_context_rel_sptr;
class namespace_decl;
/// Convenience typedef for a shared pointer on namespace_decl.
typedef shared_ptr<namespace_decl> namespace_decl_sptr;
class class_tdecl;
/// Convenience typedef for a shared pointer on a @ref class_tdecl
typedef shared_ptr<class_tdecl> class_tdecl_sptr;
class function_tdecl;
/// Convenience typedef for a shared pointer on a @ref function_tdecl
typedef shared_ptr<function_tdecl> function_tdecl_sptr;
class global_scope;
/// Convenience typedef for shared pointer on @ref global_scope.
typedef shared_ptr<global_scope> global_scope_sptr;
class node_visitor;
class template_decl;
/// Convenience typedef for a shared pointer to @ref template_decl
typedef shared_ptr<template_decl> template_decl_sptr;
/// Convenience typedef for a weak pointer to template_decl
typedef weak_ptr<template_decl> template_decl_wptr;
class template_parameter;
/// Convenience typedef for shared pointer to template parameter
typedef shared_ptr<template_parameter> template_parameter_sptr;
class non_type_tparameter;
/// Convenience typedef for shared pointer to @ref
/// non_type_template_parameter
typedef shared_ptr<non_type_tparameter> non_type_tparameter_sptr;
class type_tparameter;
class template_tparameter;
/// Convenience typedef for a shared_ptr to @ref template_tparameter.
typedef shared_ptr<template_tparameter> template_tparameter_sptr;
/// Convenience typedef for a shared pointer to @ref type_tparameter.
typedef shared_ptr<type_tparameter> type_tparameter_sptr;
class type_composition;
class member_function_template;
typedef shared_ptr<member_function_template> member_function_template_sptr;
typedef vector<member_function_template_sptr> member_function_templates;
class member_class_template;
typedef shared_ptr<member_class_template> member_class_template_sptr;
typedef vector<member_class_template_sptr> member_class_templates;
/// Convenience typedef for shared pointer to type_composition
typedef shared_ptr<type_composition> type_composition_sptr;
decl_base_sptr
add_decl_to_scope(decl_base_sptr, scope_decl*);
decl_base_sptr
add_decl_to_scope(decl_base_sptr, const scope_decl_sptr&);
const global_scope*
get_global_scope(const decl_base&);
const global_scope*
get_global_scope(const decl_base*);
Support reading namespaces * include/abg-fwd.h (get_global_scope): Return a const global_scope. Add a new overload that takes a naked pointer as parm. (insert_decl_into_scope, get_top_most_scope_under): Declare new entry points. * include/abg-ir.h (class decl_base, class scope_decl): Add insert_decl_into_scope as a friend of these classes. (scope_decl::{insert_decl_into_scope, find_iterator_for_member}): Declare new member. (scope_decl::get_member_decls): New non-const overload. * src/abg-dwarf-reader.cc (build_translation_unit): Remove the "recurse" parameter. Adjust the call to build_ir_node_from_die to read just public decls that are at namespace scope. Anything else should be dropped unless it's needed to emitting the public namespace-level decls. (build_namespace_decl_and_add_to_ir) (canonicalize_and_insert_type_into_ir): Define new static functions. (build_corpus): Adjust ad build_translation_unit doesn't have the "recurse" parameter anymore. (canonicalize_and_add_type_to_ir): Make this static. Fix comments. (build_ir_node_from_die): Take a new "only_public_decl" parameter. For DW_TAG_base_type case, use the new canonicalize_and_insert_type_into_ir to insert the type at the right place in the global scope making sure it is seen before the current scope. For pointer, references and qualified types, use canonicalize_and_insert_type_into_ir to add the type at the same scope as its underlying type. Handle DW_TAG_{namespace,module} using the new build_namespace_decl_and_add_to_ir function. Add some vertical spaces and some assertions. * src/abg-ir.cc (scope_decl::add_member_decl): Use scope_decl_sptr typedef. (scope_decl::{insert_member_decl,find_iterator_for_member}): Define new methods. (insert_decl_into_scope, get_top_most_scope_under): Define new functions. (get_global_scope): Constify the return type. (get_translation_unit): Adjust as get_global_scope now returns a const. * src/abg-reader.cc (get_translation_unit): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2013-12-12 14:40:52 +00:00
const global_scope*
get_global_scope(const decl_base_sptr);
translation_unit*
get_translation_unit(const decl_base&);
translation_unit*
get_translation_unit(const decl_base*);
translation_unit*
get_translation_unit(const decl_base_sptr);
bool
is_global_scope(const scope_decl&);
const global_scope*
is_global_scope(const scope_decl*);
bool
is_global_scope(const scope_decl_sptr);
bool
is_at_global_scope(const decl_base&);
bool
is_at_global_scope(const decl_base_sptr);
Initial support of anonymous data members An anonymous data member is a data member of a struct or a union which has no name. The type of such data member is either a struct or a union. For instance: struct foo { int a; struct { // <-- this is an anonymous data member char a; char b; }; int c; }; In DWARF (as emitted by GCC at least), an anonymous data member is represented as a data member with an empty name. Libabigail sees it just fine, but then when representing *changes* to that kind of data member, it needs special treatment, otherwise users cannot make sense of the reports. This patch adds initial support to represent changes to anonymous data members. * include/abg-comparison.h (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Declare new functions. * include/abg-fwd.h (is_class_type): Declare new overload for type_or_decl_base&. (is_data_member): Declare new overload for decl_base*. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Declare new functions. (is_at_class_scope): Return the class or union scope. * include/abg-ir.h (var_decl::get_qualified_name): New virtual data member which overloads decl_base::get_qualified_name. * src/abg-comparison.cc (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Define new functions (leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous class or union diff nodes as diff nodes. * src/abg-ir.cc (is_data_member): Define new overload for decl_base*. (is_class_type, is_union_type): Define new overload for type_or_decl_base&. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Define new function overloads. (var_decl::get_qualified_name): Define new virtual member function. (is_at_class_scope): Return the class or union scope. (var_decl::get_pretty_representation): Support anonymous data members. (equals): In the overload for class_or_union_diff, mark data member textual representation changes as local changes. * src/abg-reporter-priv.cc (represent): In the overload for var_diff, support changes to anonymous data members. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted -- by offset -- data member changes before the ones that are sorted by other things. * tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so: New binary test input * tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt: New reference test outputs. * tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c: Source code of the new binary test output above. * tests/data/Makefile.am: Add the new test files above to the source distribution. * tests/data/test-annotate/libtest23.so.abi: Adjust test reference output. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-09 06:51:50 +00:00
class_or_union*
is_at_class_scope(const decl_base_sptr);
Initial support of anonymous data members An anonymous data member is a data member of a struct or a union which has no name. The type of such data member is either a struct or a union. For instance: struct foo { int a; struct { // <-- this is an anonymous data member char a; char b; }; int c; }; In DWARF (as emitted by GCC at least), an anonymous data member is represented as a data member with an empty name. Libabigail sees it just fine, but then when representing *changes* to that kind of data member, it needs special treatment, otherwise users cannot make sense of the reports. This patch adds initial support to represent changes to anonymous data members. * include/abg-comparison.h (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Declare new functions. * include/abg-fwd.h (is_class_type): Declare new overload for type_or_decl_base&. (is_data_member): Declare new overload for decl_base*. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Declare new functions. (is_at_class_scope): Return the class or union scope. * include/abg-ir.h (var_decl::get_qualified_name): New virtual data member which overloads decl_base::get_qualified_name. * src/abg-comparison.cc (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Define new functions (leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous class or union diff nodes as diff nodes. * src/abg-ir.cc (is_data_member): Define new overload for decl_base*. (is_class_type, is_union_type): Define new overload for type_or_decl_base&. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Define new function overloads. (var_decl::get_qualified_name): Define new virtual member function. (is_at_class_scope): Return the class or union scope. (var_decl::get_pretty_representation): Support anonymous data members. (equals): In the overload for class_or_union_diff, mark data member textual representation changes as local changes. * src/abg-reporter-priv.cc (represent): In the overload for var_diff, support changes to anonymous data members. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted -- by offset -- data member changes before the ones that are sorted by other things. * tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so: New binary test input * tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt: New reference test outputs. * tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c: Source code of the new binary test output above. * tests/data/Makefile.am: Add the new test files above to the source distribution. * tests/data/test-annotate/libtest23.so.abi: Adjust test reference output. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-09 06:51:50 +00:00
class_or_union*
Use the same representation for member and non-member types * include/abg-fwd.h (is_at_class_scope): Add new oveloads. (as_non_member_type, as_non_member_class_decl): Remove. (has_scope, is_member_decl, is_member_type): New function declarations. (get_member_is_static, set_member_is_static): Likewise. * include/abg-ir.h (enum access_specifier): Move to the abigail:: namespace, from ... (class_decl::access_specifier): ... here. (class context_rel): New type. (decl_base::hash_as_member): New hasher. (decl_base::context_): Change the type of this to context_rel_sptr. (decl_base::get_context_rel): New protected getter. (decl_base::get_scope): Move this out-of-line. (class_decl::member_type): Remove. (class_decl::member_types): Adjust this typedef. (class_decl::{insert,add}_member_type): Make these take a type_base_sptr now. (class_decl::add_member_type): Change the overload that returned a member_type to return a type_base_sptr. (get_member_access_specifier, set_member_access_specifier): New function declarations. * include/abg-comparison.h (class member_type_diff): Remove. (compute_diff): Remove the overload for member_type_diff. * src/abg-comparison.cc (compute_diff_for_types): Adjust for the removal of class_decl::member_type. (maybe_report_diff_for_class_members): New static function. (report_name_size_and_alignment_changes): Do not report a name change just because of a struct -> class change. ({var_diff, enum_diff, function_decl_diff}::report): Use the new maybe_report_diff_for_class_members. (class_diff::report): Adjust for the removal of class_decl::member_type. Use the new maybe_report_diff_for_class_members. (class member_diff): Remove. * src/abg-dwarf-reader.cc (die_access_specifier) (get_scope_for_die, build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_function_decl) (build_ir_node_from_die): Adjust. * abg-hash.cc (struct decl_base::hash_as_member): Define. ({scope_type_decl, enum_type_decl, typedef_decl}::hash::operator()): Use the decl_base::hash_as_member. * src/abg-ir.cc (decl_base::decl_base): Adjust. (decl_base::get_scope): New out-of-line getter. (decl_base::{operator==, set_scope): Adjust. (has_scope, is_member_decl, is_member_type) (get_member_access_specifier, set_member_access_specifier) (get_member_is_static, set_member_is_static, is_at_class_scope): New function definitions. (as_non_member_type, as_non_member_class_decl): Remove. (get_node_name): Adjust. (class_decl::{class_decl, set_earlier_declaration, insert_member_decl, insert_member_type, add_member_type): Likewise. (class_decl::member_type::*) Remove. * src/abg-reader.cc (read_access, build_qualified_type_decl) (build_reference_type_def, build_typedef_decl) (build_class_decl): Adjust. * src/abg-writer.cc (write_access, write_member_type) (write_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-13 10:13:54 +00:00
is_at_class_scope(const decl_base*);
Initial support of anonymous data members An anonymous data member is a data member of a struct or a union which has no name. The type of such data member is either a struct or a union. For instance: struct foo { int a; struct { // <-- this is an anonymous data member char a; char b; }; int c; }; In DWARF (as emitted by GCC at least), an anonymous data member is represented as a data member with an empty name. Libabigail sees it just fine, but then when representing *changes* to that kind of data member, it needs special treatment, otherwise users cannot make sense of the reports. This patch adds initial support to represent changes to anonymous data members. * include/abg-comparison.h (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Declare new functions. * include/abg-fwd.h (is_class_type): Declare new overload for type_or_decl_base&. (is_data_member): Declare new overload for decl_base*. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Declare new functions. (is_at_class_scope): Return the class or union scope. * include/abg-ir.h (var_decl::get_qualified_name): New virtual data member which overloads decl_base::get_qualified_name. * src/abg-comparison.cc (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Define new functions (leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous class or union diff nodes as diff nodes. * src/abg-ir.cc (is_data_member): Define new overload for decl_base*. (is_class_type, is_union_type): Define new overload for type_or_decl_base&. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Define new function overloads. (var_decl::get_qualified_name): Define new virtual member function. (is_at_class_scope): Return the class or union scope. (var_decl::get_pretty_representation): Support anonymous data members. (equals): In the overload for class_or_union_diff, mark data member textual representation changes as local changes. * src/abg-reporter-priv.cc (represent): In the overload for var_diff, support changes to anonymous data members. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted -- by offset -- data member changes before the ones that are sorted by other things. * tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so: New binary test input * tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt: New reference test outputs. * tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c: Source code of the new binary test output above. * tests/data/Makefile.am: Add the new test files above to the source distribution. * tests/data/test-annotate/libtest23.so.abi: Adjust test reference output. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-09 06:51:50 +00:00
class_or_union*
Use the same representation for member and non-member types * include/abg-fwd.h (is_at_class_scope): Add new oveloads. (as_non_member_type, as_non_member_class_decl): Remove. (has_scope, is_member_decl, is_member_type): New function declarations. (get_member_is_static, set_member_is_static): Likewise. * include/abg-ir.h (enum access_specifier): Move to the abigail:: namespace, from ... (class_decl::access_specifier): ... here. (class context_rel): New type. (decl_base::hash_as_member): New hasher. (decl_base::context_): Change the type of this to context_rel_sptr. (decl_base::get_context_rel): New protected getter. (decl_base::get_scope): Move this out-of-line. (class_decl::member_type): Remove. (class_decl::member_types): Adjust this typedef. (class_decl::{insert,add}_member_type): Make these take a type_base_sptr now. (class_decl::add_member_type): Change the overload that returned a member_type to return a type_base_sptr. (get_member_access_specifier, set_member_access_specifier): New function declarations. * include/abg-comparison.h (class member_type_diff): Remove. (compute_diff): Remove the overload for member_type_diff. * src/abg-comparison.cc (compute_diff_for_types): Adjust for the removal of class_decl::member_type. (maybe_report_diff_for_class_members): New static function. (report_name_size_and_alignment_changes): Do not report a name change just because of a struct -> class change. ({var_diff, enum_diff, function_decl_diff}::report): Use the new maybe_report_diff_for_class_members. (class_diff::report): Adjust for the removal of class_decl::member_type. Use the new maybe_report_diff_for_class_members. (class member_diff): Remove. * src/abg-dwarf-reader.cc (die_access_specifier) (get_scope_for_die, build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_function_decl) (build_ir_node_from_die): Adjust. * abg-hash.cc (struct decl_base::hash_as_member): Define. ({scope_type_decl, enum_type_decl, typedef_decl}::hash::operator()): Use the decl_base::hash_as_member. * src/abg-ir.cc (decl_base::decl_base): Adjust. (decl_base::get_scope): New out-of-line getter. (decl_base::{operator==, set_scope): Adjust. (has_scope, is_member_decl, is_member_type) (get_member_access_specifier, set_member_access_specifier) (get_member_is_static, set_member_is_static, is_at_class_scope): New function definitions. (as_non_member_type, as_non_member_class_decl): Remove. (get_node_name): Adjust. (class_decl::{class_decl, set_earlier_declaration, insert_member_decl, insert_member_type, add_member_type): Likewise. (class_decl::member_type::*) Remove. * src/abg-reader.cc (read_access, build_qualified_type_decl) (build_reference_type_def, build_typedef_decl) (build_class_decl): Adjust. * src/abg-writer.cc (write_access, write_member_type) (write_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-13 10:13:54 +00:00
is_at_class_scope(const decl_base&);
bool
is_at_template_scope(const decl_base_sptr);
bool
is_template_parameter(const decl_base_sptr);
function_decl*
Cleanup some entry points in abg-fwd.h While looking at something else I came accross some interface cleanup opportunities, as usual. This patch honours some of those opportunities. * include/abg-fwd.h (add_decl_to_scope): Pass the scope smart pointer by reference. (is_member_type): pass the type smart pointer by reference. (is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. * include/abg-ir.h (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (scope_decl::{add_member_decl, insert_member_decl}): Pass the member smart pointer by reference. (scope_decl::remove_member_decl): Take a non-const smart pointer. (class_decl::add_member_decl): Pass the decl smart pointer by reference. (is_method_decl): Take pointer or reference to type_or_decl_base rather than function_decl. * src/abg-ir.cc (translation_unit::priv::corpus): Make this a pointer to non-const corpus. (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (translation_unit::get_global_scope): Adjust. (translation_unit::bind_function_type_life_time): Adjust. (type_or_decl_base::translation_unit): Make this a pointer to non-const translation_unit. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (is_member_type): pass the type smart pointer by reference. (scope_decl::{add_member_decl, insert_member_decl}): Take a reference to the member decl smart pointer. Adjust. (class_decl::add_member_decl): Likewise. (scope_decl::remove_member_decl): Take a non-const smart pointer. (add_decl_to_scope): Pass the scope smart pointer by reference. (is_decl, is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_method_decl, is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-31 11:26:22 +00:00
is_function_decl(const type_or_decl_base*);
function_decl_sptr
is_function_decl(const type_or_decl_base_sptr&);
Initial support for function suppressions * include/abg-comparison.h (enum visiting_kind): Change the meaning of this. It was to determine if traversal was to be done in a pre or post manner. But with the recent addition of diff_node_visitor::visit_{begin,end}() notifiers, the pre/post handling is taken care of in a different way. So now the meaning of this enum is changed to handle whether diff node children should be visited or not. So the enumerators are now DEFAULT_VISITING_KIND, and SKIP_CHILDREN_VISITING_KIND. And it's a bit-field. (operator{&,~}): Declare more bit manipulation operators for the enum visiting_kind. (function_suppression_sptr, function_suppressions_type): New typedefs. (function_suppression, function_suppression::parameter_spec): Declare new types. (read_function_suppressions): Declare new function. (diff_node_visitor::diff_node_visitor): Adjust for the enum visiting_kind change. Value-initialize the visiting_kind_ data member. * src/abg-comparison.cc (operator{&,~}): Define these operators for enum visiting_kind. (read_type_suppressions): Forward declare this static function. (read_function_suppression, read_parameter_spec_from_string): Define new static functions. (read_suppressions): Update to read function suppressions too, using the new read_function_suppression function above. (class function_suppression::parameter_spec::priv): Define new type. (function_suppression::parameter_spec::*): Define the member functions of the new function_suppression::parameter_spec type. (class function_suppression::priv): Define new type. (function_suppression::*): Define the member functions of the new function_suppression type. (diff::traverse): There is no more {PRE,POST}_VISITING_KIND enumerator. So nuke the code that was dealing with it. (redundancy_marking_visitor::skip_children_nodes_): New data member flag. (redundancy_marking_visitor::visit_begin): If the current diff node is not be reported (is filtered out), do not bother visit its children nodes for the purpose of marking redundant nodes. So use the new skip_children_nodes_ flag above to know we are in that case. (redundancy_marking_visitor::visit_end): Unset the new skip_children_nodes_ flag above when appropriate. * include/abg-fwd.h (is_function_decl): Declare new function. * include/abg-ir.h (function_type::get_parm_at_index_from_first_non_implicit_parm): Declare new member function. * src/abg-ir.cc (is_function_decl): Define new function. (function_type::get_parm_at_index_from_first_non_implicit_parm): Define new member function. * src/abg-comp-filter.cc (apply_filter): Adjust for the enum visiting_kind change. No need to set it for filters anymore * doc/suppr-doc.txt: Update examples of function suppression. * doc/manuals/libabigail-concepts.rst: Update the manual for the function suppression addition. * tests/data/test-diff-suppr/libtest5-fn-suppr-v0.so: New test input. * tests/data/test-diff-suppr/libtest5-fn-suppr-v1.so: New test input. * tests/data/test-diff-suppr/libtest6-fn-suppr-v0.so: New test input. * tests/data/test-diff-suppr/libtest6-fn-suppr-v1.so: New test input. * tests/data/test-diff-suppr/test5-fn-suppr-0.suppr: New test input. * tests/data/test-diff-suppr/test5-fn-suppr-1.suppr: New test input. * tests/data/test-diff-suppr/test5-fn-suppr-2.suppr: New test input. * tests/data/test-diff-suppr/test5-fn-suppr-3.suppr: New test input. * tests/data/test-diff-suppr/test5-fn-suppr-4.suppr: New test input. * tests/data/test-diff-suppr/test5-fn-suppr-report-0.txt: New test input. * tests/data/test-diff-suppr/test5-fn-suppr-report-1.txt: New test input. * tests/data/test-diff-suppr/test5-fn-suppr-report-2.txt: New test input. * tests/data/test-diff-suppr/test5-fn-suppr-report-3.txt: New test input. * tests/data/test-diff-suppr/test5-fn-suppr-report-4.txt: New test input. * tests/data/test-diff-suppr/test5-fn-suppr-report-5.txt: New test input. * tests/data/test-diff-suppr/test5-fn-suppr-v0.cc: Source code for new test input. * tests/data/test-diff-suppr/test5-fn-suppr-v1.cc: Source code for new test input. * tests/data/test-diff-suppr/test6-fn-suppr-0.suppr: New test input. * tests/data/test-diff-suppr/test6-fn-suppr-1.suppr: New test input. * tests/data/test-diff-suppr/test6-fn-suppr-2.suppr: New test input. * tests/data/test-diff-suppr/test6-fn-suppr-3.suppr: New test input. * tests/data/test-diff-suppr/test6-fn-suppr-report-0.txt: New test input. * tests/data/test-diff-suppr/test6-fn-suppr-report-1.txt: New test input. * tests/data/test-diff-suppr/test6-fn-suppr-report-2.txt: New test input. * tests/data/test-diff-suppr/test6-fn-suppr-report-3.txt: New test input. * tests/data/test-diff-suppr/test6-fn-suppr-report-4.txt: New test input. * tests/data/test-diff-suppr/test6-fn-suppr-v0.cc: Source code for new test input. * tests/data/test-diff-suppr/test6-fn-suppr-v1.cc: Source code for new test input. * tests/data/test-diff-suppr/test6-fn-suppr-version-script: New test input. * tests/Makefile.am: Add the new files above to source the distribution. * tests/test-diff-suppr.cc (in_out_specs): Add the test inputs above to the list of tests to be run by this harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-28 10:32:15 +00:00
Do not compare access specs for member types & functions It turns that in some DWARF (e.g, from the r300_dri.so binary in bug libabigail/19024) the same class Foo can be declared as a struct, and later defined as a class. Or the other way around. In some cases, Foo can be declared as a struct, have a member type Foo::Type with no access specifier, and later that member type is still present with no access specifier when Foo is defined as a class. So when comparing Foo::Type (from struct Foo) against Foo::Type (from class Foo) we must not consider the access specification of Type, otherwise, as in the first case it's 'public' and in the second case it's 'private', the two member types would be considered different. And something similar happens for member function declarations too. This patch thus avoids comparing access specifiers for member types and functions. Though it can be considered as a regression compared to what was being done before, access specifiers don't have an impact on ABI per se. And they can cause noise in the result, as we are seeing here. * include/abg-fwd.h (is_function_decl): Declare a new overload. * src/abg-ir.cc (is_function_decl): Define a new overload. (equals): In the overload for decl_base, do not compare access specifiers when comparing member functions and types. * tests/data/test-diff-dwarf/test0-report.txt: Adjust. * tests/data/test-diff-filter/test0-report.txt: Likewise. * tests/data/test-diff-filter/test01-report.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test4-report.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 11:49:29 +00:00
bool
Cleanup some entry points in abg-fwd.h While looking at something else I came accross some interface cleanup opportunities, as usual. This patch honours some of those opportunities. * include/abg-fwd.h (add_decl_to_scope): Pass the scope smart pointer by reference. (is_member_type): pass the type smart pointer by reference. (is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. * include/abg-ir.h (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (scope_decl::{add_member_decl, insert_member_decl}): Pass the member smart pointer by reference. (scope_decl::remove_member_decl): Take a non-const smart pointer. (class_decl::add_member_decl): Pass the decl smart pointer by reference. (is_method_decl): Take pointer or reference to type_or_decl_base rather than function_decl. * src/abg-ir.cc (translation_unit::priv::corpus): Make this a pointer to non-const corpus. (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (translation_unit::get_global_scope): Adjust. (translation_unit::bind_function_type_life_time): Adjust. (type_or_decl_base::translation_unit): Make this a pointer to non-const translation_unit. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (is_member_type): pass the type smart pointer by reference. (scope_decl::{add_member_decl, insert_member_decl}): Take a reference to the member decl smart pointer. Adjust. (class_decl::add_member_decl): Likewise. (scope_decl::remove_member_decl): Take a non-const smart pointer. (add_decl_to_scope): Pass the scope smart pointer by reference. (is_decl, is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_method_decl, is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-31 11:26:22 +00:00
is_function_decl(const type_or_decl_base&);
Do not compare access specs for member types & functions It turns that in some DWARF (e.g, from the r300_dri.so binary in bug libabigail/19024) the same class Foo can be declared as a struct, and later defined as a class. Or the other way around. In some cases, Foo can be declared as a struct, have a member type Foo::Type with no access specifier, and later that member type is still present with no access specifier when Foo is defined as a class. So when comparing Foo::Type (from struct Foo) against Foo::Type (from class Foo) we must not consider the access specification of Type, otherwise, as in the first case it's 'public' and in the second case it's 'private', the two member types would be considered different. And something similar happens for member function declarations too. This patch thus avoids comparing access specifiers for member types and functions. Though it can be considered as a regression compared to what was being done before, access specifiers don't have an impact on ABI per se. And they can cause noise in the result, as we are seeing here. * include/abg-fwd.h (is_function_decl): Declare a new overload. * src/abg-ir.cc (is_function_decl): Define a new overload. (equals): In the overload for decl_base, do not compare access specifiers when comparing member functions and types. * tests/data/test-diff-dwarf/test0-report.txt: Adjust. * tests/data/test-diff-filter/test0-report.txt: Likewise. * tests/data/test-diff-filter/test01-report.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test4-report.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 11:49:29 +00:00
decl_base*
is_decl(const type_or_decl_base*);
decl_base_sptr
is_decl(const type_or_decl_base_sptr&);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
Serialize canonical types to avoid testing if types have been emitted When emitting abixml, profiling shows that we spend a great deal of time testing if a given type has been emitted already, to avoid emitting a given type more than once. This makes the serialization phase take more time than the binary analysis phase! This patch leverages the fact that we already have the set of canonical types in the system. While emitting that set entirely, we don't need to test if a type has been emitted already because we know by definition that every type is present just once in that set, more or less. OK, because there are also types that don't have canonical types (for instance, declaration-only class/structs), we'll still have to check of those types have already been emitted, but this is a very small set to handle. The patch thus organizes the canonical types per scope, so that when emitting a scope and the canonical types within it, the type is emitted in its correct namespace. Then, when emitting a translation unit and each namespaces in it, the patch emits the canonical types of those namespaces. The patch arranges for some ancillary things that are needed to make the whole picture be coherent enough for things to keep working. Testing shows that we gained ~ 30% of performance by doing this, while analysing the whole linux kernel 5.1 version. We went from ~ 3m30s minutes to less than 2m30s. With this patch, the serialization phase now takes less time than the analysis time. * include/abg-fwd.h (is_decl_slow) (peel_pointer_or_reference_type): Declare new functions. * include/abg-ir.h (struct canonical_type_hash): Define new type. (type_base_ptr_set_type, type_base_ptrs_type) (type_base_sptrs_type, canonical_type_sptr_set_type): Define new typedefs. (environment::get_canonical_types_map): Declare new member function. (scope_decl::{get_canonical_types, get_sorted_canonical_types}): Declare new member functions. * src/abg-ir.cc (is_ptr_ref_or_qual_type) (peel_pointer_or_reference_type, is_decl_slow): Define new functions. (environment::{get_canonical_types_map}): Define new member functions. (canonical_type_hash::operator()): Likewise. (scope_decl::{get_canonical_types, get_sorted_canonical_types}): Likewise. (struct type_topo_comp): Define new comparison functor type. (environment::{sorted_canonical_types_}): Define new data member. (scope_decl::priv::{canonical_types_, sorted_canonical_types_}): Likewise. (scope_decl::is_empty): Take the presence of canonical types into account when determining if a scope is empty or not. (is_decl): Make this work for cases where the artifact at hand is a type which has a declaration, as opposed to being a pure declaration like a variable or a function. (canonicalize): Add the canonical type the list of canonical types of its scope. * src/abg-dwarf-reader.cc (read_context::die_is_in_cplus_plus): Define new member function. * src/abg-writer.cc (write_type, write_canonical_types_of_scope): Define new static functions. (fn_type_ptr_set_type): Define new typedef. (write_context::{m_referenced_fn_types_set, m_referenced_non_canonical_types_set}): Add new data members. (write_context::m_referenced_types_set): Renamed m_referenced_types_map into this. (write_context::get_referenced_types): Adjust. (write_context::get_referenced_{function_types, non_canonical_types}): (write_context::record_type_as_referenced): Adjust to add the referenced type in the proper set which would be one of the three following: write_context::{get_referenced_types, get_referenced_function_types, get_referenced_non_canonical_types}. (write_context::{type_is_referenced, clear_referenced}): Adjust. (write_translation_unit): Use the new write_canonical_types_of_scope. Also emit declaration-only classes that have member types. Do not test if a given type of a given scope has been emitted, in general, as this was super slow given the number of types. Emit referenced function types (as these don't belong to any scope). Rather than using the expensive "is_function_type" on *all* the referenced types, just walk the set write_context::get_referenced_function_types. Likewise, rather than using type_base::get_naked_canonical_type on *all* the referenced types, just walk the set write_context::get_referenced_non_canonical_types (write_class): Use write_canonical_types_of_scope here. * tools/abilint.cc (main): Support linting corpus group abixml files. * tests/data/test-annotate/libtest23.so.abi: Adjust. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test-anonymous-members-0.o.abi: Likewise. * tests/data/test-annotate/test0.abi: Likewise. * tests/data/test-annotate/test1.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test2.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-annotate/test4.so.abi: Likewise. * tests/data/test-annotate/test6.so.abi: Likewise. * tests/data/test-annotate/test7.so.abi: Likewise. * tests/data/test-annotate/test8-qualified-this-pointer.so.abi: Likewise. * tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi: Likewise. * tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise. * tests/data/test-read-dwarf/PR24378-fn-is-not-scope.abi: Likewise. * tests/data/test-read-dwarf/libtest23.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * tests/data/test-read-dwarf/test1.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test2.so.abi: Likewise. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test4.so.abi: Likewise. * tests/data/test-read-dwarf/test6.so.abi: Likewise. * tests/data/test-read-dwarf/test7.so.abi: Likewise. * tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. * tests/data/test-read-write/test10.xml: Likewise. * tests/data/test-read-write/test14.xml: Likewise. * tests/data/test-read-write/test15.xml: Likewise. * tests/data/test-read-write/test17.xml: Likewise. * tests/data/test-read-write/test18.xml: Likewise. * tests/data/test-read-write/test19.xml: Likewise. * tests/data/test-read-write/test2.xml: Likewise. * tests/data/test-read-write/test20.xml: Likewise. * tests/data/test-read-write/test21.xml: Likewise. * tests/data/test-read-write/test22.xml: Likewise. * tests/data/test-read-write/test23.xml: Likewise. * tests/data/test-read-write/test24.xml: Likewise. * tests/data/test-read-write/test25.xml: Likewise. * tests/data/test-read-write/test26.xml: Likewise. * tests/data/test-read-write/test27.xml: Likewise. * tests/data/test-read-write/test28-without-std-fns-ref.xml: Likewise. * tests/data/test-read-write/test28-without-std-vars-ref.xml: Likewise. * tests/data/test-read-write/test3.xml: Likewise. * tests/data/test-read-write/test6.xml: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-08-02 15:06:37 +00:00
decl_base*
is_decl_slow(const type_or_decl_base*);
decl_base_sptr
is_decl_slow(const type_or_decl_base_sptr&);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
bool
is_type(const type_or_decl_base&);
type_base*
is_type(const type_or_decl_base*);
type_base_sptr
is_type(const type_or_decl_base_sptr& tod);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
Use the ODR to speed up type canonicalization This is the last patch of the series of 11 patches that started at the patch with the subject: constify is_class_type() And below starts the cover letter of this patch. While analyzing some libraries like libmozjs.so[1] it appeared that type canonicalization takes a significant time to comparing composite types that are re-defined in each translation units again and again. The One Definition Rule[2] says that two types with the same name shall designate the same thing; so when a type T being canonicalized has the same name of a canonical type C in the same ABI corpus, then this patch considers C as being the canonical type of T, without comparing T and C structurally. This saves us from comparing T and C. Before this patch, `abidw --noout libmozjs.so` was taking approximatively 5 minutes; with the patch, it takes 1 minutes and 30 seconds. To do this, the patch changes ABI artifacts to carry a pointer to the corpus it belongs to. Whenever an ABI artifact is added to a given context, the corpus of that context is propagated to the artifact; that is now possible as the artifact now carries the property of the corpus it belongs to. During type canonicalization the ODR-based optimization outlined above is performed as we can now compare the corpus of a given type again the one of another type; it's now possible to know if two types come from the same corpus. There are a few cases though were the optimization is not performed: - anonymous struct; when a struct is anonymous (it has no name, as described in the DWARF), the DWARF reader gives it a name nonetheless, so that diagnostics can refer to that anonymous type. But then all anonymous types in the system have the same name. So when faced with two anonymous types (with the same name) from the same corpus, it's wrong to consider that they name the same thing. The patch added an "is_anonymous" property to types created by the DWARF reader so that such anonymous types can be detected by the type canonicalizer; they are thus not involved in this optimization. Note that the abixml writer and reader have been updated to emit and read this property. - typedefs. I have seen in some boost code two typedefs of the same name refer to different underlying types. I believe this is a violation of ODR. I'll need to investigate on this later. And I think we really need to detect these ODR violations as part of this enhancement request: https://sourceware.org/bugzilla/show_bug.cgi?id=18941. - pointers, references, arrays and function types, as they can refer to the two exceptions above. This is the last patch of the series which aimed at speeding up type canonicalization in the context of types being re-defined a lot in translation units. [1]: Instruction to build libmozjs.so from the mongodb sources: - git clone https://github.com/mongodb/mongo.git - cd mongo - scons --link-model=dynamic build/opt/third_party/mozjs-38/libmozjs.so [2] One Definition Rule: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (class corpus): Forward-declare this. (is_anonymous_type): Declare this new function. * include/abg-ir.h (corpus_sptr, corpus_wptr): Declare these typedefs here too. (translation_unit::{g,s}et_corpus): Declare new member functions. (type_or_decl_base::{g,s}et_corpus): Likewise. * src/abg-ir.cc (translation_unit::priv::corpus): New data member. (translation_unit::priv::priv): Initialize it. (translation_unit::{g,s}et_corpus): Define new accessors. (translation_unit::get_global_scope): Propagate the corpus of the translation unit to its newly created global scope. (translation_unit::bind_function_type_life_time): Propagate the corpus of the translation_unit to the added function type. (type_or_decl_base::priv::corpus_): Add new data member. (type_or_decl_base::priv::priv): Initialize it. (type_or_decl_base::{g,s}et_corpus): Define new accessors. (scope_decl::{add,insert}_member_decl): Propagate the context's corpus to the member added to the context. (decl_base::priv::is_anonymous_): Add new data member. (decl_base::priv::priv): Initialize it. (decl_base::{s,g}et_is_anonymous): Define accessors. (is_anonymous_type): Define a new test function. (decl_base::set_name): Update the "is_anonymous" property. (type_base::get_canonical_type_for): Implement the ODR-based optimization to type canonicalization. * src/abg-corpus.cc (corpus::add): When a translation unit is added to a corpus, set the corpus of the translation unit. * src/abg-dwarf-reader.cc (build_enum_type) (build_class_type_and_add_to_ir): Set the "is_anonymous" flag on anonymous enums and classes. * src/abg-reader.cc (read_is_anonymous): Define new static function. (build_type_decl, build_enum_type, build_class_decl): Call the new read_is_anonymous function and set the "is_anonymous" property on the built type declaration. * src/abg-writer.cc (write_is_anonymous): Define new static function. (write_type_decl, write_enum_type_decl, write_class_decl): Write the "is_anonymous" property. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Adjust. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-04 10:34:13 +00:00
bool
is_anonymous_type(type_base*);
bool
is_anonymous_type(const type_base_sptr&);
Use the ODR to speed up type canonicalization This is the last patch of the series of 11 patches that started at the patch with the subject: constify is_class_type() And below starts the cover letter of this patch. While analyzing some libraries like libmozjs.so[1] it appeared that type canonicalization takes a significant time to comparing composite types that are re-defined in each translation units again and again. The One Definition Rule[2] says that two types with the same name shall designate the same thing; so when a type T being canonicalized has the same name of a canonical type C in the same ABI corpus, then this patch considers C as being the canonical type of T, without comparing T and C structurally. This saves us from comparing T and C. Before this patch, `abidw --noout libmozjs.so` was taking approximatively 5 minutes; with the patch, it takes 1 minutes and 30 seconds. To do this, the patch changes ABI artifacts to carry a pointer to the corpus it belongs to. Whenever an ABI artifact is added to a given context, the corpus of that context is propagated to the artifact; that is now possible as the artifact now carries the property of the corpus it belongs to. During type canonicalization the ODR-based optimization outlined above is performed as we can now compare the corpus of a given type again the one of another type; it's now possible to know if two types come from the same corpus. There are a few cases though were the optimization is not performed: - anonymous struct; when a struct is anonymous (it has no name, as described in the DWARF), the DWARF reader gives it a name nonetheless, so that diagnostics can refer to that anonymous type. But then all anonymous types in the system have the same name. So when faced with two anonymous types (with the same name) from the same corpus, it's wrong to consider that they name the same thing. The patch added an "is_anonymous" property to types created by the DWARF reader so that such anonymous types can be detected by the type canonicalizer; they are thus not involved in this optimization. Note that the abixml writer and reader have been updated to emit and read this property. - typedefs. I have seen in some boost code two typedefs of the same name refer to different underlying types. I believe this is a violation of ODR. I'll need to investigate on this later. And I think we really need to detect these ODR violations as part of this enhancement request: https://sourceware.org/bugzilla/show_bug.cgi?id=18941. - pointers, references, arrays and function types, as they can refer to the two exceptions above. This is the last patch of the series which aimed at speeding up type canonicalization in the context of types being re-defined a lot in translation units. [1]: Instruction to build libmozjs.so from the mongodb sources: - git clone https://github.com/mongodb/mongo.git - cd mongo - scons --link-model=dynamic build/opt/third_party/mozjs-38/libmozjs.so [2] One Definition Rule: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (class corpus): Forward-declare this. (is_anonymous_type): Declare this new function. * include/abg-ir.h (corpus_sptr, corpus_wptr): Declare these typedefs here too. (translation_unit::{g,s}et_corpus): Declare new member functions. (type_or_decl_base::{g,s}et_corpus): Likewise. * src/abg-ir.cc (translation_unit::priv::corpus): New data member. (translation_unit::priv::priv): Initialize it. (translation_unit::{g,s}et_corpus): Define new accessors. (translation_unit::get_global_scope): Propagate the corpus of the translation unit to its newly created global scope. (translation_unit::bind_function_type_life_time): Propagate the corpus of the translation_unit to the added function type. (type_or_decl_base::priv::corpus_): Add new data member. (type_or_decl_base::priv::priv): Initialize it. (type_or_decl_base::{g,s}et_corpus): Define new accessors. (scope_decl::{add,insert}_member_decl): Propagate the context's corpus to the member added to the context. (decl_base::priv::is_anonymous_): Add new data member. (decl_base::priv::priv): Initialize it. (decl_base::{s,g}et_is_anonymous): Define accessors. (is_anonymous_type): Define a new test function. (decl_base::set_name): Update the "is_anonymous" property. (type_base::get_canonical_type_for): Implement the ODR-based optimization to type canonicalization. * src/abg-corpus.cc (corpus::add): When a translation unit is added to a corpus, set the corpus of the translation unit. * src/abg-dwarf-reader.cc (build_enum_type) (build_class_type_and_add_to_ir): Set the "is_anonymous" flag on anonymous enums and classes. * src/abg-reader.cc (read_is_anonymous): Define new static function. (build_type_decl, build_enum_type, build_class_decl): Call the new read_is_anonymous function and set the "is_anonymous" property on the built type declaration. * src/abg-writer.cc (write_is_anonymous): Define new static function. (write_type_decl, write_enum_type_decl, write_class_decl): Write the "is_anonymous" property. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Adjust. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-04 10:34:13 +00:00
Improve detection of local *type* changes For variables and data member, we are quite gross in the way we detect a local type change. Basically, if a textual representation of the variable (and thus of its type) changes, then we consider that the variable has a local (possibly type) change. This leads us to (wrongly) report changes like this: 'struct S1 at test-44-anonymous-data-member-v0.c:1:1' changed: type size hasn't changed there are data member changes: anonymous data member at offset 32 (in bits) changed from: union {int b; float c;} to: union {int b; float c; char e;} Here, you see that the textual representation of the anonymous data member (of union type) changed from: union {int b; float c;} to: union {int b; float c; char e;} You see that although the textual representation of the type changed, the *structure* of the type hasn't really changed. I am using the "vague" term structure, on purpose. Here, in the case of a union, the structure hasn't change because the size of the union hasn't changed. This patch thus introduces the concept of "similarity of type structures". That is, even if two types are different, if "their structure is similar", then the type change is not a local type change. More precisely, here is what we mean by type similarity: Two indirect types (pointers, references) have similar structure if their underlying types are of the same kind and have the same name. In this indirect types case, the size of the underlying type does not matter. Two direct types (i.e, non indirect) have a similar structure if they have the same kind, name and size. Two class types have similar structure if they have the same name, size, and if their data members have similar types. This patch then uses that similarity concept to detect local type changes. * include/abg-fwd.h (is_type_decl): Declare new overload for type_base*. (types_have_similar_structure): Declare new function. * src/abg-comparison.cc (class_or_union_diff::priv::count_filtered_changed_dm): Even when looking at local changes only, do not forget to count nodes that were filtered out. * src/abg-ir.cc (types_have_similar_structure): Define new function. (is_type_decl): Define new overload for type_base*. (is_enum_type): (equals): In the overload for var_decl, use the new types_have_similar_structure function to detect local (type) changes. * src/abg-reporter-priv.cc (represent): In the overload for var_decl, use the diff::has_local_changes function to detect local changes, now that we can better detect local changes. * tests/data/test-diff-filter/test44-anonymous-data-member-report-1.txt: Adjust. * tests/data/test-diff-suppr/test36-leaf-report-0.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-18 08:18:45 +00:00
const type_decl*
Implement a poor-man's RTTI for performance Profiling showed that a number of use of dynamic_cast are a speed bottleneck. This patch implements a poor-man's RTTI that allows us to implement a form of dynamic_cast that is specific to the types of the internal reprenstation that are in the namespace abigail::ir. It speeds up things greatly. Basically, the base type of all ABI artifacts (abigail::ir::type_or_decl_base) now contains three new data members. The first one contains a bitmap that identifies the type of artifact. The second one contains a pointer to the dynamic type sub-object of the current instance of the artifact. The last one contains either a pointer to the type_base sub-object of the current instance of ABI artifact if it's a type, or a pointer to the type_decl sub-object of the current instance. Together these three data members allow the patch to implement the abigail::ir::{is_type(), is_decl(), is_<type_kind>_type} functions that we need to make the code base noticeably faster when using abidw on a big vmlinux binary. * include/abg-fwd.h (is_type_decl): Replace the overloads that takes a type_base* and/or a decl_base* by one that takes a type_or_decl_base*. * include/abg-ir.h (type_or_decl_base::type_or_decl_kind): Define new enum. (type_or_decl_base::{kind, runtime_type_instance, type_or_decl_base_pointer}): Declare new accessors. (operator{|,|=,&,&=): Declare new operators for the new type_or_decl_base::type_or_decl_kind enum. (global_scope::global_scope): Move the definition of this constructor to ... * src/abg-ir.cc (global_scope::global_scope): ... here. (type_or_decl_base::priv::{kind_, rtti_, type_or_decl_ptr_}): Add new data members. (type_or_decl_base::priv::priv): Take a type_or_decl_base::type_or_decl_kind enum. (type_or_decl_base::priv::kind): Define new accessors. (operator{|,|=,&,&=): Define new operators for the new type_or_decl_base::type_or_decl_kind enum. (type_or_decl_base::type_or_decl_base): Take a type_or_decl_base::type_or_decl_kind enum. (type_or_decl_base::{kind, runtime_type_instance, type_or_decl_base_pointer}): Define new accessors. (decl_base::decl_base, scope_decl::scope_decl) (type_base::type_base, scope_type_decl::scope_type_decl) (class_or_union::class_or_union) : Adjust to set the runtime type identifier of the instances of these types. (global_scope::global_scope, type_decl::type_decl) (qualified_type_def::qualified_type_def) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def array_type_def::subrange_type::subrange_type) (array_type_def::array_type_def, enum_type_decl::enum_type_decl) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter, method_decl::method_decl) (class_decl::class_decl, class_decl::base_spec::base_spec) (union_decl::union_decl, template_decl::template_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Likewise and call runtime_type_instance() here to set the runtime type instance pointers of the current instance. (is_decl, is_type, is_class_type, is_pointer_type): Adjust to use the new poor-man's rtti machinery. (is_type_decl): Replace the overloads that takes a type_base* and/or a decl_base* by one that takes a type_or_decl_base*. (pointer_type_def::operator==, class_decl::operator==): Use the poor-man's rtti machinery to replace dynamic_cast. hash_type_or_decl: Replace dynamic_cast<const type_base> by is_type() and dynamic_cast<const decl_base*> by is_decl(). Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-08 13:37:18 +00:00
is_type_decl(const type_or_decl_base*);
Improve detection of local *type* changes For variables and data member, we are quite gross in the way we detect a local type change. Basically, if a textual representation of the variable (and thus of its type) changes, then we consider that the variable has a local (possibly type) change. This leads us to (wrongly) report changes like this: 'struct S1 at test-44-anonymous-data-member-v0.c:1:1' changed: type size hasn't changed there are data member changes: anonymous data member at offset 32 (in bits) changed from: union {int b; float c;} to: union {int b; float c; char e;} Here, you see that the textual representation of the anonymous data member (of union type) changed from: union {int b; float c;} to: union {int b; float c; char e;} You see that although the textual representation of the type changed, the *structure* of the type hasn't really changed. I am using the "vague" term structure, on purpose. Here, in the case of a union, the structure hasn't change because the size of the union hasn't changed. This patch thus introduces the concept of "similarity of type structures". That is, even if two types are different, if "their structure is similar", then the type change is not a local type change. More precisely, here is what we mean by type similarity: Two indirect types (pointers, references) have similar structure if their underlying types are of the same kind and have the same name. In this indirect types case, the size of the underlying type does not matter. Two direct types (i.e, non indirect) have a similar structure if they have the same kind, name and size. Two class types have similar structure if they have the same name, size, and if their data members have similar types. This patch then uses that similarity concept to detect local type changes. * include/abg-fwd.h (is_type_decl): Declare new overload for type_base*. (types_have_similar_structure): Declare new function. * src/abg-comparison.cc (class_or_union_diff::priv::count_filtered_changed_dm): Even when looking at local changes only, do not forget to count nodes that were filtered out. * src/abg-ir.cc (types_have_similar_structure): Define new function. (is_type_decl): Define new overload for type_base*. (is_enum_type): (equals): In the overload for var_decl, use the new types_have_similar_structure function to detect local (type) changes. * src/abg-reporter-priv.cc (represent): In the overload for var_decl, use the diff::has_local_changes function to detect local changes, now that we can better detect local changes. * tests/data/test-diff-filter/test44-anonymous-data-member-report-1.txt: Adjust. * tests/data/test-diff-suppr/test36-leaf-report-0.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-18 08:18:45 +00:00
type_decl_sptr
Implement a poor-man's RTTI for performance Profiling showed that a number of use of dynamic_cast are a speed bottleneck. This patch implements a poor-man's RTTI that allows us to implement a form of dynamic_cast that is specific to the types of the internal reprenstation that are in the namespace abigail::ir. It speeds up things greatly. Basically, the base type of all ABI artifacts (abigail::ir::type_or_decl_base) now contains three new data members. The first one contains a bitmap that identifies the type of artifact. The second one contains a pointer to the dynamic type sub-object of the current instance of the artifact. The last one contains either a pointer to the type_base sub-object of the current instance of ABI artifact if it's a type, or a pointer to the type_decl sub-object of the current instance. Together these three data members allow the patch to implement the abigail::ir::{is_type(), is_decl(), is_<type_kind>_type} functions that we need to make the code base noticeably faster when using abidw on a big vmlinux binary. * include/abg-fwd.h (is_type_decl): Replace the overloads that takes a type_base* and/or a decl_base* by one that takes a type_or_decl_base*. * include/abg-ir.h (type_or_decl_base::type_or_decl_kind): Define new enum. (type_or_decl_base::{kind, runtime_type_instance, type_or_decl_base_pointer}): Declare new accessors. (operator{|,|=,&,&=): Declare new operators for the new type_or_decl_base::type_or_decl_kind enum. (global_scope::global_scope): Move the definition of this constructor to ... * src/abg-ir.cc (global_scope::global_scope): ... here. (type_or_decl_base::priv::{kind_, rtti_, type_or_decl_ptr_}): Add new data members. (type_or_decl_base::priv::priv): Take a type_or_decl_base::type_or_decl_kind enum. (type_or_decl_base::priv::kind): Define new accessors. (operator{|,|=,&,&=): Define new operators for the new type_or_decl_base::type_or_decl_kind enum. (type_or_decl_base::type_or_decl_base): Take a type_or_decl_base::type_or_decl_kind enum. (type_or_decl_base::{kind, runtime_type_instance, type_or_decl_base_pointer}): Define new accessors. (decl_base::decl_base, scope_decl::scope_decl) (type_base::type_base, scope_type_decl::scope_type_decl) (class_or_union::class_or_union) : Adjust to set the runtime type identifier of the instances of these types. (global_scope::global_scope, type_decl::type_decl) (qualified_type_def::qualified_type_def) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def array_type_def::subrange_type::subrange_type) (array_type_def::array_type_def, enum_type_decl::enum_type_decl) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter, method_decl::method_decl) (class_decl::class_decl, class_decl::base_spec::base_spec) (union_decl::union_decl, template_decl::template_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Likewise and call runtime_type_instance() here to set the runtime type instance pointers of the current instance. (is_decl, is_type, is_class_type, is_pointer_type): Adjust to use the new poor-man's rtti machinery. (is_type_decl): Replace the overloads that takes a type_base* and/or a decl_base* by one that takes a type_or_decl_base*. (pointer_type_def::operator==, class_decl::operator==): Use the poor-man's rtti machinery to replace dynamic_cast. hash_type_or_decl: Replace dynamic_cast<const type_base> by is_type() and dynamic_cast<const decl_base*> by is_decl(). Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-08 13:37:18 +00:00
is_type_decl(const type_or_decl_base_sptr&);
Replace is_typedef by type_kind property in type suppressions * doc/suppr-doc.txt: Add type_kind property "documentation" in the type suppression. * include/abg-comparison.h (type_suppression::type_kind): New enum. (type_suppression::{get_consider_typedefness, set_consider_typedefness, get_is_typedef, set_is_typedef}): Remove. (type_suppression::{get_consider_type_kind, set_consider_type_kind, get_type_kind, set_type_kind}): Declare new methods. * Include/abg-fwd.h (is_type_decl): Declare new function. (is_enum): Declare new overload that takes a type_base_sptr. * src/abg-comparison.cc (type_suppression::priv::{consider_typedefness_, is_typedef_}): Remove these data members. (type_suppression::priv::{consider_type_kind_, type_kind_}): New data members. (type_suppression::priv::priv): Adjust. (type_suppression::{get_consider_typedefness, set_consider_typedefness, get_is_typedef, set_is_typedef}): Remove these member functions. (type_suppression::{get_consider_type_kind, set_consider_type_kind, get_type_kind, set_type_kind}): Define these new member functions. (type_suppression::suppresses_diff): Adjust to consider the kind of types more generally than just considering typedef-ness. (read_type_kind_string): New static function. (read_type_suppression): Use the above to parse the value of the new type_kind property. Adjust the creation of the resulting type_suppression object. * src/abg-ir.cc (is_type_decl): Define new function. * tests/data/test-diff-suppr/test1-typedef-suppr-0.suppr: Adjust. * tests/data/test-diff-suppr/test1-typedef-suppr-1.suppr: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-09-22 06:03:02 +00:00
typedef_decl_sptr
Don't try to de-duplicate all anonymous struct DIEs Trying to de-duplicate anonymous struct DIEs can lead to subtle issues, because there can be two different naming typedefs designating two anonymous structs that are equivalent, in the same translation unit. In that case, de-duplicating the two leaf anonymous structs DIEs leads to non-resolvable conflict. This patch avoids de-duplicating anonymous structs DIEs and rather de-duplicates (naming) typedefs. * include/abg-fwd.h (is_typedef): Remove the overloads for type_base_sptr and decl_base_sptr. Replace those with an overload for type_or_decl_base_sptr. * src/abg-ir.cc (is_typedef): Do the same for the definitions. * src/abg-dwarf-reader.cc (add_or_update_class_type) (add_or_update_union_type): Do not de-duplicate anonymous struct/union DIEs. (build_typedef_type): Try to de-duplicate typedefs DIEs. * tests/data/test-annotate/test17-pr19027.so.abi: Adjust. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi: Likewise. * tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-24 14:20:30 +00:00
is_typedef(const type_or_decl_base_sptr);
Add a COMPATIBLE_TYPE_CHANGE_CATEGORY to bidiff --no-harmless * include/abg-comparison.h (diff_category::COMPATIBLE_TYPE_CHANGE_CATEGORY): New enumerator. (operator|=(diff_category&, diff_category)): New declaration. * include/abg-fwd.h (is_typedef, strip_typedef) (types_are_compatible): New declarations. * include/abg-ir.h (operator==(const decl_base_sptr, const decl_base_sptr)): Added the consts here. (operator==(const type_base_sptr, const type_base_sptr)): New declaration. * src/abg-comp-filter.cc (is_compatible_change): New static function. (harmless_filter::visit): Detect compatible changes and add the sub-tree into the new COMPATIBLE_TYPE_CHANGE_CATEGORY if applicable. Cleanup the logic. * src/abg-comparison.cc (operator|=(diff_category&, diff_category)): Define new function. (operator==(const decl_base_sptr l, const decl_base_sptr r)): Add consts. (operator==(const type_base_sptr l, const type_base_sptr r)): Define new operator. (is_typedef, strip_typedef, types_are_compatible): New function definitions. * tests/data/test-diff-filter/test3-report.txt: New test report reference. * tests/data/test-diff-filter/test3-v0.cc: Source code for new test input. * tests/data/test-diff-filter/test3-v0.o: New test input. * tests/data/test-diff-filter/test3-v1.cc: Source code for new test input. * tests/data/test-diff-filter/test3-v1.o: New test input. * tests/test-diff-filter.cc: Adjust to consume the new tests inputs above. * tools/bidiff.cc: Add the new COMPATIBLE_TYPE_CHANGE_CATEGORY into the --harmless group. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-04-02 15:23:56 +00:00
Make type_has_non_canonicalized_subtype() tighter type_has_non_canonicalized_subtype() gives up too quickly. For instance, suppose it's looking a type 'foo'. If foo has no canonicalized type yet and has a data member which type is foo* (for instance), then type_has_non_canonicalized_subtype() just sees that type 'foo*' has no canonicalized type, and so it returns, saying that he found a non-canonicalized subtype for foo. In that case though, what type_has_non_canonicalized_subtype() should do is detect that foo* is a pointer to foo itself, so it shouldn't count as a non-canonicalized sub-type. It should keep going and look for other meaningful non-canonicalized sub-types. And this what this patch does. It changes the sub-type walker that type_has_non_canonicalized_subtype() uses, so that - it doesn't flag sub-types that refer to the type we are looking at as non-canonicalized sub-types. This is for sub-types that are combinations of pointers, references and typedefs. - it doesn't consider sub-types of member functions of the type we are looking at, unless that member function is virtual. The result is that more types are canonicalized early during DWARF reading, and so there are less types to store on the side for late canonicalization. This can have a big impact on, e.g, C++ libraries with tens of thousands of types. * include/abg-fwd.h (is_typedef, is_pointer_type) (is_reference_type): Declare new overloads. (peel_typedef_type): Renamed get_typedef_underlying_type into this. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Declare new functions. * src/abg-ir.cc (peel_typedef_type): Renamed get_typedef_underlying_type into this. (is_typedef, is_pointer_type, is_reference_type): Define new overloads. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Define new functions. (non_canonicalized_subtype_detector::has_non_canonical_type_): Make the type of this data member be a type_base*, not a bool. This is so that we can return the first non-canonicalized subtype of the type we are looking at. (non_canonicalized_subtype_detector::non_canonicalized_subtype_detector): Adjust the data member initialization. (non_canonicalized_subtype_detector::visit_begin): Add an overload for function_decl*, to avoid looking into non-virtual member functions. In the overload for type_base*, peel typedefs, pointers and reference of each sub-type that has no canonical type, to see if refers to the type we are actually walking. If yes, then keep going. (type_has_non_canonicalized_subtype): Return the non-canonicalized sub-type found. * src/abg-comparison.cc (type_suppression::suppresses_diff): Adjust for the get_typedef_underlying_type -> peel_typedef_type renaming. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-19 14:15:28 +00:00
const typedef_decl*
is_typedef(const type_base*);
typedef_decl*
is_typedef(type_base*);
enum_type_decl_sptr
is_enum_type(const type_or_decl_base_sptr&);
const enum_type_decl*
is_enum_type(const type_or_decl_base*);
Initial support of anonymous data members An anonymous data member is a data member of a struct or a union which has no name. The type of such data member is either a struct or a union. For instance: struct foo { int a; struct { // <-- this is an anonymous data member char a; char b; }; int c; }; In DWARF (as emitted by GCC at least), an anonymous data member is represented as a data member with an empty name. Libabigail sees it just fine, but then when representing *changes* to that kind of data member, it needs special treatment, otherwise users cannot make sense of the reports. This patch adds initial support to represent changes to anonymous data members. * include/abg-comparison.h (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Declare new functions. * include/abg-fwd.h (is_class_type): Declare new overload for type_or_decl_base&. (is_data_member): Declare new overload for decl_base*. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Declare new functions. (is_at_class_scope): Return the class or union scope. * include/abg-ir.h (var_decl::get_qualified_name): New virtual data member which overloads decl_base::get_qualified_name. * src/abg-comparison.cc (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Define new functions (leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous class or union diff nodes as diff nodes. * src/abg-ir.cc (is_data_member): Define new overload for decl_base*. (is_class_type, is_union_type): Define new overload for type_or_decl_base&. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Define new function overloads. (var_decl::get_qualified_name): Define new virtual member function. (is_at_class_scope): Return the class or union scope. (var_decl::get_pretty_representation): Support anonymous data members. (equals): In the overload for class_or_union_diff, mark data member textual representation changes as local changes. * src/abg-reporter-priv.cc (represent): In the overload for var_diff, support changes to anonymous data members. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted -- by offset -- data member changes before the ones that are sorted by other things. * tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so: New binary test input * tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt: New reference test outputs. * tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c: Source code of the new binary test output above. * tests/data/Makefile.am: Add the new test files above to the source distribution. * tests/data/test-annotate/libtest23.so.abi: Adjust test reference output. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-09 06:51:50 +00:00
bool
is_class_type(const type_or_decl_base&);
When reading DWARF set member type access where the type is built The DWARF reader assumes that the DIEs for all member types are seen by build_class_type_and_add_to_ir(), as member type DIEs of the DIE of the class. Well that assumption is not correct because there can be errors in the DWARF we are looking at. One of these errors I stumbled accross is that a DIE for a typedef that should be a member typedef is actually a child of a *function* DIE. And that function DIE is a child of the class. Go figure. In any case, get_scope_for_die() already fixes that up and behaves as if the DIE of the typedef is a child of the DIE of the class. A side effect of this is that when build_class_type_and_add_to_ir() reads the DIE of the class, it never sees the DIE for that typedef. The takeaway of this state of affairs is that we cannot rely on build_class_type_and_add_to_ir() to update the member access specifier for member types because it does not see all member types. Rather build_ir_node_from_die() detects (reliably) that the type is a member type and updates the access specifier there. I also realize that the "is_member_type" flag of build_ir_node_from_die() and friends is useless now because inside build_ir_node_from_die() to know that that the type we are building is a member type, we just need to look at the scope and see if it's a class type. So by doing all this, this patch fixes the fact that some types were not being canonicalized because build_class_type_and_add_to_ir() was not seeing them. Ahhhh, DWARF. * include/abg-fwd.h (is_class(decl_base*)): Return a class_decl* rather than just a bool. * abg-ir.cc (is_class(decl_base*)): Return a class_decl* rather than just a bool. Simplify the implementation. * src/abg-dwarf-reader.cc (maybe_set_member_type_access_specifier): Define new static function. (build_ir_node_from_die): Remove the is_member_type flag. When building member types set their access specifier. Simplify the logic of detecting that a type is a member type; basically delegate taht to the new maybe_set_member_type_access_specifier(). (build_class_type_and_add_to_ir): Do not try to set the member type access specifiers anymore. (build_qualified_type, build_pointer_type, build_reference_type) (build_typedef_type, build_var_decl, build_function_decl): Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-24 11:42:22 +00:00
class_decl*
is_class_type(const type_or_decl_base*);
class_decl_sptr
is_class_type(const type_or_decl_base_sptr&);
Support union types This patch makes Libabigail understand C and C++ union types. It defines a new class abigail::ir::union_decl to represent the declaration of a union type. It also defines a new type abigail::comparison::union_diff to represent the changes between two union types. The patch then adds facilities to read union types from DWARF and abixml and also to write union types into the abixml format. As union types and class types have a lot in common, the patch tries very hard to share code between the abigail::ir::class_decl and abigail::ir::union_decl. To do so, a new class abigail::ir::class_or_union is created. It's the base class for both abigai::ir::class_decl and abigail::ir::union_decl. Its data members and methods represent the set of data and behaviour that are common to classes and unions. A lot of code and data that were initially in abigail::ir::class_decl got moved into the new abigail::ir::class_or_union class. Similary, the patch creates a new class abigail::comparison::class_or_union_diff that is a base class for both the existing class abigail::comparison::class_diff and the newly created class abigail::comparison::union_diff. The new class abigail::comparison::class_or_union_diff contains data and behaviour that are common to both union_diff and class_diff and that were previously in class_diff. The rest of the patch is mostly adjustment so that code that was supposed to work with class class_decl only can now work with class class_or_union when it makes sense. Similarly for class_diff and class_or_union_diff. The patch adds regression tests into the test suite and adjust many existing tests involving binaries that contain union types; the reference output of those tests now take union types into account. * include/abg-fwd.h (class_or_union, union_decl): Forward-declare new types. (is_class_or_union_type, is_union_type): Declare new functions. * include/abg-ir.h (method_type::class_type_): Make this be of class_or_union_wptr type. (method_type::method_type): Make the class_type parameter be of class_or_union_wptr type. (method_type::{g,s}et_class_type): Take or return a class_or_union_sptr. (member_base, method_decl, member_function_template) (member_class_template, member_base::hash) (member_function_template::hash, member_class_template::hash): Take these class types out of the class_decl scope. (is_method_decl): Adjust. (operator==, opertor!=): Adjust overloads for member_function_template_sptr and member_class_template_sptr. (class class_or_union): Declare new type. (class class_decl): Make this class inherit class_or_union class. (class_decl::{add_member_decl, insert_member_decl, remove_member_decl, set_size_in_bits, get_size_in_bits, get_alignment_in_bits, set_alignment_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, insert_member_type, add_member_type, remove_member_type, get_member_type, find_member_type, add_data_member, get_data_members, find_data_member, get_non_static_data_members, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates): Move these to the parent class class_or_union. (copy_member_function, equals): Add overloads for class_or_union. (struct class_or_union::hash): Declare new type. (class union_decl): Declare new type. (equals, copy_member_function): New overloads for class union_decl type. (ir_node_visitor::visit): Add new overloads for union_decl* and class_or_union*. * src/abg-ir.cc (get_member_function_is_ctor) (set_member_function_is_ctor, get_member_function_is_dtor) (set_member_function_is_dtor, get_member_function_is_const) (set_member_function_is_const, get_member_function_vtable_offset) (set_member_function_vtable_offset) (get_member_function_is_virtual, set_member_function_is_virtual) (maybe_update_types_lookup_map, get_location) (get_method_type_name, is_at_global_scope, is_at_class_scope): Adjust. (is_class_or_union_type, is_union_type): Define new functions. (type_base::get_canonical_type_for, maybe_adjust_canonical_type) (method_type::method_type, method_type::set_class_type) (function_decl::get_pretty_representation) (function_decl::get_first_non_implicit_parm) (function_decl::clone): Adjust. (equals): Adjust the overload for function_type. (struct class_or_union::priv): Define new type. (class::priv::{declaration_, definition_of_declaration_, member_types_, data_members_, non_static_data_members_, member_functions_, mem_fns_map_, member_function_templates_, member_class_templates_, is_declaration_only_}): Move these data member into class_or_union::priv. (class_priv::{mark_as_being_compared, unmark_as_being_compared, comparison_started}): Moved these member functions to class_or_union::priv. (class_or_union::{class_or_union, traverse, ~class_or_union, add_member_decl, remove_member_decl, insert_member_type, add_member_type, get_size_in_bits, remove_member_type, get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, get_member_types, find_member_type, add_data_member, get_data_member, find_data_member, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates, has_no_member, insert_member_decl, operator==}): Define new member functions. (class_decl::{add_member_decl, remove_member_decl, insert_member_type, add_member_type, get_size_in_bits, remove_member_type, get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, get_member_types, find_member_type, add_data_member, get_data_member, find_data_member, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates): Move these member functions into class_or_union. (class_decl::{class_decl, get_definition_of_declaration, insert_member_decl, add_member_function, has_no_base_nor_member}): Adjust. (equals, copy_member_function): Define new overloads for class_or_union. (equals): Adjust the overload for class_decl. (method_decl::{method_decl, set_linkage_name, ~method_decl, get_type, set_scope}): Remove from the class_decl scope. (member_base::operator==, member_function_template::operator==): Likewise. (member_function_template::traverse) (member_class_template::operator==) (member_class_template::traverse): Likewise. (operator==, operator!=): Adjust the overlod for member_function_template_sptr. (is_method_decl, fixup_virtual_member_function) (set_member_is_static): Adjust. (virtual_member_function_less_than::operator()): Likewise. (union_decl::{union_decl, get_pretty_representation, operator==, traverse}): Define new member functions. (equals, copy_member_function): Define new overloads for union_decl. (hash_type_or_decl): Adjust. (ir_node_visitor::visit_{begin, end}): Adjust. Add new overloads for class_or_union* and union_decl*. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust these typedefs. (class class_or_union_diff): Declare new type. (class_diff): Adjust to make this inherit the new class_or_union_diff type. (class_diff::{get_priv, member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes}): These member functions got moved into -- and shared with -- class_or_union_diff class. (class union_diff): Declare new type. (typedef union_diff_sptr): New typedef. (compute_diff): New overload for union_diff (is_class_diff, is_union_diff): Declare new functions. * src/abg-comparison.cc (is_class_diff, is_union_diff): Define new functions. (compute_diff_for_types): Support union_decl. (represent): Adjust. (represent_data_member): Do not show offset information for data members of unions as all union data members are at offset 0. (struct class_or_union_diff::priv): New type. (class_or_union_diff::priv::{member_type_has_changed, subtype_changed_dm, member_class_tmpl_has_changed, get_deleted_non_static_data_members_number, get_inserted_non_static_data_members_number, count_filtered_subtype_changed_dm, count_filtered_changed_dm, count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns}): Define new member functions. (class_or_union_diff::{class_or_union_diff, finish_diff_type, lookup_tables_empty, lookup_tables_empty, ensure_lookup_tables_populated, allocate_priv_data, get_priv, ~class_or_union_diff, first_class_or_union, second_class_or_union, member_types_changes, member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fns_changes, changed_member_fns, member_fns_changes, inserted_member_fns, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes, member_class_tmpls_changes, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new member functions. (class_diff::priv::{member_types_changes_, data_members_changes, member_fn_tmpls_changes_, member_class_tmpls_changes_, deleted_member_types_, inserted_member_types_, changed_member_types_, sorted_changed_member_types_, deleted_data_members_, deleted_dm_by_offset_, inserted_data_members_, inserted_dm_by_offset_, subtype_changed_dm_, sorted_subtype_changed_dm_, changed_dm_, sorted_changed_dm_, deleted_member_functions_, inserted_member_functions_, changed_member_functions_, sorted_changed_member_functions_, deleted_member_class_tmpls_, inserted_member_class_tmpls_, changed_member_class_tmpls_, sorted_changed_member_class_tmpls_}): Move these data members into class_or_union_diff::priv. (class_diff::{clear_lookup_tables, lookup_tables_empty, ensure_lookup_tables_populate}): Adjust. (class_diff::allocate_priv_data): Define new function. (class_diff::priv::{count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns, chain_into_hierarchy, class_diff}): Likewise. (class_diff::{member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes}): These are deleted as they got moved to class_or_union_diff. (class_diff::report): Adjust. (union_diff::{clear_lookup_tables, lookup_tables_empty, ensure_lookup_tables_populated, allocate_priv_data, union_diff, finish_diff_type, first_union_decl, second_union_decl, get_pretty_representation, report}): Define new functions. (compute_diff): Define an overload for union_decl_sptr. (function_decl_diff::report): Adjust. (corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars): Adjust. (corpus_diff::report): Adjust. * src/abg-hash.cc (member_base::hash::operator) (member_function_template::hash::operator) (member_class_template::hash::operator): Move these out of the class_decl scope. (class_or_union::hash::operator): Define new member function. (class_decl::hash::operator): Adjust. (type_base::dynamic_hash::operator): Support hashing of union_decl. Adjust. * src/abg-suppression.cc (type_suppression::suppresses_diff): Adjust. * src/abg-dwarf-reader.cc (typedef die_class_or_union_map_type): Define new typedef. (read_context::{die_wip_classes_map_, alternate_die_wip_classes_map_, type_unit_die_wip_classes_map_): Make these data member have type die_class_or_union_map_type. (read_context::{lookup_type_from_die_offset, die_wip_classes_map, is_wip_class_die_offset, resolve_declaration_only_classes}): Adjust. (finish_member_function_reading, build_class_type_and_add_to_ir) (build_function_type, build_function_decl, build_reference_type) (type_is_suppressed, build_function_decl) (maybe_canonicalize_type, maybe_set_member_type_access_specifier): Adjust. (build_union_type_and_add_to_ir): Define new static function. (build_ir_node_from_die): Support DW_TAG_union_type DIE tag. * src/abg-reader.cc (handle_element_node): Handle union_decl. (build_function_decl, build_function_decl_if_not_suppressed): Adjust. (build_union_decl_if_not_suppressed, build_union_decl) (handle_union_decl): Define new functions. (build_class_decl): Adjust. * src/abg-writer.cc (record_decl_only_type_as_emitted): Adjust. (write_decl): Adjust. Support writting union_decl type. p (write_class_decl_opening_tag, write_class_decl): Adjust. Call the new write_class_or_union_is_declaration_only. (write_union_decl_opening_tag, write_union_decl): Define new static functions. (write_member_tpe): Support writting union decl. * tests/test-diff-dwarf.cc (in_out_specs): Add new tests for this union type support. * tests/data/test-diff-dwarf/libtest37-union-v0.so: New test input. * tests/data/test-diff-dwarf/libtest37-union-v1.so: Likewise. * tests/data/test-diff-dwarf/libtest38-union-v0.so: Likewise. * tests/data/test-diff-dwarf/libtest38-union-v1.so: Likewise. * tests/data/test-diff-dwarf/libtest39-union-v0.so: Likewise. * tests/data/test-diff-dwarf/libtest39-union-v1.so: Likewise. * tests/data/test-diff-dwarf/test37-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test38-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test39-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test37-union-v0.cc: Source code for new test input. * tests/data/test-diff-dwarf/test37-union-v1.cc: Likewise. * tests/data/test-diff-dwarf/test38-union-v0.cc: Likewise. * tests/data/test-diff-dwarf/test38-union-v1.cc: Likewise. * tests/data/test-diff-dwarf/test39-union-v0.cc: Likewise. * tests/data/test-diff-dwarf/test39-union-v1.cc: Likewise. * tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi: Update test reference. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-read-dwarf/libtest23.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-15 00:16:46 +00:00
class_or_union*
is_class_or_union_type(const type_or_decl_base*);
class_or_union_sptr
is_class_or_union_type(const type_or_decl_base_sptr&);
Support union types This patch makes Libabigail understand C and C++ union types. It defines a new class abigail::ir::union_decl to represent the declaration of a union type. It also defines a new type abigail::comparison::union_diff to represent the changes between two union types. The patch then adds facilities to read union types from DWARF and abixml and also to write union types into the abixml format. As union types and class types have a lot in common, the patch tries very hard to share code between the abigail::ir::class_decl and abigail::ir::union_decl. To do so, a new class abigail::ir::class_or_union is created. It's the base class for both abigai::ir::class_decl and abigail::ir::union_decl. Its data members and methods represent the set of data and behaviour that are common to classes and unions. A lot of code and data that were initially in abigail::ir::class_decl got moved into the new abigail::ir::class_or_union class. Similary, the patch creates a new class abigail::comparison::class_or_union_diff that is a base class for both the existing class abigail::comparison::class_diff and the newly created class abigail::comparison::union_diff. The new class abigail::comparison::class_or_union_diff contains data and behaviour that are common to both union_diff and class_diff and that were previously in class_diff. The rest of the patch is mostly adjustment so that code that was supposed to work with class class_decl only can now work with class class_or_union when it makes sense. Similarly for class_diff and class_or_union_diff. The patch adds regression tests into the test suite and adjust many existing tests involving binaries that contain union types; the reference output of those tests now take union types into account. * include/abg-fwd.h (class_or_union, union_decl): Forward-declare new types. (is_class_or_union_type, is_union_type): Declare new functions. * include/abg-ir.h (method_type::class_type_): Make this be of class_or_union_wptr type. (method_type::method_type): Make the class_type parameter be of class_or_union_wptr type. (method_type::{g,s}et_class_type): Take or return a class_or_union_sptr. (member_base, method_decl, member_function_template) (member_class_template, member_base::hash) (member_function_template::hash, member_class_template::hash): Take these class types out of the class_decl scope. (is_method_decl): Adjust. (operator==, opertor!=): Adjust overloads for member_function_template_sptr and member_class_template_sptr. (class class_or_union): Declare new type. (class class_decl): Make this class inherit class_or_union class. (class_decl::{add_member_decl, insert_member_decl, remove_member_decl, set_size_in_bits, get_size_in_bits, get_alignment_in_bits, set_alignment_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, insert_member_type, add_member_type, remove_member_type, get_member_type, find_member_type, add_data_member, get_data_members, find_data_member, get_non_static_data_members, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates): Move these to the parent class class_or_union. (copy_member_function, equals): Add overloads for class_or_union. (struct class_or_union::hash): Declare new type. (class union_decl): Declare new type. (equals, copy_member_function): New overloads for class union_decl type. (ir_node_visitor::visit): Add new overloads for union_decl* and class_or_union*. * src/abg-ir.cc (get_member_function_is_ctor) (set_member_function_is_ctor, get_member_function_is_dtor) (set_member_function_is_dtor, get_member_function_is_const) (set_member_function_is_const, get_member_function_vtable_offset) (set_member_function_vtable_offset) (get_member_function_is_virtual, set_member_function_is_virtual) (maybe_update_types_lookup_map, get_location) (get_method_type_name, is_at_global_scope, is_at_class_scope): Adjust. (is_class_or_union_type, is_union_type): Define new functions. (type_base::get_canonical_type_for, maybe_adjust_canonical_type) (method_type::method_type, method_type::set_class_type) (function_decl::get_pretty_representation) (function_decl::get_first_non_implicit_parm) (function_decl::clone): Adjust. (equals): Adjust the overload for function_type. (struct class_or_union::priv): Define new type. (class::priv::{declaration_, definition_of_declaration_, member_types_, data_members_, non_static_data_members_, member_functions_, mem_fns_map_, member_function_templates_, member_class_templates_, is_declaration_only_}): Move these data member into class_or_union::priv. (class_priv::{mark_as_being_compared, unmark_as_being_compared, comparison_started}): Moved these member functions to class_or_union::priv. (class_or_union::{class_or_union, traverse, ~class_or_union, add_member_decl, remove_member_decl, insert_member_type, add_member_type, get_size_in_bits, remove_member_type, get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, get_member_types, find_member_type, add_data_member, get_data_member, find_data_member, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates, has_no_member, insert_member_decl, operator==}): Define new member functions. (class_decl::{add_member_decl, remove_member_decl, insert_member_type, add_member_type, get_size_in_bits, remove_member_type, get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, get_member_types, find_member_type, add_data_member, get_data_member, find_data_member, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates): Move these member functions into class_or_union. (class_decl::{class_decl, get_definition_of_declaration, insert_member_decl, add_member_function, has_no_base_nor_member}): Adjust. (equals, copy_member_function): Define new overloads for class_or_union. (equals): Adjust the overload for class_decl. (method_decl::{method_decl, set_linkage_name, ~method_decl, get_type, set_scope}): Remove from the class_decl scope. (member_base::operator==, member_function_template::operator==): Likewise. (member_function_template::traverse) (member_class_template::operator==) (member_class_template::traverse): Likewise. (operator==, operator!=): Adjust the overlod for member_function_template_sptr. (is_method_decl, fixup_virtual_member_function) (set_member_is_static): Adjust. (virtual_member_function_less_than::operator()): Likewise. (union_decl::{union_decl, get_pretty_representation, operator==, traverse}): Define new member functions. (equals, copy_member_function): Define new overloads for union_decl. (hash_type_or_decl): Adjust. (ir_node_visitor::visit_{begin, end}): Adjust. Add new overloads for class_or_union* and union_decl*. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust these typedefs. (class class_or_union_diff): Declare new type. (class_diff): Adjust to make this inherit the new class_or_union_diff type. (class_diff::{get_priv, member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes}): These member functions got moved into -- and shared with -- class_or_union_diff class. (class union_diff): Declare new type. (typedef union_diff_sptr): New typedef. (compute_diff): New overload for union_diff (is_class_diff, is_union_diff): Declare new functions. * src/abg-comparison.cc (is_class_diff, is_union_diff): Define new functions. (compute_diff_for_types): Support union_decl. (represent): Adjust. (represent_data_member): Do not show offset information for data members of unions as all union data members are at offset 0. (struct class_or_union_diff::priv): New type. (class_or_union_diff::priv::{member_type_has_changed, subtype_changed_dm, member_class_tmpl_has_changed, get_deleted_non_static_data_members_number, get_inserted_non_static_data_members_number, count_filtered_subtype_changed_dm, count_filtered_changed_dm, count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns}): Define new member functions. (class_or_union_diff::{class_or_union_diff, finish_diff_type, lookup_tables_empty, lookup_tables_empty, ensure_lookup_tables_populated, allocate_priv_data, get_priv, ~class_or_union_diff, first_class_or_union, second_class_or_union, member_types_changes, member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fns_changes, changed_member_fns, member_fns_changes, inserted_member_fns, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes, member_class_tmpls_changes, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new member functions. (class_diff::priv::{member_types_changes_, data_members_changes, member_fn_tmpls_changes_, member_class_tmpls_changes_, deleted_member_types_, inserted_member_types_, changed_member_types_, sorted_changed_member_types_, deleted_data_members_, deleted_dm_by_offset_, inserted_data_members_, inserted_dm_by_offset_, subtype_changed_dm_, sorted_subtype_changed_dm_, changed_dm_, sorted_changed_dm_, deleted_member_functions_, inserted_member_functions_, changed_member_functions_, sorted_changed_member_functions_, deleted_member_class_tmpls_, inserted_member_class_tmpls_, changed_member_class_tmpls_, sorted_changed_member_class_tmpls_}): Move these data members into class_or_union_diff::priv. (class_diff::{clear_lookup_tables, lookup_tables_empty, ensure_lookup_tables_populate}): Adjust. (class_diff::allocate_priv_data): Define new function. (class_diff::priv::{count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns, chain_into_hierarchy, class_diff}): Likewise. (class_diff::{member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes}): These are deleted as they got moved to class_or_union_diff. (class_diff::report): Adjust. (union_diff::{clear_lookup_tables, lookup_tables_empty, ensure_lookup_tables_populated, allocate_priv_data, union_diff, finish_diff_type, first_union_decl, second_union_decl, get_pretty_representation, report}): Define new functions. (compute_diff): Define an overload for union_decl_sptr. (function_decl_diff::report): Adjust. (corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars): Adjust. (corpus_diff::report): Adjust. * src/abg-hash.cc (member_base::hash::operator) (member_function_template::hash::operator) (member_class_template::hash::operator): Move these out of the class_decl scope. (class_or_union::hash::operator): Define new member function. (class_decl::hash::operator): Adjust. (type_base::dynamic_hash::operator): Support hashing of union_decl. Adjust. * src/abg-suppression.cc (type_suppression::suppresses_diff): Adjust. * src/abg-dwarf-reader.cc (typedef die_class_or_union_map_type): Define new typedef. (read_context::{die_wip_classes_map_, alternate_die_wip_classes_map_, type_unit_die_wip_classes_map_): Make these data member have type die_class_or_union_map_type. (read_context::{lookup_type_from_die_offset, die_wip_classes_map, is_wip_class_die_offset, resolve_declaration_only_classes}): Adjust. (finish_member_function_reading, build_class_type_and_add_to_ir) (build_function_type, build_function_decl, build_reference_type) (type_is_suppressed, build_function_decl) (maybe_canonicalize_type, maybe_set_member_type_access_specifier): Adjust. (build_union_type_and_add_to_ir): Define new static function. (build_ir_node_from_die): Support DW_TAG_union_type DIE tag. * src/abg-reader.cc (handle_element_node): Handle union_decl. (build_function_decl, build_function_decl_if_not_suppressed): Adjust. (build_union_decl_if_not_suppressed, build_union_decl) (handle_union_decl): Define new functions. (build_class_decl): Adjust. * src/abg-writer.cc (record_decl_only_type_as_emitted): Adjust. (write_decl): Adjust. Support writting union_decl type. p (write_class_decl_opening_tag, write_class_decl): Adjust. Call the new write_class_or_union_is_declaration_only. (write_union_decl_opening_tag, write_union_decl): Define new static functions. (write_member_tpe): Support writting union decl. * tests/test-diff-dwarf.cc (in_out_specs): Add new tests for this union type support. * tests/data/test-diff-dwarf/libtest37-union-v0.so: New test input. * tests/data/test-diff-dwarf/libtest37-union-v1.so: Likewise. * tests/data/test-diff-dwarf/libtest38-union-v0.so: Likewise. * tests/data/test-diff-dwarf/libtest38-union-v1.so: Likewise. * tests/data/test-diff-dwarf/libtest39-union-v0.so: Likewise. * tests/data/test-diff-dwarf/libtest39-union-v1.so: Likewise. * tests/data/test-diff-dwarf/test37-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test38-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test39-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test37-union-v0.cc: Source code for new test input. * tests/data/test-diff-dwarf/test37-union-v1.cc: Likewise. * tests/data/test-diff-dwarf/test38-union-v0.cc: Likewise. * tests/data/test-diff-dwarf/test38-union-v1.cc: Likewise. * tests/data/test-diff-dwarf/test39-union-v0.cc: Likewise. * tests/data/test-diff-dwarf/test39-union-v1.cc: Likewise. * tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi: Update test reference. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-read-dwarf/libtest23.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-15 00:16:46 +00:00
Initial support of anonymous data members An anonymous data member is a data member of a struct or a union which has no name. The type of such data member is either a struct or a union. For instance: struct foo { int a; struct { // <-- this is an anonymous data member char a; char b; }; int c; }; In DWARF (as emitted by GCC at least), an anonymous data member is represented as a data member with an empty name. Libabigail sees it just fine, but then when representing *changes* to that kind of data member, it needs special treatment, otherwise users cannot make sense of the reports. This patch adds initial support to represent changes to anonymous data members. * include/abg-comparison.h (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Declare new functions. * include/abg-fwd.h (is_class_type): Declare new overload for type_or_decl_base&. (is_data_member): Declare new overload for decl_base*. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Declare new functions. (is_at_class_scope): Return the class or union scope. * include/abg-ir.h (var_decl::get_qualified_name): New virtual data member which overloads decl_base::get_qualified_name. * src/abg-comparison.cc (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Define new functions (leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous class or union diff nodes as diff nodes. * src/abg-ir.cc (is_data_member): Define new overload for decl_base*. (is_class_type, is_union_type): Define new overload for type_or_decl_base&. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Define new function overloads. (var_decl::get_qualified_name): Define new virtual member function. (is_at_class_scope): Return the class or union scope. (var_decl::get_pretty_representation): Support anonymous data members. (equals): In the overload for class_or_union_diff, mark data member textual representation changes as local changes. * src/abg-reporter-priv.cc (represent): In the overload for var_diff, support changes to anonymous data members. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted -- by offset -- data member changes before the ones that are sorted by other things. * tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so: New binary test input * tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt: New reference test outputs. * tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c: Source code of the new binary test output above. * tests/data/Makefile.am: Add the new test files above to the source distribution. * tests/data/test-annotate/libtest23.so.abi: Adjust test reference output. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-09 06:51:50 +00:00
bool
is_union_type(const type_or_decl_base&);
Support union types This patch makes Libabigail understand C and C++ union types. It defines a new class abigail::ir::union_decl to represent the declaration of a union type. It also defines a new type abigail::comparison::union_diff to represent the changes between two union types. The patch then adds facilities to read union types from DWARF and abixml and also to write union types into the abixml format. As union types and class types have a lot in common, the patch tries very hard to share code between the abigail::ir::class_decl and abigail::ir::union_decl. To do so, a new class abigail::ir::class_or_union is created. It's the base class for both abigai::ir::class_decl and abigail::ir::union_decl. Its data members and methods represent the set of data and behaviour that are common to classes and unions. A lot of code and data that were initially in abigail::ir::class_decl got moved into the new abigail::ir::class_or_union class. Similary, the patch creates a new class abigail::comparison::class_or_union_diff that is a base class for both the existing class abigail::comparison::class_diff and the newly created class abigail::comparison::union_diff. The new class abigail::comparison::class_or_union_diff contains data and behaviour that are common to both union_diff and class_diff and that were previously in class_diff. The rest of the patch is mostly adjustment so that code that was supposed to work with class class_decl only can now work with class class_or_union when it makes sense. Similarly for class_diff and class_or_union_diff. The patch adds regression tests into the test suite and adjust many existing tests involving binaries that contain union types; the reference output of those tests now take union types into account. * include/abg-fwd.h (class_or_union, union_decl): Forward-declare new types. (is_class_or_union_type, is_union_type): Declare new functions. * include/abg-ir.h (method_type::class_type_): Make this be of class_or_union_wptr type. (method_type::method_type): Make the class_type parameter be of class_or_union_wptr type. (method_type::{g,s}et_class_type): Take or return a class_or_union_sptr. (member_base, method_decl, member_function_template) (member_class_template, member_base::hash) (member_function_template::hash, member_class_template::hash): Take these class types out of the class_decl scope. (is_method_decl): Adjust. (operator==, opertor!=): Adjust overloads for member_function_template_sptr and member_class_template_sptr. (class class_or_union): Declare new type. (class class_decl): Make this class inherit class_or_union class. (class_decl::{add_member_decl, insert_member_decl, remove_member_decl, set_size_in_bits, get_size_in_bits, get_alignment_in_bits, set_alignment_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, insert_member_type, add_member_type, remove_member_type, get_member_type, find_member_type, add_data_member, get_data_members, find_data_member, get_non_static_data_members, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates): Move these to the parent class class_or_union. (copy_member_function, equals): Add overloads for class_or_union. (struct class_or_union::hash): Declare new type. (class union_decl): Declare new type. (equals, copy_member_function): New overloads for class union_decl type. (ir_node_visitor::visit): Add new overloads for union_decl* and class_or_union*. * src/abg-ir.cc (get_member_function_is_ctor) (set_member_function_is_ctor, get_member_function_is_dtor) (set_member_function_is_dtor, get_member_function_is_const) (set_member_function_is_const, get_member_function_vtable_offset) (set_member_function_vtable_offset) (get_member_function_is_virtual, set_member_function_is_virtual) (maybe_update_types_lookup_map, get_location) (get_method_type_name, is_at_global_scope, is_at_class_scope): Adjust. (is_class_or_union_type, is_union_type): Define new functions. (type_base::get_canonical_type_for, maybe_adjust_canonical_type) (method_type::method_type, method_type::set_class_type) (function_decl::get_pretty_representation) (function_decl::get_first_non_implicit_parm) (function_decl::clone): Adjust. (equals): Adjust the overload for function_type. (struct class_or_union::priv): Define new type. (class::priv::{declaration_, definition_of_declaration_, member_types_, data_members_, non_static_data_members_, member_functions_, mem_fns_map_, member_function_templates_, member_class_templates_, is_declaration_only_}): Move these data member into class_or_union::priv. (class_priv::{mark_as_being_compared, unmark_as_being_compared, comparison_started}): Moved these member functions to class_or_union::priv. (class_or_union::{class_or_union, traverse, ~class_or_union, add_member_decl, remove_member_decl, insert_member_type, add_member_type, get_size_in_bits, remove_member_type, get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, get_member_types, find_member_type, add_data_member, get_data_member, find_data_member, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates, has_no_member, insert_member_decl, operator==}): Define new member functions. (class_decl::{add_member_decl, remove_member_decl, insert_member_type, add_member_type, get_size_in_bits, remove_member_type, get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, get_member_types, find_member_type, add_data_member, get_data_member, find_data_member, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates): Move these member functions into class_or_union. (class_decl::{class_decl, get_definition_of_declaration, insert_member_decl, add_member_function, has_no_base_nor_member}): Adjust. (equals, copy_member_function): Define new overloads for class_or_union. (equals): Adjust the overload for class_decl. (method_decl::{method_decl, set_linkage_name, ~method_decl, get_type, set_scope}): Remove from the class_decl scope. (member_base::operator==, member_function_template::operator==): Likewise. (member_function_template::traverse) (member_class_template::operator==) (member_class_template::traverse): Likewise. (operator==, operator!=): Adjust the overlod for member_function_template_sptr. (is_method_decl, fixup_virtual_member_function) (set_member_is_static): Adjust. (virtual_member_function_less_than::operator()): Likewise. (union_decl::{union_decl, get_pretty_representation, operator==, traverse}): Define new member functions. (equals, copy_member_function): Define new overloads for union_decl. (hash_type_or_decl): Adjust. (ir_node_visitor::visit_{begin, end}): Adjust. Add new overloads for class_or_union* and union_decl*. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust these typedefs. (class class_or_union_diff): Declare new type. (class_diff): Adjust to make this inherit the new class_or_union_diff type. (class_diff::{get_priv, member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes}): These member functions got moved into -- and shared with -- class_or_union_diff class. (class union_diff): Declare new type. (typedef union_diff_sptr): New typedef. (compute_diff): New overload for union_diff (is_class_diff, is_union_diff): Declare new functions. * src/abg-comparison.cc (is_class_diff, is_union_diff): Define new functions. (compute_diff_for_types): Support union_decl. (represent): Adjust. (represent_data_member): Do not show offset information for data members of unions as all union data members are at offset 0. (struct class_or_union_diff::priv): New type. (class_or_union_diff::priv::{member_type_has_changed, subtype_changed_dm, member_class_tmpl_has_changed, get_deleted_non_static_data_members_number, get_inserted_non_static_data_members_number, count_filtered_subtype_changed_dm, count_filtered_changed_dm, count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns}): Define new member functions. (class_or_union_diff::{class_or_union_diff, finish_diff_type, lookup_tables_empty, lookup_tables_empty, ensure_lookup_tables_populated, allocate_priv_data, get_priv, ~class_or_union_diff, first_class_or_union, second_class_or_union, member_types_changes, member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fns_changes, changed_member_fns, member_fns_changes, inserted_member_fns, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes, member_class_tmpls_changes, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new member functions. (class_diff::priv::{member_types_changes_, data_members_changes, member_fn_tmpls_changes_, member_class_tmpls_changes_, deleted_member_types_, inserted_member_types_, changed_member_types_, sorted_changed_member_types_, deleted_data_members_, deleted_dm_by_offset_, inserted_data_members_, inserted_dm_by_offset_, subtype_changed_dm_, sorted_subtype_changed_dm_, changed_dm_, sorted_changed_dm_, deleted_member_functions_, inserted_member_functions_, changed_member_functions_, sorted_changed_member_functions_, deleted_member_class_tmpls_, inserted_member_class_tmpls_, changed_member_class_tmpls_, sorted_changed_member_class_tmpls_}): Move these data members into class_or_union_diff::priv. (class_diff::{clear_lookup_tables, lookup_tables_empty, ensure_lookup_tables_populate}): Adjust. (class_diff::allocate_priv_data): Define new function. (class_diff::priv::{count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns, chain_into_hierarchy, class_diff}): Likewise. (class_diff::{member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes}): These are deleted as they got moved to class_or_union_diff. (class_diff::report): Adjust. (union_diff::{clear_lookup_tables, lookup_tables_empty, ensure_lookup_tables_populated, allocate_priv_data, union_diff, finish_diff_type, first_union_decl, second_union_decl, get_pretty_representation, report}): Define new functions. (compute_diff): Define an overload for union_decl_sptr. (function_decl_diff::report): Adjust. (corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars): Adjust. (corpus_diff::report): Adjust. * src/abg-hash.cc (member_base::hash::operator) (member_function_template::hash::operator) (member_class_template::hash::operator): Move these out of the class_decl scope. (class_or_union::hash::operator): Define new member function. (class_decl::hash::operator): Adjust. (type_base::dynamic_hash::operator): Support hashing of union_decl. Adjust. * src/abg-suppression.cc (type_suppression::suppresses_diff): Adjust. * src/abg-dwarf-reader.cc (typedef die_class_or_union_map_type): Define new typedef. (read_context::{die_wip_classes_map_, alternate_die_wip_classes_map_, type_unit_die_wip_classes_map_): Make these data member have type die_class_or_union_map_type. (read_context::{lookup_type_from_die_offset, die_wip_classes_map, is_wip_class_die_offset, resolve_declaration_only_classes}): Adjust. (finish_member_function_reading, build_class_type_and_add_to_ir) (build_function_type, build_function_decl, build_reference_type) (type_is_suppressed, build_function_decl) (maybe_canonicalize_type, maybe_set_member_type_access_specifier): Adjust. (build_union_type_and_add_to_ir): Define new static function. (build_ir_node_from_die): Support DW_TAG_union_type DIE tag. * src/abg-reader.cc (handle_element_node): Handle union_decl. (build_function_decl, build_function_decl_if_not_suppressed): Adjust. (build_union_decl_if_not_suppressed, build_union_decl) (handle_union_decl): Define new functions. (build_class_decl): Adjust. * src/abg-writer.cc (record_decl_only_type_as_emitted): Adjust. (write_decl): Adjust. Support writting union_decl type. p (write_class_decl_opening_tag, write_class_decl): Adjust. Call the new write_class_or_union_is_declaration_only. (write_union_decl_opening_tag, write_union_decl): Define new static functions. (write_member_tpe): Support writting union decl. * tests/test-diff-dwarf.cc (in_out_specs): Add new tests for this union type support. * tests/data/test-diff-dwarf/libtest37-union-v0.so: New test input. * tests/data/test-diff-dwarf/libtest37-union-v1.so: Likewise. * tests/data/test-diff-dwarf/libtest38-union-v0.so: Likewise. * tests/data/test-diff-dwarf/libtest38-union-v1.so: Likewise. * tests/data/test-diff-dwarf/libtest39-union-v0.so: Likewise. * tests/data/test-diff-dwarf/libtest39-union-v1.so: Likewise. * tests/data/test-diff-dwarf/test37-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test38-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test39-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test37-union-v0.cc: Source code for new test input. * tests/data/test-diff-dwarf/test37-union-v1.cc: Likewise. * tests/data/test-diff-dwarf/test38-union-v0.cc: Likewise. * tests/data/test-diff-dwarf/test38-union-v1.cc: Likewise. * tests/data/test-diff-dwarf/test39-union-v0.cc: Likewise. * tests/data/test-diff-dwarf/test39-union-v1.cc: Likewise. * tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi: Update test reference. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-read-dwarf/libtest23.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-15 00:16:46 +00:00
union_decl*
is_union_type(const type_or_decl_base*);
union_decl_sptr
is_union_type(const type_or_decl_base_sptr&);
Support union types This patch makes Libabigail understand C and C++ union types. It defines a new class abigail::ir::union_decl to represent the declaration of a union type. It also defines a new type abigail::comparison::union_diff to represent the changes between two union types. The patch then adds facilities to read union types from DWARF and abixml and also to write union types into the abixml format. As union types and class types have a lot in common, the patch tries very hard to share code between the abigail::ir::class_decl and abigail::ir::union_decl. To do so, a new class abigail::ir::class_or_union is created. It's the base class for both abigai::ir::class_decl and abigail::ir::union_decl. Its data members and methods represent the set of data and behaviour that are common to classes and unions. A lot of code and data that were initially in abigail::ir::class_decl got moved into the new abigail::ir::class_or_union class. Similary, the patch creates a new class abigail::comparison::class_or_union_diff that is a base class for both the existing class abigail::comparison::class_diff and the newly created class abigail::comparison::union_diff. The new class abigail::comparison::class_or_union_diff contains data and behaviour that are common to both union_diff and class_diff and that were previously in class_diff. The rest of the patch is mostly adjustment so that code that was supposed to work with class class_decl only can now work with class class_or_union when it makes sense. Similarly for class_diff and class_or_union_diff. The patch adds regression tests into the test suite and adjust many existing tests involving binaries that contain union types; the reference output of those tests now take union types into account. * include/abg-fwd.h (class_or_union, union_decl): Forward-declare new types. (is_class_or_union_type, is_union_type): Declare new functions. * include/abg-ir.h (method_type::class_type_): Make this be of class_or_union_wptr type. (method_type::method_type): Make the class_type parameter be of class_or_union_wptr type. (method_type::{g,s}et_class_type): Take or return a class_or_union_sptr. (member_base, method_decl, member_function_template) (member_class_template, member_base::hash) (member_function_template::hash, member_class_template::hash): Take these class types out of the class_decl scope. (is_method_decl): Adjust. (operator==, opertor!=): Adjust overloads for member_function_template_sptr and member_class_template_sptr. (class class_or_union): Declare new type. (class class_decl): Make this class inherit class_or_union class. (class_decl::{add_member_decl, insert_member_decl, remove_member_decl, set_size_in_bits, get_size_in_bits, get_alignment_in_bits, set_alignment_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, insert_member_type, add_member_type, remove_member_type, get_member_type, find_member_type, add_data_member, get_data_members, find_data_member, get_non_static_data_members, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates): Move these to the parent class class_or_union. (copy_member_function, equals): Add overloads for class_or_union. (struct class_or_union::hash): Declare new type. (class union_decl): Declare new type. (equals, copy_member_function): New overloads for class union_decl type. (ir_node_visitor::visit): Add new overloads for union_decl* and class_or_union*. * src/abg-ir.cc (get_member_function_is_ctor) (set_member_function_is_ctor, get_member_function_is_dtor) (set_member_function_is_dtor, get_member_function_is_const) (set_member_function_is_const, get_member_function_vtable_offset) (set_member_function_vtable_offset) (get_member_function_is_virtual, set_member_function_is_virtual) (maybe_update_types_lookup_map, get_location) (get_method_type_name, is_at_global_scope, is_at_class_scope): Adjust. (is_class_or_union_type, is_union_type): Define new functions. (type_base::get_canonical_type_for, maybe_adjust_canonical_type) (method_type::method_type, method_type::set_class_type) (function_decl::get_pretty_representation) (function_decl::get_first_non_implicit_parm) (function_decl::clone): Adjust. (equals): Adjust the overload for function_type. (struct class_or_union::priv): Define new type. (class::priv::{declaration_, definition_of_declaration_, member_types_, data_members_, non_static_data_members_, member_functions_, mem_fns_map_, member_function_templates_, member_class_templates_, is_declaration_only_}): Move these data member into class_or_union::priv. (class_priv::{mark_as_being_compared, unmark_as_being_compared, comparison_started}): Moved these member functions to class_or_union::priv. (class_or_union::{class_or_union, traverse, ~class_or_union, add_member_decl, remove_member_decl, insert_member_type, add_member_type, get_size_in_bits, remove_member_type, get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, get_member_types, find_member_type, add_data_member, get_data_member, find_data_member, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates, has_no_member, insert_member_decl, operator==}): Define new member functions. (class_decl::{add_member_decl, remove_member_decl, insert_member_type, add_member_type, get_size_in_bits, remove_member_type, get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits, get_is_declaration_only, set_is_declaration_only, set_definition_of_declaration, get_earlier_declaration, set_earlier_declaration, get_member_types, find_member_type, add_data_member, get_data_member, find_data_member, add_member_function, get_member_functions, find_member_function, add_member_function_template, get_member_function_templates, add_member_class_template, get_member_class_templates): Move these member functions into class_or_union. (class_decl::{class_decl, get_definition_of_declaration, insert_member_decl, add_member_function, has_no_base_nor_member}): Adjust. (equals, copy_member_function): Define new overloads for class_or_union. (equals): Adjust the overload for class_decl. (method_decl::{method_decl, set_linkage_name, ~method_decl, get_type, set_scope}): Remove from the class_decl scope. (member_base::operator==, member_function_template::operator==): Likewise. (member_function_template::traverse) (member_class_template::operator==) (member_class_template::traverse): Likewise. (operator==, operator!=): Adjust the overlod for member_function_template_sptr. (is_method_decl, fixup_virtual_member_function) (set_member_is_static): Adjust. (virtual_member_function_less_than::operator()): Likewise. (union_decl::{union_decl, get_pretty_representation, operator==, traverse}): Define new member functions. (equals, copy_member_function): Define new overloads for union_decl. (hash_type_or_decl): Adjust. (ir_node_visitor::visit_{begin, end}): Adjust. Add new overloads for class_or_union* and union_decl*. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust these typedefs. (class class_or_union_diff): Declare new type. (class_diff): Adjust to make this inherit the new class_or_union_diff type. (class_diff::{get_priv, member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes}): These member functions got moved into -- and shared with -- class_or_union_diff class. (class union_diff): Declare new type. (typedef union_diff_sptr): New typedef. (compute_diff): New overload for union_diff (is_class_diff, is_union_diff): Declare new functions. * src/abg-comparison.cc (is_class_diff, is_union_diff): Define new functions. (compute_diff_for_types): Support union_decl. (represent): Adjust. (represent_data_member): Do not show offset information for data members of unions as all union data members are at offset 0. (struct class_or_union_diff::priv): New type. (class_or_union_diff::priv::{member_type_has_changed, subtype_changed_dm, member_class_tmpl_has_changed, get_deleted_non_static_data_members_number, get_inserted_non_static_data_members_number, count_filtered_subtype_changed_dm, count_filtered_changed_dm, count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns}): Define new member functions. (class_or_union_diff::{class_or_union_diff, finish_diff_type, lookup_tables_empty, lookup_tables_empty, ensure_lookup_tables_populated, allocate_priv_data, get_priv, ~class_or_union_diff, first_class_or_union, second_class_or_union, member_types_changes, member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fns_changes, changed_member_fns, member_fns_changes, inserted_member_fns, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes, member_class_tmpls_changes, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new member functions. (class_diff::priv::{member_types_changes_, data_members_changes, member_fn_tmpls_changes_, member_class_tmpls_changes_, deleted_member_types_, inserted_member_types_, changed_member_types_, sorted_changed_member_types_, deleted_data_members_, deleted_dm_by_offset_, inserted_data_members_, inserted_dm_by_offset_, subtype_changed_dm_, sorted_subtype_changed_dm_, changed_dm_, sorted_changed_dm_, deleted_member_functions_, inserted_member_functions_, changed_member_functions_, sorted_changed_member_functions_, deleted_member_class_tmpls_, inserted_member_class_tmpls_, changed_member_class_tmpls_, sorted_changed_member_class_tmpls_}): Move these data members into class_or_union_diff::priv. (class_diff::{clear_lookup_tables, lookup_tables_empty, ensure_lookup_tables_populate}): Adjust. (class_diff::allocate_priv_data): Define new function. (class_diff::priv::{count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns, chain_into_hierarchy, class_diff}): Likewise. (class_diff::{member_types_changes, data_members_changes, inserted_data_members, deleted_data_members, member_fn_tmpls_changes, member_fn_tmpls_changes, member_class_tmpls_changes}): These are deleted as they got moved to class_or_union_diff. (class_diff::report): Adjust. (union_diff::{clear_lookup_tables, lookup_tables_empty, ensure_lookup_tables_populated, allocate_priv_data, union_diff, finish_diff_type, first_union_decl, second_union_decl, get_pretty_representation, report}): Define new functions. (compute_diff): Define an overload for union_decl_sptr. (function_decl_diff::report): Adjust. (corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars): Adjust. (corpus_diff::report): Adjust. * src/abg-hash.cc (member_base::hash::operator) (member_function_template::hash::operator) (member_class_template::hash::operator): Move these out of the class_decl scope. (class_or_union::hash::operator): Define new member function. (class_decl::hash::operator): Adjust. (type_base::dynamic_hash::operator): Support hashing of union_decl. Adjust. * src/abg-suppression.cc (type_suppression::suppresses_diff): Adjust. * src/abg-dwarf-reader.cc (typedef die_class_or_union_map_type): Define new typedef. (read_context::{die_wip_classes_map_, alternate_die_wip_classes_map_, type_unit_die_wip_classes_map_): Make these data member have type die_class_or_union_map_type. (read_context::{lookup_type_from_die_offset, die_wip_classes_map, is_wip_class_die_offset, resolve_declaration_only_classes}): Adjust. (finish_member_function_reading, build_class_type_and_add_to_ir) (build_function_type, build_function_decl, build_reference_type) (type_is_suppressed, build_function_decl) (maybe_canonicalize_type, maybe_set_member_type_access_specifier): Adjust. (build_union_type_and_add_to_ir): Define new static function. (build_ir_node_from_die): Support DW_TAG_union_type DIE tag. * src/abg-reader.cc (handle_element_node): Handle union_decl. (build_function_decl, build_function_decl_if_not_suppressed): Adjust. (build_union_decl_if_not_suppressed, build_union_decl) (handle_union_decl): Define new functions. (build_class_decl): Adjust. * src/abg-writer.cc (record_decl_only_type_as_emitted): Adjust. (write_decl): Adjust. Support writting union_decl type. p (write_class_decl_opening_tag, write_class_decl): Adjust. Call the new write_class_or_union_is_declaration_only. (write_union_decl_opening_tag, write_union_decl): Define new static functions. (write_member_tpe): Support writting union decl. * tests/test-diff-dwarf.cc (in_out_specs): Add new tests for this union type support. * tests/data/test-diff-dwarf/libtest37-union-v0.so: New test input. * tests/data/test-diff-dwarf/libtest37-union-v1.so: Likewise. * tests/data/test-diff-dwarf/libtest38-union-v0.so: Likewise. * tests/data/test-diff-dwarf/libtest38-union-v1.so: Likewise. * tests/data/test-diff-dwarf/libtest39-union-v0.so: Likewise. * tests/data/test-diff-dwarf/libtest39-union-v1.so: Likewise. * tests/data/test-diff-dwarf/test37-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test38-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test39-union-report-0.txt: Likewise. * tests/data/test-diff-dwarf/test37-union-v0.cc: Source code for new test input. * tests/data/test-diff-dwarf/test37-union-v1.cc: Likewise. * tests/data/test-diff-dwarf/test38-union-v0.cc: Likewise. * tests/data/test-diff-dwarf/test38-union-v1.cc: Likewise. * tests/data/test-diff-dwarf/test39-union-v0.cc: Likewise. * tests/data/test-diff-dwarf/test39-union-v1.cc: Likewise. * tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi: Update test reference. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-read-dwarf/libtest23.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-15 00:16:46 +00:00
class_decl_sptr
is_compatible_with_class_type(const type_base_sptr&);
Make strip_typedef() act on canonical types only strip_typedef(), when constructing new pointers, references and other composite types was building new types that weakly referred to their sub-types; for instance, a pointer type has a weak reference on its pointed-type. That means the referred-to type must be 'own' by something else. That means that strip_typedef() needs to create types which lifetime is "long enough". This patch ensures that strip_typedef() returns a canonical type; and we are sure that a canonical type is live during the entire life time of the libabigail library itself. So that means strip_typedef can only be used after types have been canonicalized. To that end, this patch changes is_class_type() to make it not strip typedefs. That way, is_class_type() can be used even when canonicalized types are not yet available. The patch then introduces a new is_compatible_with_class_type() function that strips typedef. The code of type_size_changed() that wanted to strip typedefs is then adjusted to use this new is_compatible_with_class_type() instead. * include/abg-fwd.h (is_compatible_with_class_type): Declare new function. (canonicalize): Move the declaration here, from ... * include/abg-ir.h (canonicalize): ... here. * src/abg-ir.cc (strip_typedef): Assert that the input type is canonicalized. Make sure that weak references are on canonicalized types. Make sure that the returned type is a canonical one. (canonicalize): Make this return the canonical type that it has computed. * src/abg-comp-filter.cc (type_size_changed): Use the new is_compatible_with_class_type() function, instead of is_class_type(). Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-19 10:30:43 +00:00
class_decl_sptr
is_compatible_with_class_type(const decl_base_sptr&);
pointer_type_def*
Cleanup some entry points in abg-fwd.h While looking at something else I came accross some interface cleanup opportunities, as usual. This patch honours some of those opportunities. * include/abg-fwd.h (add_decl_to_scope): Pass the scope smart pointer by reference. (is_member_type): pass the type smart pointer by reference. (is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. * include/abg-ir.h (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (scope_decl::{add_member_decl, insert_member_decl}): Pass the member smart pointer by reference. (scope_decl::remove_member_decl): Take a non-const smart pointer. (class_decl::add_member_decl): Pass the decl smart pointer by reference. (is_method_decl): Take pointer or reference to type_or_decl_base rather than function_decl. * src/abg-ir.cc (translation_unit::priv::corpus): Make this a pointer to non-const corpus. (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (translation_unit::get_global_scope): Adjust. (translation_unit::bind_function_type_life_time): Adjust. (type_or_decl_base::translation_unit): Make this a pointer to non-const translation_unit. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (is_member_type): pass the type smart pointer by reference. (scope_decl::{add_member_decl, insert_member_decl}): Take a reference to the member decl smart pointer. Adjust. (class_decl::add_member_decl): Likewise. (scope_decl::remove_member_decl): Take a non-const smart pointer. (add_decl_to_scope): Pass the scope smart pointer by reference. (is_decl, is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_method_decl, is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-31 11:26:22 +00:00
is_pointer_type(type_or_decl_base*);
Make type_has_non_canonicalized_subtype() tighter type_has_non_canonicalized_subtype() gives up too quickly. For instance, suppose it's looking a type 'foo'. If foo has no canonicalized type yet and has a data member which type is foo* (for instance), then type_has_non_canonicalized_subtype() just sees that type 'foo*' has no canonicalized type, and so it returns, saying that he found a non-canonicalized subtype for foo. In that case though, what type_has_non_canonicalized_subtype() should do is detect that foo* is a pointer to foo itself, so it shouldn't count as a non-canonicalized sub-type. It should keep going and look for other meaningful non-canonicalized sub-types. And this what this patch does. It changes the sub-type walker that type_has_non_canonicalized_subtype() uses, so that - it doesn't flag sub-types that refer to the type we are looking at as non-canonicalized sub-types. This is for sub-types that are combinations of pointers, references and typedefs. - it doesn't consider sub-types of member functions of the type we are looking at, unless that member function is virtual. The result is that more types are canonicalized early during DWARF reading, and so there are less types to store on the side for late canonicalization. This can have a big impact on, e.g, C++ libraries with tens of thousands of types. * include/abg-fwd.h (is_typedef, is_pointer_type) (is_reference_type): Declare new overloads. (peel_typedef_type): Renamed get_typedef_underlying_type into this. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Declare new functions. * src/abg-ir.cc (peel_typedef_type): Renamed get_typedef_underlying_type into this. (is_typedef, is_pointer_type, is_reference_type): Define new overloads. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Define new functions. (non_canonicalized_subtype_detector::has_non_canonical_type_): Make the type of this data member be a type_base*, not a bool. This is so that we can return the first non-canonicalized subtype of the type we are looking at. (non_canonicalized_subtype_detector::non_canonicalized_subtype_detector): Adjust the data member initialization. (non_canonicalized_subtype_detector::visit_begin): Add an overload for function_decl*, to avoid looking into non-virtual member functions. In the overload for type_base*, peel typedefs, pointers and reference of each sub-type that has no canonical type, to see if refers to the type we are actually walking. If yes, then keep going. (type_has_non_canonicalized_subtype): Return the non-canonicalized sub-type found. * src/abg-comparison.cc (type_suppression::suppresses_diff): Adjust for the get_typedef_underlying_type -> peel_typedef_type renaming. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-19 14:15:28 +00:00
const pointer_type_def*
Cleanup some entry points in abg-fwd.h While looking at something else I came accross some interface cleanup opportunities, as usual. This patch honours some of those opportunities. * include/abg-fwd.h (add_decl_to_scope): Pass the scope smart pointer by reference. (is_member_type): pass the type smart pointer by reference. (is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. * include/abg-ir.h (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (scope_decl::{add_member_decl, insert_member_decl}): Pass the member smart pointer by reference. (scope_decl::remove_member_decl): Take a non-const smart pointer. (class_decl::add_member_decl): Pass the decl smart pointer by reference. (is_method_decl): Take pointer or reference to type_or_decl_base rather than function_decl. * src/abg-ir.cc (translation_unit::priv::corpus): Make this a pointer to non-const corpus. (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (translation_unit::get_global_scope): Adjust. (translation_unit::bind_function_type_life_time): Adjust. (type_or_decl_base::translation_unit): Make this a pointer to non-const translation_unit. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (is_member_type): pass the type smart pointer by reference. (scope_decl::{add_member_decl, insert_member_decl}): Take a reference to the member decl smart pointer. Adjust. (class_decl::add_member_decl): Likewise. (scope_decl::remove_member_decl): Take a non-const smart pointer. (add_decl_to_scope): Pass the scope smart pointer by reference. (is_decl, is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_method_decl, is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-31 11:26:22 +00:00
is_pointer_type(const type_or_decl_base*);
Make type_has_non_canonicalized_subtype() tighter type_has_non_canonicalized_subtype() gives up too quickly. For instance, suppose it's looking a type 'foo'. If foo has no canonicalized type yet and has a data member which type is foo* (for instance), then type_has_non_canonicalized_subtype() just sees that type 'foo*' has no canonicalized type, and so it returns, saying that he found a non-canonicalized subtype for foo. In that case though, what type_has_non_canonicalized_subtype() should do is detect that foo* is a pointer to foo itself, so it shouldn't count as a non-canonicalized sub-type. It should keep going and look for other meaningful non-canonicalized sub-types. And this what this patch does. It changes the sub-type walker that type_has_non_canonicalized_subtype() uses, so that - it doesn't flag sub-types that refer to the type we are looking at as non-canonicalized sub-types. This is for sub-types that are combinations of pointers, references and typedefs. - it doesn't consider sub-types of member functions of the type we are looking at, unless that member function is virtual. The result is that more types are canonicalized early during DWARF reading, and so there are less types to store on the side for late canonicalization. This can have a big impact on, e.g, C++ libraries with tens of thousands of types. * include/abg-fwd.h (is_typedef, is_pointer_type) (is_reference_type): Declare new overloads. (peel_typedef_type): Renamed get_typedef_underlying_type into this. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Declare new functions. * src/abg-ir.cc (peel_typedef_type): Renamed get_typedef_underlying_type into this. (is_typedef, is_pointer_type, is_reference_type): Define new overloads. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Define new functions. (non_canonicalized_subtype_detector::has_non_canonical_type_): Make the type of this data member be a type_base*, not a bool. This is so that we can return the first non-canonicalized subtype of the type we are looking at. (non_canonicalized_subtype_detector::non_canonicalized_subtype_detector): Adjust the data member initialization. (non_canonicalized_subtype_detector::visit_begin): Add an overload for function_decl*, to avoid looking into non-virtual member functions. In the overload for type_base*, peel typedefs, pointers and reference of each sub-type that has no canonical type, to see if refers to the type we are actually walking. If yes, then keep going. (type_has_non_canonicalized_subtype): Return the non-canonicalized sub-type found. * src/abg-comparison.cc (type_suppression::suppresses_diff): Adjust for the get_typedef_underlying_type -> peel_typedef_type renaming. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-19 14:15:28 +00:00
pointer_type_def_sptr
is_pointer_type(const type_or_decl_base_sptr&);
reference_type_def*
Cleanup some entry points in abg-fwd.h While looking at something else I came accross some interface cleanup opportunities, as usual. This patch honours some of those opportunities. * include/abg-fwd.h (add_decl_to_scope): Pass the scope smart pointer by reference. (is_member_type): pass the type smart pointer by reference. (is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. * include/abg-ir.h (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (scope_decl::{add_member_decl, insert_member_decl}): Pass the member smart pointer by reference. (scope_decl::remove_member_decl): Take a non-const smart pointer. (class_decl::add_member_decl): Pass the decl smart pointer by reference. (is_method_decl): Take pointer or reference to type_or_decl_base rather than function_decl. * src/abg-ir.cc (translation_unit::priv::corpus): Make this a pointer to non-const corpus. (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (translation_unit::get_global_scope): Adjust. (translation_unit::bind_function_type_life_time): Adjust. (type_or_decl_base::translation_unit): Make this a pointer to non-const translation_unit. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (is_member_type): pass the type smart pointer by reference. (scope_decl::{add_member_decl, insert_member_decl}): Take a reference to the member decl smart pointer. Adjust. (class_decl::add_member_decl): Likewise. (scope_decl::remove_member_decl): Take a non-const smart pointer. (add_decl_to_scope): Pass the scope smart pointer by reference. (is_decl, is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_method_decl, is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-31 11:26:22 +00:00
is_reference_type(type_or_decl_base*);
Make type_has_non_canonicalized_subtype() tighter type_has_non_canonicalized_subtype() gives up too quickly. For instance, suppose it's looking a type 'foo'. If foo has no canonicalized type yet and has a data member which type is foo* (for instance), then type_has_non_canonicalized_subtype() just sees that type 'foo*' has no canonicalized type, and so it returns, saying that he found a non-canonicalized subtype for foo. In that case though, what type_has_non_canonicalized_subtype() should do is detect that foo* is a pointer to foo itself, so it shouldn't count as a non-canonicalized sub-type. It should keep going and look for other meaningful non-canonicalized sub-types. And this what this patch does. It changes the sub-type walker that type_has_non_canonicalized_subtype() uses, so that - it doesn't flag sub-types that refer to the type we are looking at as non-canonicalized sub-types. This is for sub-types that are combinations of pointers, references and typedefs. - it doesn't consider sub-types of member functions of the type we are looking at, unless that member function is virtual. The result is that more types are canonicalized early during DWARF reading, and so there are less types to store on the side for late canonicalization. This can have a big impact on, e.g, C++ libraries with tens of thousands of types. * include/abg-fwd.h (is_typedef, is_pointer_type) (is_reference_type): Declare new overloads. (peel_typedef_type): Renamed get_typedef_underlying_type into this. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Declare new functions. * src/abg-ir.cc (peel_typedef_type): Renamed get_typedef_underlying_type into this. (is_typedef, is_pointer_type, is_reference_type): Define new overloads. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Define new functions. (non_canonicalized_subtype_detector::has_non_canonical_type_): Make the type of this data member be a type_base*, not a bool. This is so that we can return the first non-canonicalized subtype of the type we are looking at. (non_canonicalized_subtype_detector::non_canonicalized_subtype_detector): Adjust the data member initialization. (non_canonicalized_subtype_detector::visit_begin): Add an overload for function_decl*, to avoid looking into non-virtual member functions. In the overload for type_base*, peel typedefs, pointers and reference of each sub-type that has no canonical type, to see if refers to the type we are actually walking. If yes, then keep going. (type_has_non_canonicalized_subtype): Return the non-canonicalized sub-type found. * src/abg-comparison.cc (type_suppression::suppresses_diff): Adjust for the get_typedef_underlying_type -> peel_typedef_type renaming. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-19 14:15:28 +00:00
const reference_type_def*
Cleanup some entry points in abg-fwd.h While looking at something else I came accross some interface cleanup opportunities, as usual. This patch honours some of those opportunities. * include/abg-fwd.h (add_decl_to_scope): Pass the scope smart pointer by reference. (is_member_type): pass the type smart pointer by reference. (is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. * include/abg-ir.h (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (scope_decl::{add_member_decl, insert_member_decl}): Pass the member smart pointer by reference. (scope_decl::remove_member_decl): Take a non-const smart pointer. (class_decl::add_member_decl): Pass the decl smart pointer by reference. (is_method_decl): Take pointer or reference to type_or_decl_base rather than function_decl. * src/abg-ir.cc (translation_unit::priv::corpus): Make this a pointer to non-const corpus. (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (translation_unit::get_global_scope): Adjust. (translation_unit::bind_function_type_life_time): Adjust. (type_or_decl_base::translation_unit): Make this a pointer to non-const translation_unit. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (is_member_type): pass the type smart pointer by reference. (scope_decl::{add_member_decl, insert_member_decl}): Take a reference to the member decl smart pointer. Adjust. (class_decl::add_member_decl): Likewise. (scope_decl::remove_member_decl): Take a non-const smart pointer. (add_decl_to_scope): Pass the scope smart pointer by reference. (is_decl, is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_method_decl, is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-31 11:26:22 +00:00
is_reference_type(const type_or_decl_base*);
Make type_has_non_canonicalized_subtype() tighter type_has_non_canonicalized_subtype() gives up too quickly. For instance, suppose it's looking a type 'foo'. If foo has no canonicalized type yet and has a data member which type is foo* (for instance), then type_has_non_canonicalized_subtype() just sees that type 'foo*' has no canonicalized type, and so it returns, saying that he found a non-canonicalized subtype for foo. In that case though, what type_has_non_canonicalized_subtype() should do is detect that foo* is a pointer to foo itself, so it shouldn't count as a non-canonicalized sub-type. It should keep going and look for other meaningful non-canonicalized sub-types. And this what this patch does. It changes the sub-type walker that type_has_non_canonicalized_subtype() uses, so that - it doesn't flag sub-types that refer to the type we are looking at as non-canonicalized sub-types. This is for sub-types that are combinations of pointers, references and typedefs. - it doesn't consider sub-types of member functions of the type we are looking at, unless that member function is virtual. The result is that more types are canonicalized early during DWARF reading, and so there are less types to store on the side for late canonicalization. This can have a big impact on, e.g, C++ libraries with tens of thousands of types. * include/abg-fwd.h (is_typedef, is_pointer_type) (is_reference_type): Declare new overloads. (peel_typedef_type): Renamed get_typedef_underlying_type into this. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Declare new functions. * src/abg-ir.cc (peel_typedef_type): Renamed get_typedef_underlying_type into this. (is_typedef, is_pointer_type, is_reference_type): Define new overloads. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Define new functions. (non_canonicalized_subtype_detector::has_non_canonical_type_): Make the type of this data member be a type_base*, not a bool. This is so that we can return the first non-canonicalized subtype of the type we are looking at. (non_canonicalized_subtype_detector::non_canonicalized_subtype_detector): Adjust the data member initialization. (non_canonicalized_subtype_detector::visit_begin): Add an overload for function_decl*, to avoid looking into non-virtual member functions. In the overload for type_base*, peel typedefs, pointers and reference of each sub-type that has no canonical type, to see if refers to the type we are actually walking. If yes, then keep going. (type_has_non_canonicalized_subtype): Return the non-canonicalized sub-type found. * src/abg-comparison.cc (type_suppression::suppresses_diff): Adjust for the get_typedef_underlying_type -> peel_typedef_type renaming. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-19 14:15:28 +00:00
reference_type_def_sptr
is_reference_type(const type_or_decl_base_sptr&);
Make determining of compatible types complete Until now, two types that are different were considered compatible if one type is a typedef of the other. This is useful because two different types, if compatible, are not ABI-incompatible. This patch extends the concept of compatible types to types which might have sub-types that are typedefs of each others, including function types. Note implementing this required that I fixed various other things left and right. Like style fixes, crash avoiding fixes, etc. * include/abg-fwd.h (is_reference_type, is_function_type) (is_method_type): Declare new predicates. * include/abg-ir.h (class qualified_type_def): Pimpl this class. (qualified_type_def::qualified_type_def): Use the convenience type_base_sptr typedef. (qualified_type_def::{get_cv_quals, set_cv_quals}): Use the qualified_type_def::CV type rather than char. (qualified_type_def::get_underlying_type): Use the convenience type_base_sptr typedef. (pointer_type_def::pointer_type_def): Likewise. (function_decl::parameter::parameter): Add a new constructor. * src/abg-ir.cc (is_reference_type, is_function_type) (is_method_type): Define new predicates. (class qualified_type_def::priv): Define this new private type, for the purpose of Pimpl-ifying the qualified_type_def class. (qualified_type_def::{qualified_type_def, build_name, get_cv_quals_string_prefix, get_underlying_type}): Adjust for the purpose of Pimpl-ifying the qualified_type_def class. (equals): In the qualified_type_def, reference_type_def overloads, trust the fact that we have operator== overload for the type_base_sptr. This avoids crashes for when the (possible) underlying type is null. (pointer_type_def::operator==): Likewise. (strip_typedef): Make this recursively strip typedefs from sub-types. (types_are_compatible): Handle null types. (qualified_type_def::{get_cv_quals, set_cv_quals}): Handle qualified_type_def::CV rather than char. (pointer_type_def::pointer_type_def): Use the convenience type_base_sptr typedef. * include/abg-comparison.h (distinct_diff::compatible_child_diff): Declare new member function. * src/abg-comparison.cc (distinct_diff::compatible_child_diff): Define new member function. (distinct_diff::chain_into_hierarchy): Chain the compatible child diff node that might be present. (distinct_diff::report): Now when a distinct diff carries a compatible change, mention it in the report. * src/abg-comp-filter.cc (is_compatible_change): A compatible change can now involve types that are not typedefs. Only their sub-types need to be involved with typedef-ness. * tests/data/test-diff-dwarf/test{2,4,5}-report.txt: Adjust. * tests/data/test-diff-filter/libtest21-compatible-vars-v0.so: New test data input. * tests/data/test-diff-filter/libtest21-compatible-vars-v1.so: Likewise. * tests/data/test-diff-filter/test21-compatible-vars-report-0.txt Likewise. * tests/data/test-diff-filter/test21-compatible-vars-report-1.txt Likewise. * tests/data/test-diff-filter/test21-compatible-vars-v0.cc: Source code for the first data input binary above. * tests/data/test-diff-filter/test21-compatible-vars-v1.cc: Source code for the second data input binary above. * tests/data/test-diff-filter/libtest22-compatible-fns-v0.so: New test data input. * tests/data/test-diff-filter/libtest22-compatible-fns-v1.so Likewise. * tests/data/test-diff-filter/test22-compatible-fns-report-0.txt: New test data input. * tests/data/test-diff-filter/test22-compatible-fns-report-1.txt: Likewise. * tests/data/test-diff-filter/test22-compatible-fns-v0.c: Source code for the first test data input binary above. * tests/data/test-diff-filter/test22-compatible-fns-v1.c: Source code for the second test data input binary above. * tests/data/Makefile.am: Add the new test input data to source distribution. * tests/test-diff-filter.cc (in_out_specs): Add the new test data input above to the list of test data this harness has to be run over. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-12-10 06:25:01 +00:00
const type_base*
is_void_pointer_type(const type_base*);
qualified_type_def*
Cleanup some entry points in abg-fwd.h While looking at something else I came accross some interface cleanup opportunities, as usual. This patch honours some of those opportunities. * include/abg-fwd.h (add_decl_to_scope): Pass the scope smart pointer by reference. (is_member_type): pass the type smart pointer by reference. (is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. * include/abg-ir.h (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (scope_decl::{add_member_decl, insert_member_decl}): Pass the member smart pointer by reference. (scope_decl::remove_member_decl): Take a non-const smart pointer. (class_decl::add_member_decl): Pass the decl smart pointer by reference. (is_method_decl): Take pointer or reference to type_or_decl_base rather than function_decl. * src/abg-ir.cc (translation_unit::priv::corpus): Make this a pointer to non-const corpus. (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (translation_unit::get_global_scope): Adjust. (translation_unit::bind_function_type_life_time): Adjust. (type_or_decl_base::translation_unit): Make this a pointer to non-const translation_unit. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (is_member_type): pass the type smart pointer by reference. (scope_decl::{add_member_decl, insert_member_decl}): Take a reference to the member decl smart pointer. Adjust. (class_decl::add_member_decl): Likewise. (scope_decl::remove_member_decl): Take a non-const smart pointer. (add_decl_to_scope): Pass the scope smart pointer by reference. (is_decl, is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_method_decl, is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-31 11:26:22 +00:00
is_qualified_type(const type_or_decl_base*);
qualified_type_def_sptr
is_qualified_type(const type_or_decl_base_sptr&);
Bug 21296 - Reporting diff of const ref against non-const ref aborts References are always const. But then GCC sometimes emits DWARF that represents a const reference. This leads, for instance, to a given reference to be considered as different from that same reference wraps into a const qualifier. Which is wrong. Libabigail then represents those const references as a particular case of a "no-op qualifier". That is, a qualifier that should be ignored by the comparison code. In the case of this issue, the comparison engine considers the two references (const and non-const) to be equal, but the reporting code forgets to ignore the ignore no-op qualifier and thus (wrongly) considers the two references as being different. That inconsistency leads to an abort of the process. This patch moves the code that ignores no-op qualifiers at a lower level of the comparison engine so that whenever function parameters are compared, no-op qualifiers are ignored as they should. * include/abg-fwd.h (look_through_no_op_qualified_type): Declare new function. * src/abg-ir.cc (look_through_no_op_qualified_type): Define it. (compute_diff_for_types): Use the new look_through_no_op_qualified_type here rather than open-coding it. (equals): In the overload for function_decl::parameter, use the new look_through_no_op_qualified_type function. * tests/data/test-diff-dwarf/test40-PR21296-clanggcc.cc: Source code of the new test inputs. * tests/data/test-diff-dwarf/test40-PR21296-clanggcc-report0.txt: New test input. * tests/data/test-diff-dwarf/test40-PR21296-libgcc.so: New binary test input. * tests/data/test-diff-dwarf/test40-PR21296-libclang.so: Likewise. * tests/test-diff-dwarf.cc (in_out_specs): Add the new test inputs to the test harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-24 11:04:53 +00:00
type_base_sptr
look_through_no_op_qualified_type(const shared_ptr<type_base>& t);
function_type_sptr
is_function_type(const type_or_decl_base_sptr&);
Make determining of compatible types complete Until now, two types that are different were considered compatible if one type is a typedef of the other. This is useful because two different types, if compatible, are not ABI-incompatible. This patch extends the concept of compatible types to types which might have sub-types that are typedefs of each others, including function types. Note implementing this required that I fixed various other things left and right. Like style fixes, crash avoiding fixes, etc. * include/abg-fwd.h (is_reference_type, is_function_type) (is_method_type): Declare new predicates. * include/abg-ir.h (class qualified_type_def): Pimpl this class. (qualified_type_def::qualified_type_def): Use the convenience type_base_sptr typedef. (qualified_type_def::{get_cv_quals, set_cv_quals}): Use the qualified_type_def::CV type rather than char. (qualified_type_def::get_underlying_type): Use the convenience type_base_sptr typedef. (pointer_type_def::pointer_type_def): Likewise. (function_decl::parameter::parameter): Add a new constructor. * src/abg-ir.cc (is_reference_type, is_function_type) (is_method_type): Define new predicates. (class qualified_type_def::priv): Define this new private type, for the purpose of Pimpl-ifying the qualified_type_def class. (qualified_type_def::{qualified_type_def, build_name, get_cv_quals_string_prefix, get_underlying_type}): Adjust for the purpose of Pimpl-ifying the qualified_type_def class. (equals): In the qualified_type_def, reference_type_def overloads, trust the fact that we have operator== overload for the type_base_sptr. This avoids crashes for when the (possible) underlying type is null. (pointer_type_def::operator==): Likewise. (strip_typedef): Make this recursively strip typedefs from sub-types. (types_are_compatible): Handle null types. (qualified_type_def::{get_cv_quals, set_cv_quals}): Handle qualified_type_def::CV rather than char. (pointer_type_def::pointer_type_def): Use the convenience type_base_sptr typedef. * include/abg-comparison.h (distinct_diff::compatible_child_diff): Declare new member function. * src/abg-comparison.cc (distinct_diff::compatible_child_diff): Define new member function. (distinct_diff::chain_into_hierarchy): Chain the compatible child diff node that might be present. (distinct_diff::report): Now when a distinct diff carries a compatible change, mention it in the report. * src/abg-comp-filter.cc (is_compatible_change): A compatible change can now involve types that are not typedefs. Only their sub-types need to be involved with typedef-ness. * tests/data/test-diff-dwarf/test{2,4,5}-report.txt: Adjust. * tests/data/test-diff-filter/libtest21-compatible-vars-v0.so: New test data input. * tests/data/test-diff-filter/libtest21-compatible-vars-v1.so: Likewise. * tests/data/test-diff-filter/test21-compatible-vars-report-0.txt Likewise. * tests/data/test-diff-filter/test21-compatible-vars-report-1.txt Likewise. * tests/data/test-diff-filter/test21-compatible-vars-v0.cc: Source code for the first data input binary above. * tests/data/test-diff-filter/test21-compatible-vars-v1.cc: Source code for the second data input binary above. * tests/data/test-diff-filter/libtest22-compatible-fns-v0.so: New test data input. * tests/data/test-diff-filter/libtest22-compatible-fns-v1.so Likewise. * tests/data/test-diff-filter/test22-compatible-fns-report-0.txt: New test data input. * tests/data/test-diff-filter/test22-compatible-fns-report-1.txt: Likewise. * tests/data/test-diff-filter/test22-compatible-fns-v0.c: Source code for the first test data input binary above. * tests/data/test-diff-filter/test22-compatible-fns-v1.c: Source code for the second test data input binary above. * tests/data/Makefile.am: Add the new test input data to source distribution. * tests/test-diff-filter.cc (in_out_specs): Add the new test data input above to the list of test data this harness has to be run over. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-12-10 06:25:01 +00:00
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
function_type*
Cleanup some entry points in abg-fwd.h While looking at something else I came accross some interface cleanup opportunities, as usual. This patch honours some of those opportunities. * include/abg-fwd.h (add_decl_to_scope): Pass the scope smart pointer by reference. (is_member_type): pass the type smart pointer by reference. (is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. * include/abg-ir.h (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (scope_decl::{add_member_decl, insert_member_decl}): Pass the member smart pointer by reference. (scope_decl::remove_member_decl): Take a non-const smart pointer. (class_decl::add_member_decl): Pass the decl smart pointer by reference. (is_method_decl): Take pointer or reference to type_or_decl_base rather than function_decl. * src/abg-ir.cc (translation_unit::priv::corpus): Make this a pointer to non-const corpus. (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (translation_unit::get_global_scope): Adjust. (translation_unit::bind_function_type_life_time): Adjust. (type_or_decl_base::translation_unit): Make this a pointer to non-const translation_unit. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (is_member_type): pass the type smart pointer by reference. (scope_decl::{add_member_decl, insert_member_decl}): Take a reference to the member decl smart pointer. Adjust. (class_decl::add_member_decl): Likewise. (scope_decl::remove_member_decl): Take a non-const smart pointer. (add_decl_to_scope): Pass the scope smart pointer by reference. (is_decl, is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_method_decl, is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-31 11:26:22 +00:00
is_function_type(type_or_decl_base*);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
const function_type*
Cleanup some entry points in abg-fwd.h While looking at something else I came accross some interface cleanup opportunities, as usual. This patch honours some of those opportunities. * include/abg-fwd.h (add_decl_to_scope): Pass the scope smart pointer by reference. (is_member_type): pass the type smart pointer by reference. (is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. * include/abg-ir.h (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (scope_decl::{add_member_decl, insert_member_decl}): Pass the member smart pointer by reference. (scope_decl::remove_member_decl): Take a non-const smart pointer. (class_decl::add_member_decl): Pass the decl smart pointer by reference. (is_method_decl): Take pointer or reference to type_or_decl_base rather than function_decl. * src/abg-ir.cc (translation_unit::priv::corpus): Make this a pointer to non-const corpus. (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (translation_unit::get_global_scope): Adjust. (translation_unit::bind_function_type_life_time): Adjust. (type_or_decl_base::translation_unit): Make this a pointer to non-const translation_unit. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (is_member_type): pass the type smart pointer by reference. (scope_decl::{add_member_decl, insert_member_decl}): Take a reference to the member decl smart pointer. Adjust. (class_decl::add_member_decl): Likewise. (scope_decl::remove_member_decl): Take a non-const smart pointer. (add_decl_to_scope): Pass the scope smart pointer by reference. (is_decl, is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_method_decl, is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-31 11:26:22 +00:00
is_function_type(const type_or_decl_base*);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
method_type_sptr
is_method_type(const type_or_decl_base_sptr&);
Make determining of compatible types complete Until now, two types that are different were considered compatible if one type is a typedef of the other. This is useful because two different types, if compatible, are not ABI-incompatible. This patch extends the concept of compatible types to types which might have sub-types that are typedefs of each others, including function types. Note implementing this required that I fixed various other things left and right. Like style fixes, crash avoiding fixes, etc. * include/abg-fwd.h (is_reference_type, is_function_type) (is_method_type): Declare new predicates. * include/abg-ir.h (class qualified_type_def): Pimpl this class. (qualified_type_def::qualified_type_def): Use the convenience type_base_sptr typedef. (qualified_type_def::{get_cv_quals, set_cv_quals}): Use the qualified_type_def::CV type rather than char. (qualified_type_def::get_underlying_type): Use the convenience type_base_sptr typedef. (pointer_type_def::pointer_type_def): Likewise. (function_decl::parameter::parameter): Add a new constructor. * src/abg-ir.cc (is_reference_type, is_function_type) (is_method_type): Define new predicates. (class qualified_type_def::priv): Define this new private type, for the purpose of Pimpl-ifying the qualified_type_def class. (qualified_type_def::{qualified_type_def, build_name, get_cv_quals_string_prefix, get_underlying_type}): Adjust for the purpose of Pimpl-ifying the qualified_type_def class. (equals): In the qualified_type_def, reference_type_def overloads, trust the fact that we have operator== overload for the type_base_sptr. This avoids crashes for when the (possible) underlying type is null. (pointer_type_def::operator==): Likewise. (strip_typedef): Make this recursively strip typedefs from sub-types. (types_are_compatible): Handle null types. (qualified_type_def::{get_cv_quals, set_cv_quals}): Handle qualified_type_def::CV rather than char. (pointer_type_def::pointer_type_def): Use the convenience type_base_sptr typedef. * include/abg-comparison.h (distinct_diff::compatible_child_diff): Declare new member function. * src/abg-comparison.cc (distinct_diff::compatible_child_diff): Define new member function. (distinct_diff::chain_into_hierarchy): Chain the compatible child diff node that might be present. (distinct_diff::report): Now when a distinct diff carries a compatible change, mention it in the report. * src/abg-comp-filter.cc (is_compatible_change): A compatible change can now involve types that are not typedefs. Only their sub-types need to be involved with typedef-ness. * tests/data/test-diff-dwarf/test{2,4,5}-report.txt: Adjust. * tests/data/test-diff-filter/libtest21-compatible-vars-v0.so: New test data input. * tests/data/test-diff-filter/libtest21-compatible-vars-v1.so: Likewise. * tests/data/test-diff-filter/test21-compatible-vars-report-0.txt Likewise. * tests/data/test-diff-filter/test21-compatible-vars-report-1.txt Likewise. * tests/data/test-diff-filter/test21-compatible-vars-v0.cc: Source code for the first data input binary above. * tests/data/test-diff-filter/test21-compatible-vars-v1.cc: Source code for the second data input binary above. * tests/data/test-diff-filter/libtest22-compatible-fns-v0.so: New test data input. * tests/data/test-diff-filter/libtest22-compatible-fns-v1.so Likewise. * tests/data/test-diff-filter/test22-compatible-fns-report-0.txt: New test data input. * tests/data/test-diff-filter/test22-compatible-fns-report-1.txt: Likewise. * tests/data/test-diff-filter/test22-compatible-fns-v0.c: Source code for the first test data input binary above. * tests/data/test-diff-filter/test22-compatible-fns-v1.c: Source code for the second test data input binary above. * tests/data/Makefile.am: Add the new test input data to source distribution. * tests/test-diff-filter.cc (in_out_specs): Add the new test data input above to the list of test data this harness has to be run over. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-12-10 06:25:01 +00:00
const method_type*
Cleanup some entry points in abg-fwd.h While looking at something else I came accross some interface cleanup opportunities, as usual. This patch honours some of those opportunities. * include/abg-fwd.h (add_decl_to_scope): Pass the scope smart pointer by reference. (is_member_type): pass the type smart pointer by reference. (is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. * include/abg-ir.h (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (scope_decl::{add_member_decl, insert_member_decl}): Pass the member smart pointer by reference. (scope_decl::remove_member_decl): Take a non-const smart pointer. (class_decl::add_member_decl): Pass the decl smart pointer by reference. (is_method_decl): Take pointer or reference to type_or_decl_base rather than function_decl. * src/abg-ir.cc (translation_unit::priv::corpus): Make this a pointer to non-const corpus. (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (translation_unit::get_global_scope): Adjust. (translation_unit::bind_function_type_life_time): Adjust. (type_or_decl_base::translation_unit): Make this a pointer to non-const translation_unit. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (is_member_type): pass the type smart pointer by reference. (scope_decl::{add_member_decl, insert_member_decl}): Take a reference to the member decl smart pointer. Adjust. (class_decl::add_member_decl): Likewise. (scope_decl::remove_member_decl): Take a non-const smart pointer. (add_decl_to_scope): Pass the scope smart pointer by reference. (is_decl, is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_method_decl, is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-31 11:26:22 +00:00
is_method_type(const type_or_decl_base*);
method_type*
Cleanup some entry points in abg-fwd.h While looking at something else I came accross some interface cleanup opportunities, as usual. This patch honours some of those opportunities. * include/abg-fwd.h (add_decl_to_scope): Pass the scope smart pointer by reference. (is_member_type): pass the type smart pointer by reference. (is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. * include/abg-ir.h (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (scope_decl::{add_member_decl, insert_member_decl}): Pass the member smart pointer by reference. (scope_decl::remove_member_decl): Take a non-const smart pointer. (class_decl::add_member_decl): Pass the decl smart pointer by reference. (is_method_decl): Take pointer or reference to type_or_decl_base rather than function_decl. * src/abg-ir.cc (translation_unit::priv::corpus): Make this a pointer to non-const corpus. (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (translation_unit::get_global_scope): Adjust. (translation_unit::bind_function_type_life_time): Adjust. (type_or_decl_base::translation_unit): Make this a pointer to non-const translation_unit. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (is_member_type): pass the type smart pointer by reference. (scope_decl::{add_member_decl, insert_member_decl}): Take a reference to the member decl smart pointer. Adjust. (class_decl::add_member_decl): Likewise. (scope_decl::remove_member_decl): Take a non-const smart pointer. (add_decl_to_scope): Pass the scope smart pointer by reference. (is_decl, is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_method_decl, is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-31 11:26:22 +00:00
is_method_type(type_or_decl_base*);
class_or_union_sptr
look_through_decl_only_class(const class_or_union&);
Allow selective resolution of class declaration 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>
2017-05-17 08:19:30 +00:00
class_or_union_sptr
look_through_decl_only_class(class_or_union_sptr);
var_decl*
is_var_decl(const type_or_decl_base*);
var_decl_sptr
is_var_decl(const type_or_decl_base_sptr&);
namespace_decl_sptr
is_namespace(const decl_base_sptr&);
namespace_decl*
Bug 19025 - abixml writer forgets to emit some member types When a member type (a type that is a member of a class) M is referenced by some types emitted by abixml, but the context of M (the class type which M is a member of) is not itself referenced by any ABI artifact, then abixml forgets to emit the context of M and thus M itself. With this patch, when the abixml writer has emitted almost all ABI artifacts for the current translation unit, it looks for types that have been referenced by the emitted ABI artifacts, but that haven't been emitted themselves. It then emits those referenced-but-not-emitted types, and makes sure their contexts are emitted as well. * include/abg-fwd.h (is_namespace): Fix prototype. * src/abg-writer.cc (struct type_ptr_comp_functor): New internal type. (sort_type_ptr_map): New static function. (write_context::m_referenced_types_map): Renamed m_referenced_fntypes_map data member into this. (write_context::get_referenced_types): New member function. (write_context::record_type_as_referenced): Renamed record_fntype_as_referenced member function into this. Adjust. (write_context::type_is_referenced): Renamed fntype_is_referenced into this. (write_context::clear_referenced_types_map): Renamed clear_referenced_fntypes_map member function into this. Adjust. (write_decl_in_scope): New static function. (write_translation_unit): Use it here to emit types that are referenced by other types in the TU, but that are not emitted. Adjust. (write_pointer_type_def, write_reference_type_def) (write_typedef_decl): Record the underlying types referenced by the emitted types as being, well, referenced. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so: New test binary input. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: New reference output of the binary input above. * tests/data/Makefile.am: Add the new test material above to the source distribution. * tests/test-read-dwarf.cc (in_out_spec): Add the new test inputs. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-08 10:57:04 +00:00
is_namespace(const decl_base*);
bool
is_template_parm_composition_type(const decl_base_sptr);
bool
is_template_decl(const decl_base_sptr);
bool
is_function_template_pattern(const decl_base_sptr);
decl_base_sptr
insert_decl_into_scope(decl_base_sptr,
vector<decl_base_sptr >::iterator,
Support reading namespaces * include/abg-fwd.h (get_global_scope): Return a const global_scope. Add a new overload that takes a naked pointer as parm. (insert_decl_into_scope, get_top_most_scope_under): Declare new entry points. * include/abg-ir.h (class decl_base, class scope_decl): Add insert_decl_into_scope as a friend of these classes. (scope_decl::{insert_decl_into_scope, find_iterator_for_member}): Declare new member. (scope_decl::get_member_decls): New non-const overload. * src/abg-dwarf-reader.cc (build_translation_unit): Remove the "recurse" parameter. Adjust the call to build_ir_node_from_die to read just public decls that are at namespace scope. Anything else should be dropped unless it's needed to emitting the public namespace-level decls. (build_namespace_decl_and_add_to_ir) (canonicalize_and_insert_type_into_ir): Define new static functions. (build_corpus): Adjust ad build_translation_unit doesn't have the "recurse" parameter anymore. (canonicalize_and_add_type_to_ir): Make this static. Fix comments. (build_ir_node_from_die): Take a new "only_public_decl" parameter. For DW_TAG_base_type case, use the new canonicalize_and_insert_type_into_ir to insert the type at the right place in the global scope making sure it is seen before the current scope. For pointer, references and qualified types, use canonicalize_and_insert_type_into_ir to add the type at the same scope as its underlying type. Handle DW_TAG_{namespace,module} using the new build_namespace_decl_and_add_to_ir function. Add some vertical spaces and some assertions. * src/abg-ir.cc (scope_decl::add_member_decl): Use scope_decl_sptr typedef. (scope_decl::{insert_member_decl,find_iterator_for_member}): Define new methods. (insert_decl_into_scope, get_top_most_scope_under): Define new functions. (get_global_scope): Constify the return type. (get_translation_unit): Adjust as get_global_scope now returns a const. * src/abg-reader.cc (get_translation_unit): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2013-12-12 14:40:52 +00:00
scope_decl*);
decl_base_sptr
insert_decl_into_scope(decl_base_sptr,
vector<decl_base_sptr >::iterator,
scope_decl_sptr);
Support reading namespaces * include/abg-fwd.h (get_global_scope): Return a const global_scope. Add a new overload that takes a naked pointer as parm. (insert_decl_into_scope, get_top_most_scope_under): Declare new entry points. * include/abg-ir.h (class decl_base, class scope_decl): Add insert_decl_into_scope as a friend of these classes. (scope_decl::{insert_decl_into_scope, find_iterator_for_member}): Declare new member. (scope_decl::get_member_decls): New non-const overload. * src/abg-dwarf-reader.cc (build_translation_unit): Remove the "recurse" parameter. Adjust the call to build_ir_node_from_die to read just public decls that are at namespace scope. Anything else should be dropped unless it's needed to emitting the public namespace-level decls. (build_namespace_decl_and_add_to_ir) (canonicalize_and_insert_type_into_ir): Define new static functions. (build_corpus): Adjust ad build_translation_unit doesn't have the "recurse" parameter anymore. (canonicalize_and_add_type_to_ir): Make this static. Fix comments. (build_ir_node_from_die): Take a new "only_public_decl" parameter. For DW_TAG_base_type case, use the new canonicalize_and_insert_type_into_ir to insert the type at the right place in the global scope making sure it is seen before the current scope. For pointer, references and qualified types, use canonicalize_and_insert_type_into_ir to add the type at the same scope as its underlying type. Handle DW_TAG_{namespace,module} using the new build_namespace_decl_and_add_to_ir function. Add some vertical spaces and some assertions. * src/abg-ir.cc (scope_decl::add_member_decl): Use scope_decl_sptr typedef. (scope_decl::{insert_member_decl,find_iterator_for_member}): Define new methods. (insert_decl_into_scope, get_top_most_scope_under): Define new functions. (get_global_scope): Constify the return type. (get_translation_unit): Adjust as get_global_scope now returns a const. * src/abg-reader.cc (get_translation_unit): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2013-12-12 14:40:52 +00:00
Use the same representation for member and non-member types * include/abg-fwd.h (is_at_class_scope): Add new oveloads. (as_non_member_type, as_non_member_class_decl): Remove. (has_scope, is_member_decl, is_member_type): New function declarations. (get_member_is_static, set_member_is_static): Likewise. * include/abg-ir.h (enum access_specifier): Move to the abigail:: namespace, from ... (class_decl::access_specifier): ... here. (class context_rel): New type. (decl_base::hash_as_member): New hasher. (decl_base::context_): Change the type of this to context_rel_sptr. (decl_base::get_context_rel): New protected getter. (decl_base::get_scope): Move this out-of-line. (class_decl::member_type): Remove. (class_decl::member_types): Adjust this typedef. (class_decl::{insert,add}_member_type): Make these take a type_base_sptr now. (class_decl::add_member_type): Change the overload that returned a member_type to return a type_base_sptr. (get_member_access_specifier, set_member_access_specifier): New function declarations. * include/abg-comparison.h (class member_type_diff): Remove. (compute_diff): Remove the overload for member_type_diff. * src/abg-comparison.cc (compute_diff_for_types): Adjust for the removal of class_decl::member_type. (maybe_report_diff_for_class_members): New static function. (report_name_size_and_alignment_changes): Do not report a name change just because of a struct -> class change. ({var_diff, enum_diff, function_decl_diff}::report): Use the new maybe_report_diff_for_class_members. (class_diff::report): Adjust for the removal of class_decl::member_type. Use the new maybe_report_diff_for_class_members. (class member_diff): Remove. * src/abg-dwarf-reader.cc (die_access_specifier) (get_scope_for_die, build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_function_decl) (build_ir_node_from_die): Adjust. * abg-hash.cc (struct decl_base::hash_as_member): Define. ({scope_type_decl, enum_type_decl, typedef_decl}::hash::operator()): Use the decl_base::hash_as_member. * src/abg-ir.cc (decl_base::decl_base): Adjust. (decl_base::get_scope): New out-of-line getter. (decl_base::{operator==, set_scope): Adjust. (has_scope, is_member_decl, is_member_type) (get_member_access_specifier, set_member_access_specifier) (get_member_is_static, set_member_is_static, is_at_class_scope): New function definitions. (as_non_member_type, as_non_member_class_decl): Remove. (get_node_name): Adjust. (class_decl::{class_decl, set_earlier_declaration, insert_member_decl, insert_member_type, add_member_type): Likewise. (class_decl::member_type::*) Remove. * src/abg-reader.cc (read_access, build_qualified_type_decl) (build_reference_type_def, build_typedef_decl) (build_class_decl): Adjust. * src/abg-writer.cc (write_access, write_member_type) (write_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-13 10:13:54 +00:00
bool
has_scope(const decl_base&);
bool
has_scope(const decl_base_sptr);
Use the same representation for member and non-member types * include/abg-fwd.h (is_at_class_scope): Add new oveloads. (as_non_member_type, as_non_member_class_decl): Remove. (has_scope, is_member_decl, is_member_type): New function declarations. (get_member_is_static, set_member_is_static): Likewise. * include/abg-ir.h (enum access_specifier): Move to the abigail:: namespace, from ... (class_decl::access_specifier): ... here. (class context_rel): New type. (decl_base::hash_as_member): New hasher. (decl_base::context_): Change the type of this to context_rel_sptr. (decl_base::get_context_rel): New protected getter. (decl_base::get_scope): Move this out-of-line. (class_decl::member_type): Remove. (class_decl::member_types): Adjust this typedef. (class_decl::{insert,add}_member_type): Make these take a type_base_sptr now. (class_decl::add_member_type): Change the overload that returned a member_type to return a type_base_sptr. (get_member_access_specifier, set_member_access_specifier): New function declarations. * include/abg-comparison.h (class member_type_diff): Remove. (compute_diff): Remove the overload for member_type_diff. * src/abg-comparison.cc (compute_diff_for_types): Adjust for the removal of class_decl::member_type. (maybe_report_diff_for_class_members): New static function. (report_name_size_and_alignment_changes): Do not report a name change just because of a struct -> class change. ({var_diff, enum_diff, function_decl_diff}::report): Use the new maybe_report_diff_for_class_members. (class_diff::report): Adjust for the removal of class_decl::member_type. Use the new maybe_report_diff_for_class_members. (class member_diff): Remove. * src/abg-dwarf-reader.cc (die_access_specifier) (get_scope_for_die, build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_function_decl) (build_ir_node_from_die): Adjust. * abg-hash.cc (struct decl_base::hash_as_member): Define. ({scope_type_decl, enum_type_decl, typedef_decl}::hash::operator()): Use the decl_base::hash_as_member. * src/abg-ir.cc (decl_base::decl_base): Adjust. (decl_base::get_scope): New out-of-line getter. (decl_base::{operator==, set_scope): Adjust. (has_scope, is_member_decl, is_member_type) (get_member_access_specifier, set_member_access_specifier) (get_member_is_static, set_member_is_static, is_at_class_scope): New function definitions. (as_non_member_type, as_non_member_class_decl): Remove. (get_node_name): Adjust. (class_decl::{class_decl, set_earlier_declaration, insert_member_decl, insert_member_type, add_member_type): Likewise. (class_decl::member_type::*) Remove. * src/abg-reader.cc (read_access, build_qualified_type_decl) (build_reference_type_def, build_typedef_decl) (build_class_decl): Adjust. * src/abg-writer.cc (write_access, write_member_type) (write_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-13 10:13:54 +00:00
bool
is_member_decl(const decl_base_sptr);
Use the same representation for member and non-member types * include/abg-fwd.h (is_at_class_scope): Add new oveloads. (as_non_member_type, as_non_member_class_decl): Remove. (has_scope, is_member_decl, is_member_type): New function declarations. (get_member_is_static, set_member_is_static): Likewise. * include/abg-ir.h (enum access_specifier): Move to the abigail:: namespace, from ... (class_decl::access_specifier): ... here. (class context_rel): New type. (decl_base::hash_as_member): New hasher. (decl_base::context_): Change the type of this to context_rel_sptr. (decl_base::get_context_rel): New protected getter. (decl_base::get_scope): Move this out-of-line. (class_decl::member_type): Remove. (class_decl::member_types): Adjust this typedef. (class_decl::{insert,add}_member_type): Make these take a type_base_sptr now. (class_decl::add_member_type): Change the overload that returned a member_type to return a type_base_sptr. (get_member_access_specifier, set_member_access_specifier): New function declarations. * include/abg-comparison.h (class member_type_diff): Remove. (compute_diff): Remove the overload for member_type_diff. * src/abg-comparison.cc (compute_diff_for_types): Adjust for the removal of class_decl::member_type. (maybe_report_diff_for_class_members): New static function. (report_name_size_and_alignment_changes): Do not report a name change just because of a struct -> class change. ({var_diff, enum_diff, function_decl_diff}::report): Use the new maybe_report_diff_for_class_members. (class_diff::report): Adjust for the removal of class_decl::member_type. Use the new maybe_report_diff_for_class_members. (class member_diff): Remove. * src/abg-dwarf-reader.cc (die_access_specifier) (get_scope_for_die, build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_function_decl) (build_ir_node_from_die): Adjust. * abg-hash.cc (struct decl_base::hash_as_member): Define. ({scope_type_decl, enum_type_decl, typedef_decl}::hash::operator()): Use the decl_base::hash_as_member. * src/abg-ir.cc (decl_base::decl_base): Adjust. (decl_base::get_scope): New out-of-line getter. (decl_base::{operator==, set_scope): Adjust. (has_scope, is_member_decl, is_member_type) (get_member_access_specifier, set_member_access_specifier) (get_member_is_static, set_member_is_static, is_at_class_scope): New function definitions. (as_non_member_type, as_non_member_class_decl): Remove. (get_node_name): Adjust. (class_decl::{class_decl, set_earlier_declaration, insert_member_decl, insert_member_type, add_member_type): Likewise. (class_decl::member_type::*) Remove. * src/abg-reader.cc (read_access, build_qualified_type_decl) (build_reference_type_def, build_typedef_decl) (build_class_decl): Adjust. * src/abg-writer.cc (write_access, write_member_type) (write_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-13 10:13:54 +00:00
bool
is_member_decl(const decl_base*);
bool
is_member_decl(const decl_base&);
scope_decl*
is_scope_decl(decl_base*);
scope_decl_sptr
is_scope_decl(const decl_base_sptr&);
Cleanup some entry points in abg-fwd.h While looking at something else I came accross some interface cleanup opportunities, as usual. This patch honours some of those opportunities. * include/abg-fwd.h (add_decl_to_scope): Pass the scope smart pointer by reference. (is_member_type): pass the type smart pointer by reference. (is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. * include/abg-ir.h (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (scope_decl::{add_member_decl, insert_member_decl}): Pass the member smart pointer by reference. (scope_decl::remove_member_decl): Take a non-const smart pointer. (class_decl::add_member_decl): Pass the decl smart pointer by reference. (is_method_decl): Take pointer or reference to type_or_decl_base rather than function_decl. * src/abg-ir.cc (translation_unit::priv::corpus): Make this a pointer to non-const corpus. (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (translation_unit::get_global_scope): Adjust. (translation_unit::bind_function_type_life_time): Adjust. (type_or_decl_base::translation_unit): Make this a pointer to non-const translation_unit. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (is_member_type): pass the type smart pointer by reference. (scope_decl::{add_member_decl, insert_member_decl}): Take a reference to the member decl smart pointer. Adjust. (class_decl::add_member_decl): Likewise. (scope_decl::remove_member_decl): Take a non-const smart pointer. (add_decl_to_scope): Pass the scope smart pointer by reference. (is_decl, is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_method_decl, is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-31 11:26:22 +00:00
Use the same representation for member and non-member types * include/abg-fwd.h (is_at_class_scope): Add new oveloads. (as_non_member_type, as_non_member_class_decl): Remove. (has_scope, is_member_decl, is_member_type): New function declarations. (get_member_is_static, set_member_is_static): Likewise. * include/abg-ir.h (enum access_specifier): Move to the abigail:: namespace, from ... (class_decl::access_specifier): ... here. (class context_rel): New type. (decl_base::hash_as_member): New hasher. (decl_base::context_): Change the type of this to context_rel_sptr. (decl_base::get_context_rel): New protected getter. (decl_base::get_scope): Move this out-of-line. (class_decl::member_type): Remove. (class_decl::member_types): Adjust this typedef. (class_decl::{insert,add}_member_type): Make these take a type_base_sptr now. (class_decl::add_member_type): Change the overload that returned a member_type to return a type_base_sptr. (get_member_access_specifier, set_member_access_specifier): New function declarations. * include/abg-comparison.h (class member_type_diff): Remove. (compute_diff): Remove the overload for member_type_diff. * src/abg-comparison.cc (compute_diff_for_types): Adjust for the removal of class_decl::member_type. (maybe_report_diff_for_class_members): New static function. (report_name_size_and_alignment_changes): Do not report a name change just because of a struct -> class change. ({var_diff, enum_diff, function_decl_diff}::report): Use the new maybe_report_diff_for_class_members. (class_diff::report): Adjust for the removal of class_decl::member_type. Use the new maybe_report_diff_for_class_members. (class member_diff): Remove. * src/abg-dwarf-reader.cc (die_access_specifier) (get_scope_for_die, build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_function_decl) (build_ir_node_from_die): Adjust. * abg-hash.cc (struct decl_base::hash_as_member): Define. ({scope_type_decl, enum_type_decl, typedef_decl}::hash::operator()): Use the decl_base::hash_as_member. * src/abg-ir.cc (decl_base::decl_base): Adjust. (decl_base::get_scope): New out-of-line getter. (decl_base::{operator==, set_scope): Adjust. (has_scope, is_member_decl, is_member_type) (get_member_access_specifier, set_member_access_specifier) (get_member_is_static, set_member_is_static, is_at_class_scope): New function definitions. (as_non_member_type, as_non_member_class_decl): Remove. (get_node_name): Adjust. (class_decl::{class_decl, set_earlier_declaration, insert_member_decl, insert_member_type, add_member_type): Likewise. (class_decl::member_type::*) Remove. * src/abg-reader.cc (read_access, build_qualified_type_decl) (build_reference_type_def, build_typedef_decl) (build_class_decl): Adjust. * src/abg-writer.cc (write_access, write_member_type) (write_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-13 10:13:54 +00:00
bool
is_member_type(const type_base_sptr&);
Use the same representation for member and non-member types * include/abg-fwd.h (is_at_class_scope): Add new oveloads. (as_non_member_type, as_non_member_class_decl): Remove. (has_scope, is_member_decl, is_member_type): New function declarations. (get_member_is_static, set_member_is_static): Likewise. * include/abg-ir.h (enum access_specifier): Move to the abigail:: namespace, from ... (class_decl::access_specifier): ... here. (class context_rel): New type. (decl_base::hash_as_member): New hasher. (decl_base::context_): Change the type of this to context_rel_sptr. (decl_base::get_context_rel): New protected getter. (decl_base::get_scope): Move this out-of-line. (class_decl::member_type): Remove. (class_decl::member_types): Adjust this typedef. (class_decl::{insert,add}_member_type): Make these take a type_base_sptr now. (class_decl::add_member_type): Change the overload that returned a member_type to return a type_base_sptr. (get_member_access_specifier, set_member_access_specifier): New function declarations. * include/abg-comparison.h (class member_type_diff): Remove. (compute_diff): Remove the overload for member_type_diff. * src/abg-comparison.cc (compute_diff_for_types): Adjust for the removal of class_decl::member_type. (maybe_report_diff_for_class_members): New static function. (report_name_size_and_alignment_changes): Do not report a name change just because of a struct -> class change. ({var_diff, enum_diff, function_decl_diff}::report): Use the new maybe_report_diff_for_class_members. (class_diff::report): Adjust for the removal of class_decl::member_type. Use the new maybe_report_diff_for_class_members. (class member_diff): Remove. * src/abg-dwarf-reader.cc (die_access_specifier) (get_scope_for_die, build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_function_decl) (build_ir_node_from_die): Adjust. * abg-hash.cc (struct decl_base::hash_as_member): Define. ({scope_type_decl, enum_type_decl, typedef_decl}::hash::operator()): Use the decl_base::hash_as_member. * src/abg-ir.cc (decl_base::decl_base): Adjust. (decl_base::get_scope): New out-of-line getter. (decl_base::{operator==, set_scope): Adjust. (has_scope, is_member_decl, is_member_type) (get_member_access_specifier, set_member_access_specifier) (get_member_is_static, set_member_is_static, is_at_class_scope): New function definitions. (as_non_member_type, as_non_member_class_decl): Remove. (get_node_name): Adjust. (class_decl::{class_decl, set_earlier_declaration, insert_member_decl, insert_member_type, add_member_type): Likewise. (class_decl::member_type::*) Remove. * src/abg-reader.cc (read_access, build_qualified_type_decl) (build_reference_type_def, build_typedef_decl) (build_class_decl): Adjust. * src/abg-writer.cc (write_access, write_member_type) (write_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-13 10:13:54 +00:00
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>
2019-11-13 10:04:18 +00:00
bool
is_user_defined_type(const type_base*);
bool
is_user_defined_type(const type_base_sptr&);
Prune types that are not ref'ed by public decls * include/abg-fwd.h (remove_decl_from_scope): Declare new function. * include/abg-ir.h (type_base_sptr, decl_base_sptr): Move these convenience typedef before the translation_unit declaration. (translation_unit::{mark_type_as_used, prune_unused_types}): Declare new methods. (decl_base::remove_member_decl): Likewise. (class_decl::{remove_member_decl, remove_member_type): Likewise. * src/abg-dwarf-reader.cc (die_decl_map_type): Change this map type so that the value is now a DIE offset, rather than a DIE. This is because many times the lifetime of DIEs is shorter than the one of the reader_context. Also, the die offset uniquely designates a physical DIE even if several different instances of logical DIE might point to it. (struct die_hash): Remove this as it's useless now that we store DIE offsets in the map. (build_translation_unit): Call build_ir_node_from_die w/o setting the called_from_public_decl flag. Prune the types that are not used by any public decls. (build_namespace_decl_and_add_to_ir): all build_ir_node_from_die w/o setting the called_from_public_decl flag. (build_ir_node_from_die): Change the only_public_decl flag into a called_from_public_decl flag. Mark types used by public decls as such. Adjust for the parm changes of build_qualified_type build_pointer_type_def, build_reference_type, and build_typedef_type. (build_qualified_type, build_pointer_type_def) (build_reference_type, build_typedef_type): Take a new called_from_public_decl. Pass it to build_ir_node_from_die. (build_var_decl): Call build_ir_node_from_die with the called_from_public_decl flag set to true to flag the types referenced by this variable as being used. (build_function_decl): Take a called_from_public_decl flag as well, as this function can now call build_function_decl itself to build a function decl out of the value of the DW_AT_specification attribute, for DIEs representing function definitions. Also, flag the types referenced by public functions are being used. * src/abg-ir.cc (translation_unit::priv::used_types_): New map for the used types. (translation_unit::{mark_type_as_used, prune_unused_types}): Define new methods. (scope_decl::remove_member_decl): Likewise. (remove_decl_from_scope): Define new function. (class_decl::{remove_member_decl, remove_member_type}): Define new methods. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2013-12-13 16:30:41 +00:00
void
remove_decl_from_scope(decl_base_sptr);
Prune types that are not ref'ed by public decls * include/abg-fwd.h (remove_decl_from_scope): Declare new function. * include/abg-ir.h (type_base_sptr, decl_base_sptr): Move these convenience typedef before the translation_unit declaration. (translation_unit::{mark_type_as_used, prune_unused_types}): Declare new methods. (decl_base::remove_member_decl): Likewise. (class_decl::{remove_member_decl, remove_member_type): Likewise. * src/abg-dwarf-reader.cc (die_decl_map_type): Change this map type so that the value is now a DIE offset, rather than a DIE. This is because many times the lifetime of DIEs is shorter than the one of the reader_context. Also, the die offset uniquely designates a physical DIE even if several different instances of logical DIE might point to it. (struct die_hash): Remove this as it's useless now that we store DIE offsets in the map. (build_translation_unit): Call build_ir_node_from_die w/o setting the called_from_public_decl flag. Prune the types that are not used by any public decls. (build_namespace_decl_and_add_to_ir): all build_ir_node_from_die w/o setting the called_from_public_decl flag. (build_ir_node_from_die): Change the only_public_decl flag into a called_from_public_decl flag. Mark types used by public decls as such. Adjust for the parm changes of build_qualified_type build_pointer_type_def, build_reference_type, and build_typedef_type. (build_qualified_type, build_pointer_type_def) (build_reference_type, build_typedef_type): Take a new called_from_public_decl. Pass it to build_ir_node_from_die. (build_var_decl): Call build_ir_node_from_die with the called_from_public_decl flag set to true to flag the types referenced by this variable as being used. (build_function_decl): Take a called_from_public_decl flag as well, as this function can now call build_function_decl itself to build a function decl out of the value of the DW_AT_specification attribute, for DIEs representing function definitions. Also, flag the types referenced by public functions are being used. * src/abg-ir.cc (translation_unit::priv::used_types_): New map for the used types. (translation_unit::{mark_type_as_used, prune_unused_types}): Define new methods. (scope_decl::remove_member_decl): Likewise. (remove_decl_from_scope): Define new function. (class_decl::{remove_member_decl, remove_member_type}): Define new methods. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2013-12-13 16:30:41 +00:00
Use the same representation for member and non-member types * include/abg-fwd.h (is_at_class_scope): Add new oveloads. (as_non_member_type, as_non_member_class_decl): Remove. (has_scope, is_member_decl, is_member_type): New function declarations. (get_member_is_static, set_member_is_static): Likewise. * include/abg-ir.h (enum access_specifier): Move to the abigail:: namespace, from ... (class_decl::access_specifier): ... here. (class context_rel): New type. (decl_base::hash_as_member): New hasher. (decl_base::context_): Change the type of this to context_rel_sptr. (decl_base::get_context_rel): New protected getter. (decl_base::get_scope): Move this out-of-line. (class_decl::member_type): Remove. (class_decl::member_types): Adjust this typedef. (class_decl::{insert,add}_member_type): Make these take a type_base_sptr now. (class_decl::add_member_type): Change the overload that returned a member_type to return a type_base_sptr. (get_member_access_specifier, set_member_access_specifier): New function declarations. * include/abg-comparison.h (class member_type_diff): Remove. (compute_diff): Remove the overload for member_type_diff. * src/abg-comparison.cc (compute_diff_for_types): Adjust for the removal of class_decl::member_type. (maybe_report_diff_for_class_members): New static function. (report_name_size_and_alignment_changes): Do not report a name change just because of a struct -> class change. ({var_diff, enum_diff, function_decl_diff}::report): Use the new maybe_report_diff_for_class_members. (class_diff::report): Adjust for the removal of class_decl::member_type. Use the new maybe_report_diff_for_class_members. (class member_diff): Remove. * src/abg-dwarf-reader.cc (die_access_specifier) (get_scope_for_die, build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_function_decl) (build_ir_node_from_die): Adjust. * abg-hash.cc (struct decl_base::hash_as_member): Define. ({scope_type_decl, enum_type_decl, typedef_decl}::hash::operator()): Use the decl_base::hash_as_member. * src/abg-ir.cc (decl_base::decl_base): Adjust. (decl_base::get_scope): New out-of-line getter. (decl_base::{operator==, set_scope): Adjust. (has_scope, is_member_decl, is_member_type) (get_member_access_specifier, set_member_access_specifier) (get_member_is_static, set_member_is_static, is_at_class_scope): New function definitions. (as_non_member_type, as_non_member_class_decl): Remove. (get_node_name): Adjust. (class_decl::{class_decl, set_earlier_declaration, insert_member_decl, insert_member_type, add_member_type): Likewise. (class_decl::member_type::*) Remove. * src/abg-reader.cc (read_access, build_qualified_type_decl) (build_reference_type_def, build_typedef_decl) (build_class_decl): Adjust. * src/abg-writer.cc (write_access, write_member_type) (write_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-13 10:13:54 +00:00
bool
get_member_is_static(const decl_base&);
Get rid of class_decl::data_member * include/abg-fwd.h (has_scope): Delete the overloads for type_base. (get_member_is_static): Add an overload for decl_base*. ({is,get,set}_data_member,{get_,set}_data_member_is_laid_out) ({get,set}_data_member_offset): New access declarations. * include/abg-ir.h (class context_rel): Move up. (decl_base::set_context_rel): New definition. (class dm_context_rel): New type. (decl_base::hash_as_member): Remove. (var_decl::set_scope): Declare new virtual member. (class_decl::data_member): Remove. (ir_node_visitor::visit): Remove the overload for class_decl::data_member. (represent_data_member): Remove the represent overload for class_decl::data_member into this. Make it take a var_decl. (represent): Change the overload that takes two class_decl::data_member take two var_decl. And adjust it. (class_diff::report): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload that takes a class_decl::data_member*. Adjust the overload that takes a var_decl to recognize (static) data members. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_ir_node_from_die): Adjust. * src/abg-hash.cc (var_decl::hash::operator()): Adjust. (class_decl::data_member::hash::operator()): Remove. (decl_base::hash::operator()): Take the context relationship in account here. (decl_base::hash_as_member::operator()): Remove. ({enum_type_decl,typedef_decl}::hash::operator()): Adjust. (class_decl::member_function::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (dm_context_rel::~dm_context_rel): New definition. (has_scope): Remove overload for type_base. (get_member_is_static): New overload for decl_base*. (is_data_member): New function definition. ({get,set}_data_member_{offset,is_laid_out}): Define new accessors. (var_decl::set_scope): Define new member function. Make this set a dm_context_rel as the context relationship. (var_decl::operator==): Adjust to take in account the new data member relationship. (class_decl::class_decl): Adjust. (class_decl::insert_member_decl): Adjust. (class_decl::add_data_member): Remove the overload for class_decl::data_member. (class_decl::add_data_member): Adjust the overload for var_decl. (operator==): Remove overload for class_decl::data_member*. (class_decl::data_member::operator==): Likewise. (ir_node_visitor::visit): Remove overload for class_decl::data_member. * src/abg-writer.cc (write_layout_offset, write_class_decl): Adjust. * tests/data/test-read-write/test20.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-19 19:36:55 +00:00
bool
get_member_is_static(const decl_base*);
Use the same representation for member and non-member types * include/abg-fwd.h (is_at_class_scope): Add new oveloads. (as_non_member_type, as_non_member_class_decl): Remove. (has_scope, is_member_decl, is_member_type): New function declarations. (get_member_is_static, set_member_is_static): Likewise. * include/abg-ir.h (enum access_specifier): Move to the abigail:: namespace, from ... (class_decl::access_specifier): ... here. (class context_rel): New type. (decl_base::hash_as_member): New hasher. (decl_base::context_): Change the type of this to context_rel_sptr. (decl_base::get_context_rel): New protected getter. (decl_base::get_scope): Move this out-of-line. (class_decl::member_type): Remove. (class_decl::member_types): Adjust this typedef. (class_decl::{insert,add}_member_type): Make these take a type_base_sptr now. (class_decl::add_member_type): Change the overload that returned a member_type to return a type_base_sptr. (get_member_access_specifier, set_member_access_specifier): New function declarations. * include/abg-comparison.h (class member_type_diff): Remove. (compute_diff): Remove the overload for member_type_diff. * src/abg-comparison.cc (compute_diff_for_types): Adjust for the removal of class_decl::member_type. (maybe_report_diff_for_class_members): New static function. (report_name_size_and_alignment_changes): Do not report a name change just because of a struct -> class change. ({var_diff, enum_diff, function_decl_diff}::report): Use the new maybe_report_diff_for_class_members. (class_diff::report): Adjust for the removal of class_decl::member_type. Use the new maybe_report_diff_for_class_members. (class member_diff): Remove. * src/abg-dwarf-reader.cc (die_access_specifier) (get_scope_for_die, build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_function_decl) (build_ir_node_from_die): Adjust. * abg-hash.cc (struct decl_base::hash_as_member): Define. ({scope_type_decl, enum_type_decl, typedef_decl}::hash::operator()): Use the decl_base::hash_as_member. * src/abg-ir.cc (decl_base::decl_base): Adjust. (decl_base::get_scope): New out-of-line getter. (decl_base::{operator==, set_scope): Adjust. (has_scope, is_member_decl, is_member_type) (get_member_access_specifier, set_member_access_specifier) (get_member_is_static, set_member_is_static, is_at_class_scope): New function definitions. (as_non_member_type, as_non_member_class_decl): Remove. (get_node_name): Adjust. (class_decl::{class_decl, set_earlier_declaration, insert_member_decl, insert_member_type, add_member_type): Likewise. (class_decl::member_type::*) Remove. * src/abg-reader.cc (read_access, build_qualified_type_decl) (build_reference_type_def, build_typedef_decl) (build_class_decl): Adjust. * src/abg-writer.cc (write_access, write_member_type) (write_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-13 10:13:54 +00:00
bool
get_member_is_static(const decl_base_sptr&);
Use the same representation for member and non-member types * include/abg-fwd.h (is_at_class_scope): Add new oveloads. (as_non_member_type, as_non_member_class_decl): Remove. (has_scope, is_member_decl, is_member_type): New function declarations. (get_member_is_static, set_member_is_static): Likewise. * include/abg-ir.h (enum access_specifier): Move to the abigail:: namespace, from ... (class_decl::access_specifier): ... here. (class context_rel): New type. (decl_base::hash_as_member): New hasher. (decl_base::context_): Change the type of this to context_rel_sptr. (decl_base::get_context_rel): New protected getter. (decl_base::get_scope): Move this out-of-line. (class_decl::member_type): Remove. (class_decl::member_types): Adjust this typedef. (class_decl::{insert,add}_member_type): Make these take a type_base_sptr now. (class_decl::add_member_type): Change the overload that returned a member_type to return a type_base_sptr. (get_member_access_specifier, set_member_access_specifier): New function declarations. * include/abg-comparison.h (class member_type_diff): Remove. (compute_diff): Remove the overload for member_type_diff. * src/abg-comparison.cc (compute_diff_for_types): Adjust for the removal of class_decl::member_type. (maybe_report_diff_for_class_members): New static function. (report_name_size_and_alignment_changes): Do not report a name change just because of a struct -> class change. ({var_diff, enum_diff, function_decl_diff}::report): Use the new maybe_report_diff_for_class_members. (class_diff::report): Adjust for the removal of class_decl::member_type. Use the new maybe_report_diff_for_class_members. (class member_diff): Remove. * src/abg-dwarf-reader.cc (die_access_specifier) (get_scope_for_die, build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_function_decl) (build_ir_node_from_die): Adjust. * abg-hash.cc (struct decl_base::hash_as_member): Define. ({scope_type_decl, enum_type_decl, typedef_decl}::hash::operator()): Use the decl_base::hash_as_member. * src/abg-ir.cc (decl_base::decl_base): Adjust. (decl_base::get_scope): New out-of-line getter. (decl_base::{operator==, set_scope): Adjust. (has_scope, is_member_decl, is_member_type) (get_member_access_specifier, set_member_access_specifier) (get_member_is_static, set_member_is_static, is_at_class_scope): New function definitions. (as_non_member_type, as_non_member_class_decl): Remove. (get_node_name): Adjust. (class_decl::{class_decl, set_earlier_declaration, insert_member_decl, insert_member_type, add_member_type): Likewise. (class_decl::member_type::*) Remove. * src/abg-reader.cc (read_access, build_qualified_type_decl) (build_reference_type_def, build_typedef_decl) (build_class_decl): Adjust. * src/abg-writer.cc (write_access, write_member_type) (write_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-13 10:13:54 +00:00
void
set_member_is_static(decl_base&, bool);
Use the same representation for member and non-member types * include/abg-fwd.h (is_at_class_scope): Add new oveloads. (as_non_member_type, as_non_member_class_decl): Remove. (has_scope, is_member_decl, is_member_type): New function declarations. (get_member_is_static, set_member_is_static): Likewise. * include/abg-ir.h (enum access_specifier): Move to the abigail:: namespace, from ... (class_decl::access_specifier): ... here. (class context_rel): New type. (decl_base::hash_as_member): New hasher. (decl_base::context_): Change the type of this to context_rel_sptr. (decl_base::get_context_rel): New protected getter. (decl_base::get_scope): Move this out-of-line. (class_decl::member_type): Remove. (class_decl::member_types): Adjust this typedef. (class_decl::{insert,add}_member_type): Make these take a type_base_sptr now. (class_decl::add_member_type): Change the overload that returned a member_type to return a type_base_sptr. (get_member_access_specifier, set_member_access_specifier): New function declarations. * include/abg-comparison.h (class member_type_diff): Remove. (compute_diff): Remove the overload for member_type_diff. * src/abg-comparison.cc (compute_diff_for_types): Adjust for the removal of class_decl::member_type. (maybe_report_diff_for_class_members): New static function. (report_name_size_and_alignment_changes): Do not report a name change just because of a struct -> class change. ({var_diff, enum_diff, function_decl_diff}::report): Use the new maybe_report_diff_for_class_members. (class_diff::report): Adjust for the removal of class_decl::member_type. Use the new maybe_report_diff_for_class_members. (class member_diff): Remove. * src/abg-dwarf-reader.cc (die_access_specifier) (get_scope_for_die, build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_function_decl) (build_ir_node_from_die): Adjust. * abg-hash.cc (struct decl_base::hash_as_member): Define. ({scope_type_decl, enum_type_decl, typedef_decl}::hash::operator()): Use the decl_base::hash_as_member. * src/abg-ir.cc (decl_base::decl_base): Adjust. (decl_base::get_scope): New out-of-line getter. (decl_base::{operator==, set_scope): Adjust. (has_scope, is_member_decl, is_member_type) (get_member_access_specifier, set_member_access_specifier) (get_member_is_static, set_member_is_static, is_at_class_scope): New function definitions. (as_non_member_type, as_non_member_class_decl): Remove. (get_node_name): Adjust. (class_decl::{class_decl, set_earlier_declaration, insert_member_decl, insert_member_type, add_member_type): Likewise. (class_decl::member_type::*) Remove. * src/abg-reader.cc (read_access, build_qualified_type_decl) (build_reference_type_def, build_typedef_decl) (build_class_decl): Adjust. * src/abg-writer.cc (write_access, write_member_type) (write_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-13 10:13:54 +00:00
void
set_member_is_static(const decl_base_sptr&, bool);
Use the same representation for member and non-member types * include/abg-fwd.h (is_at_class_scope): Add new oveloads. (as_non_member_type, as_non_member_class_decl): Remove. (has_scope, is_member_decl, is_member_type): New function declarations. (get_member_is_static, set_member_is_static): Likewise. * include/abg-ir.h (enum access_specifier): Move to the abigail:: namespace, from ... (class_decl::access_specifier): ... here. (class context_rel): New type. (decl_base::hash_as_member): New hasher. (decl_base::context_): Change the type of this to context_rel_sptr. (decl_base::get_context_rel): New protected getter. (decl_base::get_scope): Move this out-of-line. (class_decl::member_type): Remove. (class_decl::member_types): Adjust this typedef. (class_decl::{insert,add}_member_type): Make these take a type_base_sptr now. (class_decl::add_member_type): Change the overload that returned a member_type to return a type_base_sptr. (get_member_access_specifier, set_member_access_specifier): New function declarations. * include/abg-comparison.h (class member_type_diff): Remove. (compute_diff): Remove the overload for member_type_diff. * src/abg-comparison.cc (compute_diff_for_types): Adjust for the removal of class_decl::member_type. (maybe_report_diff_for_class_members): New static function. (report_name_size_and_alignment_changes): Do not report a name change just because of a struct -> class change. ({var_diff, enum_diff, function_decl_diff}::report): Use the new maybe_report_diff_for_class_members. (class_diff::report): Adjust for the removal of class_decl::member_type. Use the new maybe_report_diff_for_class_members. (class member_diff): Remove. * src/abg-dwarf-reader.cc (die_access_specifier) (get_scope_for_die, build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_function_decl) (build_ir_node_from_die): Adjust. * abg-hash.cc (struct decl_base::hash_as_member): Define. ({scope_type_decl, enum_type_decl, typedef_decl}::hash::operator()): Use the decl_base::hash_as_member. * src/abg-ir.cc (decl_base::decl_base): Adjust. (decl_base::get_scope): New out-of-line getter. (decl_base::{operator==, set_scope): Adjust. (has_scope, is_member_decl, is_member_type) (get_member_access_specifier, set_member_access_specifier) (get_member_is_static, set_member_is_static, is_at_class_scope): New function definitions. (as_non_member_type, as_non_member_class_decl): Remove. (get_node_name): Adjust. (class_decl::{class_decl, set_earlier_declaration, insert_member_decl, insert_member_type, add_member_type): Likewise. (class_decl::member_type::*) Remove. * src/abg-reader.cc (read_access, build_qualified_type_decl) (build_reference_type_def, build_typedef_decl) (build_class_decl): Adjust. * src/abg-writer.cc (write_access, write_member_type) (write_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-13 10:13:54 +00:00
Get rid of class_decl::data_member * include/abg-fwd.h (has_scope): Delete the overloads for type_base. (get_member_is_static): Add an overload for decl_base*. ({is,get,set}_data_member,{get_,set}_data_member_is_laid_out) ({get,set}_data_member_offset): New access declarations. * include/abg-ir.h (class context_rel): Move up. (decl_base::set_context_rel): New definition. (class dm_context_rel): New type. (decl_base::hash_as_member): Remove. (var_decl::set_scope): Declare new virtual member. (class_decl::data_member): Remove. (ir_node_visitor::visit): Remove the overload for class_decl::data_member. (represent_data_member): Remove the represent overload for class_decl::data_member into this. Make it take a var_decl. (represent): Change the overload that takes two class_decl::data_member take two var_decl. And adjust it. (class_diff::report): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload that takes a class_decl::data_member*. Adjust the overload that takes a var_decl to recognize (static) data members. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_ir_node_from_die): Adjust. * src/abg-hash.cc (var_decl::hash::operator()): Adjust. (class_decl::data_member::hash::operator()): Remove. (decl_base::hash::operator()): Take the context relationship in account here. (decl_base::hash_as_member::operator()): Remove. ({enum_type_decl,typedef_decl}::hash::operator()): Adjust. (class_decl::member_function::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (dm_context_rel::~dm_context_rel): New definition. (has_scope): Remove overload for type_base. (get_member_is_static): New overload for decl_base*. (is_data_member): New function definition. ({get,set}_data_member_{offset,is_laid_out}): Define new accessors. (var_decl::set_scope): Define new member function. Make this set a dm_context_rel as the context relationship. (var_decl::operator==): Adjust to take in account the new data member relationship. (class_decl::class_decl): Adjust. (class_decl::insert_member_decl): Adjust. (class_decl::add_data_member): Remove the overload for class_decl::data_member. (class_decl::add_data_member): Adjust the overload for var_decl. (operator==): Remove overload for class_decl::data_member*. (class_decl::data_member::operator==): Likewise. (ir_node_visitor::visit): Remove overload for class_decl::data_member. * src/abg-writer.cc (write_layout_offset, write_class_decl): Adjust. * tests/data/test-read-write/test20.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-19 19:36:55 +00:00
bool
is_data_member(const var_decl&);
Explicitely detect anonymous data member changes This patch detects when a data member becomes anonymous or when an anonymous data member becomes non anonymous and emits an explicit message. * include/abg-comp-filter.h (has_anonymous_data_member_change): Add new function declaration. * include/abg-fwd.h (is_data_member, is_anonymous_data_member): declare new overloads. * src/abg-comp-filter.cc (has_anonymous_data_member_change): Define new overloads. * src/abg-ir.cc (is_data_member, is_anonymous_data_member): Define new overloads. * src/abg-reporter-priv.cc (represent): In the var_diff overload, detect when we have anonymous data member changes and emit explicit error messages then. * tests/data/test-diff-dwarf/test45-anon-dm-change-report-0.txt: New test material. * tests/data/test-diff-dwarf/test45-anon-dm-change-v0.cc: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v0.o: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v1.cc: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v1.o: Likewise. * tests/data/Makefile.am: Add the new test material above to source distribution. * tests/test-diff-dwarf.cc (in_out_specs): Add the new test material above to the test harness. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-06-06 10:05:10 +00:00
var_decl*
is_data_member(const type_or_decl_base*);
Get rid of class_decl::data_member * include/abg-fwd.h (has_scope): Delete the overloads for type_base. (get_member_is_static): Add an overload for decl_base*. ({is,get,set}_data_member,{get_,set}_data_member_is_laid_out) ({get,set}_data_member_offset): New access declarations. * include/abg-ir.h (class context_rel): Move up. (decl_base::set_context_rel): New definition. (class dm_context_rel): New type. (decl_base::hash_as_member): Remove. (var_decl::set_scope): Declare new virtual member. (class_decl::data_member): Remove. (ir_node_visitor::visit): Remove the overload for class_decl::data_member. (represent_data_member): Remove the represent overload for class_decl::data_member into this. Make it take a var_decl. (represent): Change the overload that takes two class_decl::data_member take two var_decl. And adjust it. (class_diff::report): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload that takes a class_decl::data_member*. Adjust the overload that takes a var_decl to recognize (static) data members. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_ir_node_from_die): Adjust. * src/abg-hash.cc (var_decl::hash::operator()): Adjust. (class_decl::data_member::hash::operator()): Remove. (decl_base::hash::operator()): Take the context relationship in account here. (decl_base::hash_as_member::operator()): Remove. ({enum_type_decl,typedef_decl}::hash::operator()): Adjust. (class_decl::member_function::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (dm_context_rel::~dm_context_rel): New definition. (has_scope): Remove overload for type_base. (get_member_is_static): New overload for decl_base*. (is_data_member): New function definition. ({get,set}_data_member_{offset,is_laid_out}): Define new accessors. (var_decl::set_scope): Define new member function. Make this set a dm_context_rel as the context relationship. (var_decl::operator==): Adjust to take in account the new data member relationship. (class_decl::class_decl): Adjust. (class_decl::insert_member_decl): Adjust. (class_decl::add_data_member): Remove the overload for class_decl::data_member. (class_decl::add_data_member): Adjust the overload for var_decl. (operator==): Remove overload for class_decl::data_member*. (class_decl::data_member::operator==): Likewise. (ir_node_visitor::visit): Remove overload for class_decl::data_member. * src/abg-writer.cc (write_layout_offset, write_class_decl): Adjust. * tests/data/test-read-write/test20.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-19 19:36:55 +00:00
bool
is_data_member(const var_decl*);
Explicitely detect anonymous data member changes This patch detects when a data member becomes anonymous or when an anonymous data member becomes non anonymous and emits an explicit message. * include/abg-comp-filter.h (has_anonymous_data_member_change): Add new function declaration. * include/abg-fwd.h (is_data_member, is_anonymous_data_member): declare new overloads. * src/abg-comp-filter.cc (has_anonymous_data_member_change): Define new overloads. * src/abg-ir.cc (is_data_member, is_anonymous_data_member): Define new overloads. * src/abg-reporter-priv.cc (represent): In the var_diff overload, detect when we have anonymous data member changes and emit explicit error messages then. * tests/data/test-diff-dwarf/test45-anon-dm-change-report-0.txt: New test material. * tests/data/test-diff-dwarf/test45-anon-dm-change-v0.cc: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v0.o: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v1.cc: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v1.o: Likewise. * tests/data/Makefile.am: Add the new test material above to source distribution. * tests/test-diff-dwarf.cc (in_out_specs): Add the new test material above to the test harness. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-06-06 10:05:10 +00:00
var_decl_sptr
is_data_member(const type_or_decl_base_sptr&);
Get rid of class_decl::data_member * include/abg-fwd.h (has_scope): Delete the overloads for type_base. (get_member_is_static): Add an overload for decl_base*. ({is,get,set}_data_member,{get_,set}_data_member_is_laid_out) ({get,set}_data_member_offset): New access declarations. * include/abg-ir.h (class context_rel): Move up. (decl_base::set_context_rel): New definition. (class dm_context_rel): New type. (decl_base::hash_as_member): Remove. (var_decl::set_scope): Declare new virtual member. (class_decl::data_member): Remove. (ir_node_visitor::visit): Remove the overload for class_decl::data_member. (represent_data_member): Remove the represent overload for class_decl::data_member into this. Make it take a var_decl. (represent): Change the overload that takes two class_decl::data_member take two var_decl. And adjust it. (class_diff::report): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload that takes a class_decl::data_member*. Adjust the overload that takes a var_decl to recognize (static) data members. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_ir_node_from_die): Adjust. * src/abg-hash.cc (var_decl::hash::operator()): Adjust. (class_decl::data_member::hash::operator()): Remove. (decl_base::hash::operator()): Take the context relationship in account here. (decl_base::hash_as_member::operator()): Remove. ({enum_type_decl,typedef_decl}::hash::operator()): Adjust. (class_decl::member_function::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (dm_context_rel::~dm_context_rel): New definition. (has_scope): Remove overload for type_base. (get_member_is_static): New overload for decl_base*. (is_data_member): New function definition. ({get,set}_data_member_{offset,is_laid_out}): Define new accessors. (var_decl::set_scope): Define new member function. Make this set a dm_context_rel as the context relationship. (var_decl::operator==): Adjust to take in account the new data member relationship. (class_decl::class_decl): Adjust. (class_decl::insert_member_decl): Adjust. (class_decl::add_data_member): Remove the overload for class_decl::data_member. (class_decl::add_data_member): Adjust the overload for var_decl. (operator==): Remove overload for class_decl::data_member*. (class_decl::data_member::operator==): Likewise. (ir_node_visitor::visit): Remove overload for class_decl::data_member. * src/abg-writer.cc (write_layout_offset, write_class_decl): Adjust. * tests/data/test-read-write/test20.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-19 19:36:55 +00:00
bool
is_data_member(const var_decl_sptr);
Get rid of class_decl::data_member * include/abg-fwd.h (has_scope): Delete the overloads for type_base. (get_member_is_static): Add an overload for decl_base*. ({is,get,set}_data_member,{get_,set}_data_member_is_laid_out) ({get,set}_data_member_offset): New access declarations. * include/abg-ir.h (class context_rel): Move up. (decl_base::set_context_rel): New definition. (class dm_context_rel): New type. (decl_base::hash_as_member): Remove. (var_decl::set_scope): Declare new virtual member. (class_decl::data_member): Remove. (ir_node_visitor::visit): Remove the overload for class_decl::data_member. (represent_data_member): Remove the represent overload for class_decl::data_member into this. Make it take a var_decl. (represent): Change the overload that takes two class_decl::data_member take two var_decl. And adjust it. (class_diff::report): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload that takes a class_decl::data_member*. Adjust the overload that takes a var_decl to recognize (static) data members. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_ir_node_from_die): Adjust. * src/abg-hash.cc (var_decl::hash::operator()): Adjust. (class_decl::data_member::hash::operator()): Remove. (decl_base::hash::operator()): Take the context relationship in account here. (decl_base::hash_as_member::operator()): Remove. ({enum_type_decl,typedef_decl}::hash::operator()): Adjust. (class_decl::member_function::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (dm_context_rel::~dm_context_rel): New definition. (has_scope): Remove overload for type_base. (get_member_is_static): New overload for decl_base*. (is_data_member): New function definition. ({get,set}_data_member_{offset,is_laid_out}): Define new accessors. (var_decl::set_scope): Define new member function. Make this set a dm_context_rel as the context relationship. (var_decl::operator==): Adjust to take in account the new data member relationship. (class_decl::class_decl): Adjust. (class_decl::insert_member_decl): Adjust. (class_decl::add_data_member): Remove the overload for class_decl::data_member. (class_decl::add_data_member): Adjust the overload for var_decl. (operator==): Remove overload for class_decl::data_member*. (class_decl::data_member::operator==): Likewise. (ir_node_visitor::visit): Remove overload for class_decl::data_member. * src/abg-writer.cc (write_layout_offset, write_class_decl): Adjust. * tests/data/test-read-write/test20.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-19 19:36:55 +00:00
var_decl_sptr
is_data_member(const decl_base_sptr&);
Initial support of anonymous data members An anonymous data member is a data member of a struct or a union which has no name. The type of such data member is either a struct or a union. For instance: struct foo { int a; struct { // <-- this is an anonymous data member char a; char b; }; int c; }; In DWARF (as emitted by GCC at least), an anonymous data member is represented as a data member with an empty name. Libabigail sees it just fine, but then when representing *changes* to that kind of data member, it needs special treatment, otherwise users cannot make sense of the reports. This patch adds initial support to represent changes to anonymous data members. * include/abg-comparison.h (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Declare new functions. * include/abg-fwd.h (is_class_type): Declare new overload for type_or_decl_base&. (is_data_member): Declare new overload for decl_base*. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Declare new functions. (is_at_class_scope): Return the class or union scope. * include/abg-ir.h (var_decl::get_qualified_name): New virtual data member which overloads decl_base::get_qualified_name. * src/abg-comparison.cc (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Define new functions (leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous class or union diff nodes as diff nodes. * src/abg-ir.cc (is_data_member): Define new overload for decl_base*. (is_class_type, is_union_type): Define new overload for type_or_decl_base&. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Define new function overloads. (var_decl::get_qualified_name): Define new virtual member function. (is_at_class_scope): Return the class or union scope. (var_decl::get_pretty_representation): Support anonymous data members. (equals): In the overload for class_or_union_diff, mark data member textual representation changes as local changes. * src/abg-reporter-priv.cc (represent): In the overload for var_diff, support changes to anonymous data members. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted -- by offset -- data member changes before the ones that are sorted by other things. * tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so: New binary test input * tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt: New reference test outputs. * tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c: Source code of the new binary test output above. * tests/data/Makefile.am: Add the new test files above to the source distribution. * tests/data/test-annotate/libtest23.so.abi: Adjust test reference output. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-09 06:51:50 +00:00
var_decl*
is_data_member(const decl_base *);
Explicitely detect anonymous data member changes This patch detects when a data member becomes anonymous or when an anonymous data member becomes non anonymous and emits an explicit message. * include/abg-comp-filter.h (has_anonymous_data_member_change): Add new function declaration. * include/abg-fwd.h (is_data_member, is_anonymous_data_member): declare new overloads. * src/abg-comp-filter.cc (has_anonymous_data_member_change): Define new overloads. * src/abg-ir.cc (is_data_member, is_anonymous_data_member): Define new overloads. * src/abg-reporter-priv.cc (represent): In the var_diff overload, detect when we have anonymous data member changes and emit explicit error messages then. * tests/data/test-diff-dwarf/test45-anon-dm-change-report-0.txt: New test material. * tests/data/test-diff-dwarf/test45-anon-dm-change-v0.cc: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v0.o: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v1.cc: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v1.o: Likewise. * tests/data/Makefile.am: Add the new test material above to source distribution. * tests/test-diff-dwarf.cc (in_out_specs): Add the new test material above to the test harness. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-06-06 10:05:10 +00:00
var_decl*
is_data_member(const decl_base *);
Initial support of anonymous data members An anonymous data member is a data member of a struct or a union which has no name. The type of such data member is either a struct or a union. For instance: struct foo { int a; struct { // <-- this is an anonymous data member char a; char b; }; int c; }; In DWARF (as emitted by GCC at least), an anonymous data member is represented as a data member with an empty name. Libabigail sees it just fine, but then when representing *changes* to that kind of data member, it needs special treatment, otherwise users cannot make sense of the reports. This patch adds initial support to represent changes to anonymous data members. * include/abg-comparison.h (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Declare new functions. * include/abg-fwd.h (is_class_type): Declare new overload for type_or_decl_base&. (is_data_member): Declare new overload for decl_base*. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Declare new functions. (is_at_class_scope): Return the class or union scope. * include/abg-ir.h (var_decl::get_qualified_name): New virtual data member which overloads decl_base::get_qualified_name. * src/abg-comparison.cc (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Define new functions (leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous class or union diff nodes as diff nodes. * src/abg-ir.cc (is_data_member): Define new overload for decl_base*. (is_class_type, is_union_type): Define new overload for type_or_decl_base&. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Define new function overloads. (var_decl::get_qualified_name): Define new virtual member function. (is_at_class_scope): Return the class or union scope. (var_decl::get_pretty_representation): Support anonymous data members. (equals): In the overload for class_or_union_diff, mark data member textual representation changes as local changes. * src/abg-reporter-priv.cc (represent): In the overload for var_diff, support changes to anonymous data members. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted -- by offset -- data member changes before the ones that are sorted by other things. * tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so: New binary test input * tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt: New reference test outputs. * tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c: Source code of the new binary test output above. * tests/data/Makefile.am: Add the new test files above to the source distribution. * tests/data/test-annotate/libtest23.so.abi: Adjust test reference output. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-09 06:51:50 +00:00
bool
is_anonymous_data_member(const decl_base&);
Explicitely detect anonymous data member changes This patch detects when a data member becomes anonymous or when an anonymous data member becomes non anonymous and emits an explicit message. * include/abg-comp-filter.h (has_anonymous_data_member_change): Add new function declaration. * include/abg-fwd.h (is_data_member, is_anonymous_data_member): declare new overloads. * src/abg-comp-filter.cc (has_anonymous_data_member_change): Define new overloads. * src/abg-ir.cc (is_data_member, is_anonymous_data_member): Define new overloads. * src/abg-reporter-priv.cc (represent): In the var_diff overload, detect when we have anonymous data member changes and emit explicit error messages then. * tests/data/test-diff-dwarf/test45-anon-dm-change-report-0.txt: New test material. * tests/data/test-diff-dwarf/test45-anon-dm-change-v0.cc: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v0.o: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v1.cc: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v1.o: Likewise. * tests/data/Makefile.am: Add the new test material above to source distribution. * tests/test-diff-dwarf.cc (in_out_specs): Add the new test material above to the test harness. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-06-06 10:05:10 +00:00
const var_decl*
is_anonymous_data_member(const type_or_decl_base*);
Initial support of anonymous data members An anonymous data member is a data member of a struct or a union which has no name. The type of such data member is either a struct or a union. For instance: struct foo { int a; struct { // <-- this is an anonymous data member char a; char b; }; int c; }; In DWARF (as emitted by GCC at least), an anonymous data member is represented as a data member with an empty name. Libabigail sees it just fine, but then when representing *changes* to that kind of data member, it needs special treatment, otherwise users cannot make sense of the reports. This patch adds initial support to represent changes to anonymous data members. * include/abg-comparison.h (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Declare new functions. * include/abg-fwd.h (is_class_type): Declare new overload for type_or_decl_base&. (is_data_member): Declare new overload for decl_base*. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Declare new functions. (is_at_class_scope): Return the class or union scope. * include/abg-ir.h (var_decl::get_qualified_name): New virtual data member which overloads decl_base::get_qualified_name. * src/abg-comparison.cc (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Define new functions (leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous class or union diff nodes as diff nodes. * src/abg-ir.cc (is_data_member): Define new overload for decl_base*. (is_class_type, is_union_type): Define new overload for type_or_decl_base&. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Define new function overloads. (var_decl::get_qualified_name): Define new virtual member function. (is_at_class_scope): Return the class or union scope. (var_decl::get_pretty_representation): Support anonymous data members. (equals): In the overload for class_or_union_diff, mark data member textual representation changes as local changes. * src/abg-reporter-priv.cc (represent): In the overload for var_diff, support changes to anonymous data members. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted -- by offset -- data member changes before the ones that are sorted by other things. * tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so: New binary test input * tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt: New reference test outputs. * tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c: Source code of the new binary test output above. * tests/data/Makefile.am: Add the new test files above to the source distribution. * tests/data/test-annotate/libtest23.so.abi: Adjust test reference output. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-09 06:51:50 +00:00
const var_decl*
is_anonymous_data_member(const decl_base*);
Explicitely detect anonymous data member changes This patch detects when a data member becomes anonymous or when an anonymous data member becomes non anonymous and emits an explicit message. * include/abg-comp-filter.h (has_anonymous_data_member_change): Add new function declaration. * include/abg-fwd.h (is_data_member, is_anonymous_data_member): declare new overloads. * src/abg-comp-filter.cc (has_anonymous_data_member_change): Define new overloads. * src/abg-ir.cc (is_data_member, is_anonymous_data_member): Define new overloads. * src/abg-reporter-priv.cc (represent): In the var_diff overload, detect when we have anonymous data member changes and emit explicit error messages then. * tests/data/test-diff-dwarf/test45-anon-dm-change-report-0.txt: New test material. * tests/data/test-diff-dwarf/test45-anon-dm-change-v0.cc: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v0.o: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v1.cc: Likewise. * tests/data/test-diff-dwarf/test45-anon-dm-change-v1.o: Likewise. * tests/data/Makefile.am: Add the new test material above to source distribution. * tests/test-diff-dwarf.cc (in_out_specs): Add the new test material above to the test harness. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Adjust. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-06-06 10:05:10 +00:00
var_decl_sptr
is_anonymous_data_member(const type_or_decl_base_sptr&);
Initial support of anonymous data members An anonymous data member is a data member of a struct or a union which has no name. The type of such data member is either a struct or a union. For instance: struct foo { int a; struct { // <-- this is an anonymous data member char a; char b; }; int c; }; In DWARF (as emitted by GCC at least), an anonymous data member is represented as a data member with an empty name. Libabigail sees it just fine, but then when representing *changes* to that kind of data member, it needs special treatment, otherwise users cannot make sense of the reports. This patch adds initial support to represent changes to anonymous data members. * include/abg-comparison.h (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Declare new functions. * include/abg-fwd.h (is_class_type): Declare new overload for type_or_decl_base&. (is_data_member): Declare new overload for decl_base*. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Declare new functions. (is_at_class_scope): Return the class or union scope. * include/abg-ir.h (var_decl::get_qualified_name): New virtual data member which overloads decl_base::get_qualified_name. * src/abg-comparison.cc (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Define new functions (leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous class or union diff nodes as diff nodes. * src/abg-ir.cc (is_data_member): Define new overload for decl_base*. (is_class_type, is_union_type): Define new overload for type_or_decl_base&. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Define new function overloads. (var_decl::get_qualified_name): Define new virtual member function. (is_at_class_scope): Return the class or union scope. (var_decl::get_pretty_representation): Support anonymous data members. (equals): In the overload for class_or_union_diff, mark data member textual representation changes as local changes. * src/abg-reporter-priv.cc (represent): In the overload for var_diff, support changes to anonymous data members. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted -- by offset -- data member changes before the ones that are sorted by other things. * tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so: New binary test input * tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt: New reference test outputs. * tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c: Source code of the new binary test output above. * tests/data/Makefile.am: Add the new test files above to the source distribution. * tests/data/test-annotate/libtest23.so.abi: Adjust test reference output. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-09 06:51:50 +00:00
var_decl_sptr
is_anonymous_data_member(const decl_base_sptr&);
var_decl_sptr
is_anonymous_data_member(const var_decl_sptr&);
const var_decl*
is_anonymous_data_member(const var_decl*);
bool
is_anonymous_data_member(const var_decl&);
const class_or_union*
anonymous_data_member_to_class_or_union(const var_decl*);
class_or_union_sptr
anonymous_data_member_to_class_or_union(const var_decl_sptr&);
const class_or_union_sptr
data_member_has_anonymous_type(const var_decl& d);
const class_or_union_sptr
data_member_has_anonymous_type(const var_decl* d);
const class_or_union_sptr
data_member_has_anonymous_type(const var_decl_sptr& d);
Bug 18342 - Segmentation fault while comparing functions with variadic parameters In the IR built from DWARF, a variadic variadic parameter has an empty type. Later during type comparison, comparing an empty (NULL) type with other types proves to be troublesome. This patch handles the issue by creating a new kind of abigail::type_decl type specifically for variadic parameters. This is like what is done for void types. After that it appears that the categorizing sub-system flags a change of variadic type to non-variadic type as redundant if that change appears several times on different functions. We don't want that because it can hide important changes we want to see. The patch fixes that too. * include/abg-fwd.h (is_array_type): New overload for a naked pointer. * include/abg-ir.h (type_decl::get_variadic_parameter_type_decl): Declare new static function. * src/abg-ir.cc (is_array_type): Define new function overload for naked pointers (type_decl::get_variadic_parameter_type_decl): Define new static function. * src/abg-dwarf-reader.cc (build_function_decl): The type of variadic parameter is now a special type_decl. * include/abg-comparison.h (is_diff_of_variadic_parameter_type) (is_diff_of_variadic_parameter): New function declarations. * src/abg-comparison.cc (is_diff_of_variadic_parameter_type) (is_diff_of_variadic_parameter): Define new functions. (compute_diff): Refuse to return a NULL diff for types. Assert that the parameters are non-NULL. (report_size_and_alignment_changes): We are comparing arrays only if the two parameters are arrays. (fn_parm_diff::fn_parm_diff): Refuse that type diff for this diff node is non empty. (fn_parm_diff::report): Strengthen an assert. Cleanup a comment. (redundancy_marking_visitor::visit_begin): Do not mark function type and variadic parms diff nodes as redundant for local changes. * tests/data/test-diff-dwarf/libtest26-added-parms-before-variadic-v{0,1}.so: New test input binaries. * tests/data/test-diff-dwarf/test26-added-parms-before-variadic-report.txt: New test output reference. * tests/data/test-diff-dwarf/test26-added-parms-before-variadic-v{0,1}.c: Source code of the new test input binaries above. * tests/data/Makefile.am: Add the new test stuff to source distribution. * tests/test-diff-dwarf.cc (in_out_specs): Add the new test inputs above to the set of input to run this test harness over. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-05-05 08:05:45 +00:00
array_type_def*
Cleanup some entry points in abg-fwd.h While looking at something else I came accross some interface cleanup opportunities, as usual. This patch honours some of those opportunities. * include/abg-fwd.h (add_decl_to_scope): Pass the scope smart pointer by reference. (is_member_type): pass the type smart pointer by reference. (is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. * include/abg-ir.h (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (scope_decl::{add_member_decl, insert_member_decl}): Pass the member smart pointer by reference. (scope_decl::remove_member_decl): Take a non-const smart pointer. (class_decl::add_member_decl): Pass the decl smart pointer by reference. (is_method_decl): Take pointer or reference to type_or_decl_base rather than function_decl. * src/abg-ir.cc (translation_unit::priv::corpus): Make this a pointer to non-const corpus. (translation_unit::set_corpus): Take a pointer to non-const corpus. (translation_unit::get_corpus): Add a non-const overload. (translation_unit::get_global_scope): Adjust. (translation_unit::bind_function_type_life_time): Adjust. (type_or_decl_base::translation_unit): Make this a pointer to non-const translation_unit. (type_or_decl_base::get_corpus): Likewise. (type_or_decl_base::set_translation_unit): Take a pointer to non-corpus translation_unit. (type_or_decl_base::get_translation_unit): Add a non-const overload. (is_member_type): pass the type smart pointer by reference. (scope_decl::{add_member_decl, insert_member_decl}): Take a reference to the member decl smart pointer. Adjust. (class_decl::add_member_decl): Likewise. (scope_decl::remove_member_decl): Take a non-const smart pointer. (add_decl_to_scope): Pass the scope smart pointer by reference. (is_decl, is_function_decl, is_pointer_type, is_reference_type) (is_qualified_type, is_function_type, is_method_type) (is_method_decl, is_array_type): Take a type_or_decl base pointer, rather than either a decl_base or type_base pointer. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-10-31 11:26:22 +00:00
is_array_type(const type_or_decl_base* decl);
Bug 18342 - Segmentation fault while comparing functions with variadic parameters In the IR built from DWARF, a variadic variadic parameter has an empty type. Later during type comparison, comparing an empty (NULL) type with other types proves to be troublesome. This patch handles the issue by creating a new kind of abigail::type_decl type specifically for variadic parameters. This is like what is done for void types. After that it appears that the categorizing sub-system flags a change of variadic type to non-variadic type as redundant if that change appears several times on different functions. We don't want that because it can hide important changes we want to see. The patch fixes that too. * include/abg-fwd.h (is_array_type): New overload for a naked pointer. * include/abg-ir.h (type_decl::get_variadic_parameter_type_decl): Declare new static function. * src/abg-ir.cc (is_array_type): Define new function overload for naked pointers (type_decl::get_variadic_parameter_type_decl): Define new static function. * src/abg-dwarf-reader.cc (build_function_decl): The type of variadic parameter is now a special type_decl. * include/abg-comparison.h (is_diff_of_variadic_parameter_type) (is_diff_of_variadic_parameter): New function declarations. * src/abg-comparison.cc (is_diff_of_variadic_parameter_type) (is_diff_of_variadic_parameter): Define new functions. (compute_diff): Refuse to return a NULL diff for types. Assert that the parameters are non-NULL. (report_size_and_alignment_changes): We are comparing arrays only if the two parameters are arrays. (fn_parm_diff::fn_parm_diff): Refuse that type diff for this diff node is non empty. (fn_parm_diff::report): Strengthen an assert. Cleanup a comment. (redundancy_marking_visitor::visit_begin): Do not mark function type and variadic parms diff nodes as redundant for local changes. * tests/data/test-diff-dwarf/libtest26-added-parms-before-variadic-v{0,1}.so: New test input binaries. * tests/data/test-diff-dwarf/test26-added-parms-before-variadic-report.txt: New test output reference. * tests/data/test-diff-dwarf/test26-added-parms-before-variadic-v{0,1}.c: Source code of the new test input binaries above. * tests/data/Makefile.am: Add the new test stuff to source distribution. * tests/test-diff-dwarf.cc (in_out_specs): Add the new test inputs above to the set of input to run this test harness over. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-05-05 08:05:45 +00:00
array_type_def_sptr
is_array_type(const type_or_decl_base_sptr& decl);
Support C and C++ array type. * include/abg-comparison.h (array_diff): Declare new class. (array_diff_sptr): Shared pointer to type array_diff. (compute_diff): Overload the function to take type array_diff_sptr as the first two arguments. * include/abg-fwd.h (array_type_def): Declare new class. (subrange_type): Likewise. (is_array_def): Declare new function. * include/abg-ir.h (array_type_def_sptr): Shared pointer to type array_type_def. (array_type_def): Declare new class. (ir_node_visitor::visit): Declare a new virtual function taking a pointer to type array_type_def as an argument. * src/abg-comparison.cc (compute_diff_for_types): Add try_to_diff for two instances of type array_type_def. (array_diff::priv): declare struct for holding private members of type array_diff. (array_diff::array_diff): Define constructor. (array_diff::{first,second}_array):Define new member functions. (array_diff::element_type_diff): Likewise. (array_diff::{length,report,traverse}): Likewise. (compute_diff): Define function overloaded in include/abg-comparison.h. * src/abg-dwarf-reader.cc (build_array_type): Define new function. Handle DW_TAG_array_type and DW_TAG_subrange type. (build_ir_node_from_die): Amend case DW_TAG_array_type with a call to build_array_type. * src/abg-hash.cc (array_type_def::hash): Declare new struct. (type_base::dynamic_hash::operator()): Attempt to dynamic_cast the argument to type array_type_def as well. (array_type_def::hash): Declare new struct. * src/abg-ir.cc (array_type_def::array_type_def): Define constructors. (array_type_def::priv): declare struct for holding private members of type array_type_def. (array_type_def::operator==(const decl_base&): Define new operator. (array_type_def::operator==(const type_base&): Likewise. (array_type_def::append_subrange{,s}): Define new functions. (array_type_def::{set,get}_size_in_bits): Likewise. (array_type_def::get_dimension_count): Likewise. (array_type_def::get_qualified_name): Likewise. (array_type_def::get_pretty_representation): Likewise. (array_type_def::get_subrange_representation): Likewise. (array_type_def::traverse): Likewise. (array_type_def::get_{element_type,location,subranges}): Likewise. (array_type_def::is_infinite): Likewise. (array_type_def::~array_type_def): Define destructor. (ir_node_visitor::visit): Define function, taking pointer to array_type_def as an argument. * src/abg-reader.cc (map_id_and_node): Check if node is an array. (is_array_def): Check if object is an array. (handle_element_node): Handle array_type_def as well. (build_subrange_type): Define new function. (build_array_type_def): Likewise. (build_type): Build type array_type_def as well. (build_type_composition): Likewise. (handle_array_type_def): Define new function. * src/abg-writer.cc: (write_decl): Output arrays as well. (write_member_type): Likewise. (write_type_composition): Likewise. (write_array_type_def): Define new function. * tests/data/test-diff-dwarf/test{10,11}-v{0,1}.{cc,o}: New test source files * tests/data/test-diff-dwarf/test{10,11}-report.txt: Likewise. * tests/data/test-diff-dwarf/test10-report.txt: New test input. * tests/data/test-read-dwarf/test7.cc: New test source file. * tests/data/test-read-dwarf/test7.so: New input binary to read. * tests/data/test-read-dwarf/test7.so.abi: New reference test to compare against. * tests/data/test-read-write/test25.xml: New test source file. * tests/test-diff-dwarf.cc: Adjust to launch the new test. * tests/test-read-dwarf.cc: Likewise. * tests/test-read-write.cc: Likewise. * test/Makefile.am: Add the new test inputs to the source distribution. Signed-off-by: Ondrej Oprala <ooprala@redhat.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-08-18 09:56:43 +00:00
Bug 24430 - Fold away const for array types In C and C++ the qualifiers of a qualified array type apply to the element type of said array. In this particular problem report, GCC and Clang emit DWARF that represent the qualifiers either on the array type, or on the element type. Quoting the test of the bug: Given the following example: struct test { const char asdf[4]; }; void func(struct test arg) {} abidiff says: 1 function with some indirect sub-type change: [C]'function void func(test)' at test.c:5:1 has some indirect sub-type changes: parameter 1 of type 'struct test' has sub-type changes: type size hasn't changed 1 data member change: type of 'const char test::asdf[4]' changed: entity changed from 'const char[4]' to 'const char[4] const' This is because GCC represents the array as const array of const signed char, whereas clang represents it as an array of const signed char. In this patch, libabigail's DWARF reader detects qualified array types and appropriately qualifies the array element type, instead of qualifying the array type. The patch accordingly adjusts the various regression tests and adds a new test which comes from the problem report. * include/abg-fwd.h (is_array_of_qualified_element): Declare 2 overloads of this function. (re_canonicalize): Declare a new function. * include/abg-ir.h (class {decl_base, type_base}): Declare re_canonicalize as a friend of these classes. * src/abg-dwarf-reader.cc (maybe_strip_qualification): Detect qualified array types and appropriately qualifies the array element type, instead of qualifying the array type itself. Re-canonicalize the resulting type if necessary. * src/abg-ir.cc (is_array_of_qualified_element): Define 2 overloads of this function. (re_canonicalize): Define new function. * tests/data/Makefile.am: The two new test binary input files PR24430-fold-qualified-array-clang and PR24430-fold-qualified-array-gcc to source distribution, as well as the expected reference output. * tests/data/test-annotate/test15-pr18892.so.abi: Adjust. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-filter/PR24430-fold-qualified-array-clang: New binary test input coming from the bug report. * tests/data/test-diff-filter/PR24430-fold-qualified-array-gcc: Likewise. * tests/data/test-diff-filter/PR24430-fold-qualified-array-report-0.txt: Expected reference abi difference. * tests/data/test-diff-filter/test33-report-0.txt: Adjust. * tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt: Likewise. * tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/test-diff-filter.cc: Add the new binary test input to this test harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-10 10:51:13 +00:00
array_type_def_sptr
is_array_of_qualified_element(type_base_sptr&);
qualified_type_def_sptr
is_array_of_qualified_element(const array_type_def_sptr&);
Get rid of class_decl::data_member * include/abg-fwd.h (has_scope): Delete the overloads for type_base. (get_member_is_static): Add an overload for decl_base*. ({is,get,set}_data_member,{get_,set}_data_member_is_laid_out) ({get,set}_data_member_offset): New access declarations. * include/abg-ir.h (class context_rel): Move up. (decl_base::set_context_rel): New definition. (class dm_context_rel): New type. (decl_base::hash_as_member): Remove. (var_decl::set_scope): Declare new virtual member. (class_decl::data_member): Remove. (ir_node_visitor::visit): Remove the overload for class_decl::data_member. (represent_data_member): Remove the represent overload for class_decl::data_member into this. Make it take a var_decl. (represent): Change the overload that takes two class_decl::data_member take two var_decl. And adjust it. (class_diff::report): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload that takes a class_decl::data_member*. Adjust the overload that takes a var_decl to recognize (static) data members. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_ir_node_from_die): Adjust. * src/abg-hash.cc (var_decl::hash::operator()): Adjust. (class_decl::data_member::hash::operator()): Remove. (decl_base::hash::operator()): Take the context relationship in account here. (decl_base::hash_as_member::operator()): Remove. ({enum_type_decl,typedef_decl}::hash::operator()): Adjust. (class_decl::member_function::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (dm_context_rel::~dm_context_rel): New definition. (has_scope): Remove overload for type_base. (get_member_is_static): New overload for decl_base*. (is_data_member): New function definition. ({get,set}_data_member_{offset,is_laid_out}): Define new accessors. (var_decl::set_scope): Define new member function. Make this set a dm_context_rel as the context relationship. (var_decl::operator==): Adjust to take in account the new data member relationship. (class_decl::class_decl): Adjust. (class_decl::insert_member_decl): Adjust. (class_decl::add_data_member): Remove the overload for class_decl::data_member. (class_decl::add_data_member): Adjust the overload for var_decl. (operator==): Remove overload for class_decl::data_member*. (class_decl::data_member::operator==): Likewise. (ir_node_visitor::visit): Remove overload for class_decl::data_member. * src/abg-writer.cc (write_layout_offset, write_class_decl): Adjust. * tests/data/test-read-write/test20.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-19 19:36:55 +00:00
void
set_data_member_offset(var_decl_sptr, uint64_t);
Get rid of class_decl::data_member * include/abg-fwd.h (has_scope): Delete the overloads for type_base. (get_member_is_static): Add an overload for decl_base*. ({is,get,set}_data_member,{get_,set}_data_member_is_laid_out) ({get,set}_data_member_offset): New access declarations. * include/abg-ir.h (class context_rel): Move up. (decl_base::set_context_rel): New definition. (class dm_context_rel): New type. (decl_base::hash_as_member): Remove. (var_decl::set_scope): Declare new virtual member. (class_decl::data_member): Remove. (ir_node_visitor::visit): Remove the overload for class_decl::data_member. (represent_data_member): Remove the represent overload for class_decl::data_member into this. Make it take a var_decl. (represent): Change the overload that takes two class_decl::data_member take two var_decl. And adjust it. (class_diff::report): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload that takes a class_decl::data_member*. Adjust the overload that takes a var_decl to recognize (static) data members. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_ir_node_from_die): Adjust. * src/abg-hash.cc (var_decl::hash::operator()): Adjust. (class_decl::data_member::hash::operator()): Remove. (decl_base::hash::operator()): Take the context relationship in account here. (decl_base::hash_as_member::operator()): Remove. ({enum_type_decl,typedef_decl}::hash::operator()): Adjust. (class_decl::member_function::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (dm_context_rel::~dm_context_rel): New definition. (has_scope): Remove overload for type_base. (get_member_is_static): New overload for decl_base*. (is_data_member): New function definition. ({get,set}_data_member_{offset,is_laid_out}): Define new accessors. (var_decl::set_scope): Define new member function. Make this set a dm_context_rel as the context relationship. (var_decl::operator==): Adjust to take in account the new data member relationship. (class_decl::class_decl): Adjust. (class_decl::insert_member_decl): Adjust. (class_decl::add_data_member): Remove the overload for class_decl::data_member. (class_decl::add_data_member): Adjust the overload for var_decl. (operator==): Remove overload for class_decl::data_member*. (class_decl::data_member::operator==): Likewise. (ir_node_visitor::visit): Remove overload for class_decl::data_member. * src/abg-writer.cc (write_layout_offset, write_class_decl): Adjust. * tests/data/test-read-write/test20.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-19 19:36:55 +00:00
uint64_t
Get rid of class_decl::data_member * include/abg-fwd.h (has_scope): Delete the overloads for type_base. (get_member_is_static): Add an overload for decl_base*. ({is,get,set}_data_member,{get_,set}_data_member_is_laid_out) ({get,set}_data_member_offset): New access declarations. * include/abg-ir.h (class context_rel): Move up. (decl_base::set_context_rel): New definition. (class dm_context_rel): New type. (decl_base::hash_as_member): Remove. (var_decl::set_scope): Declare new virtual member. (class_decl::data_member): Remove. (ir_node_visitor::visit): Remove the overload for class_decl::data_member. (represent_data_member): Remove the represent overload for class_decl::data_member into this. Make it take a var_decl. (represent): Change the overload that takes two class_decl::data_member take two var_decl. And adjust it. (class_diff::report): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload that takes a class_decl::data_member*. Adjust the overload that takes a var_decl to recognize (static) data members. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_ir_node_from_die): Adjust. * src/abg-hash.cc (var_decl::hash::operator()): Adjust. (class_decl::data_member::hash::operator()): Remove. (decl_base::hash::operator()): Take the context relationship in account here. (decl_base::hash_as_member::operator()): Remove. ({enum_type_decl,typedef_decl}::hash::operator()): Adjust. (class_decl::member_function::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (dm_context_rel::~dm_context_rel): New definition. (has_scope): Remove overload for type_base. (get_member_is_static): New overload for decl_base*. (is_data_member): New function definition. ({get,set}_data_member_{offset,is_laid_out}): Define new accessors. (var_decl::set_scope): Define new member function. Make this set a dm_context_rel as the context relationship. (var_decl::operator==): Adjust to take in account the new data member relationship. (class_decl::class_decl): Adjust. (class_decl::insert_member_decl): Adjust. (class_decl::add_data_member): Remove the overload for class_decl::data_member. (class_decl::add_data_member): Adjust the overload for var_decl. (operator==): Remove overload for class_decl::data_member*. (class_decl::data_member::operator==): Likewise. (ir_node_visitor::visit): Remove overload for class_decl::data_member. * src/abg-writer.cc (write_layout_offset, write_class_decl): Adjust. * tests/data/test-read-write/test20.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-19 19:36:55 +00:00
get_data_member_offset(const var_decl&);
uint64_t
get_data_member_offset(const var_decl_sptr);
Get rid of class_decl::data_member * include/abg-fwd.h (has_scope): Delete the overloads for type_base. (get_member_is_static): Add an overload for decl_base*. ({is,get,set}_data_member,{get_,set}_data_member_is_laid_out) ({get,set}_data_member_offset): New access declarations. * include/abg-ir.h (class context_rel): Move up. (decl_base::set_context_rel): New definition. (class dm_context_rel): New type. (decl_base::hash_as_member): Remove. (var_decl::set_scope): Declare new virtual member. (class_decl::data_member): Remove. (ir_node_visitor::visit): Remove the overload for class_decl::data_member. (represent_data_member): Remove the represent overload for class_decl::data_member into this. Make it take a var_decl. (represent): Change the overload that takes two class_decl::data_member take two var_decl. And adjust it. (class_diff::report): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload that takes a class_decl::data_member*. Adjust the overload that takes a var_decl to recognize (static) data members. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_ir_node_from_die): Adjust. * src/abg-hash.cc (var_decl::hash::operator()): Adjust. (class_decl::data_member::hash::operator()): Remove. (decl_base::hash::operator()): Take the context relationship in account here. (decl_base::hash_as_member::operator()): Remove. ({enum_type_decl,typedef_decl}::hash::operator()): Adjust. (class_decl::member_function::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (dm_context_rel::~dm_context_rel): New definition. (has_scope): Remove overload for type_base. (get_member_is_static): New overload for decl_base*. (is_data_member): New function definition. ({get,set}_data_member_{offset,is_laid_out}): Define new accessors. (var_decl::set_scope): Define new member function. Make this set a dm_context_rel as the context relationship. (var_decl::operator==): Adjust to take in account the new data member relationship. (class_decl::class_decl): Adjust. (class_decl::insert_member_decl): Adjust. (class_decl::add_data_member): Remove the overload for class_decl::data_member. (class_decl::add_data_member): Adjust the overload for var_decl. (operator==): Remove overload for class_decl::data_member*. (class_decl::data_member::operator==): Likewise. (ir_node_visitor::visit): Remove overload for class_decl::data_member. * src/abg-writer.cc (write_layout_offset, write_class_decl): Adjust. * tests/data/test-read-write/test20.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-19 19:36:55 +00:00
uint64_t
get_data_member_offset(const decl_base_sptr);
Represent a removed+added data member at a given offset as changed * include/abg-fwd.h (get_data_member_offset): Declare new overload for decl_base_sptr. * include/abg-comparison.h (unsigned_decl_base_sptr_map) (unsigned_changed_type_or_decl_map): New typedefs. * src/abg-ir.cc (get_data_member_offset): Define new overload for decl_base_sptr. * src/abg-comparison.cc (diff_kind::subtype_change_kind): New enumerator for a change about a type or sub-type of a member of a structure/enum. (report_mem_header): Handle the new enumerator above. (class_diff::priv::{deleted_dm_by_offset_, inserted_dm_by_offset_, changed_dm_}): New data members. (class_diff::priv::subtype_changed_dm_): Renamed class_diff::priv::changed_data_members_ into this. (class_diff::priv::subtype_changed_dm): Renamed class_diff::priv::data_member_has_changed into this. Adjust. (class_diff::count_filtered_subtype_changed_dm): Renamed count_filtered_data_members into this. Adjust. (class_diff::priv::count_filtered_changed_dm): New member function. (class_diff::lookup_tables_empty): Adjust. (class_diff::ensure_lookup_tables_populated): Adjust. Detect when a data member is deleted and added back to offset N, and be prepared to present that as a change of data member at offset N. (class_diff::report): Adjust. Report data members of a given offset that have changed. * tests/data/test-diff-dwarf/test6-report.txt: New reference report for new test input. * tests/data/test-diff-dwarf/test6-v0.cc: Source code for new test input binary. * tests/data/test-diff-dwarf/test6-v0.o: New test input binary. * tests/data/test-diff-dwarf/test6-v1.cc: Source code for new test input binary. * tests/data/test-diff-dwarf/test6-v1.o: New test input binary. * tests/test-diff-dwarf.cc: Adjust to include the new test inputs above. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-04-11 14:52:00 +00:00
Initial implementation of a --leaf-changes-only option to abidiff 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>
2017-08-02 16:00:23 +00:00
uint64_t
get_var_size_in_bits(const var_decl_sptr&);
Get rid of class_decl::data_member * include/abg-fwd.h (has_scope): Delete the overloads for type_base. (get_member_is_static): Add an overload for decl_base*. ({is,get,set}_data_member,{get_,set}_data_member_is_laid_out) ({get,set}_data_member_offset): New access declarations. * include/abg-ir.h (class context_rel): Move up. (decl_base::set_context_rel): New definition. (class dm_context_rel): New type. (decl_base::hash_as_member): Remove. (var_decl::set_scope): Declare new virtual member. (class_decl::data_member): Remove. (ir_node_visitor::visit): Remove the overload for class_decl::data_member. (represent_data_member): Remove the represent overload for class_decl::data_member into this. Make it take a var_decl. (represent): Change the overload that takes two class_decl::data_member take two var_decl. And adjust it. (class_diff::report): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload that takes a class_decl::data_member*. Adjust the overload that takes a var_decl to recognize (static) data members. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_ir_node_from_die): Adjust. * src/abg-hash.cc (var_decl::hash::operator()): Adjust. (class_decl::data_member::hash::operator()): Remove. (decl_base::hash::operator()): Take the context relationship in account here. (decl_base::hash_as_member::operator()): Remove. ({enum_type_decl,typedef_decl}::hash::operator()): Adjust. (class_decl::member_function::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (dm_context_rel::~dm_context_rel): New definition. (has_scope): Remove overload for type_base. (get_member_is_static): New overload for decl_base*. (is_data_member): New function definition. ({get,set}_data_member_{offset,is_laid_out}): Define new accessors. (var_decl::set_scope): Define new member function. Make this set a dm_context_rel as the context relationship. (var_decl::operator==): Adjust to take in account the new data member relationship. (class_decl::class_decl): Adjust. (class_decl::insert_member_decl): Adjust. (class_decl::add_data_member): Remove the overload for class_decl::data_member. (class_decl::add_data_member): Adjust the overload for var_decl. (operator==): Remove overload for class_decl::data_member*. (class_decl::data_member::operator==): Likewise. (ir_node_visitor::visit): Remove overload for class_decl::data_member. * src/abg-writer.cc (write_layout_offset, write_class_decl): Adjust. * tests/data/test-read-write/test20.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-19 19:36:55 +00:00
void
set_data_member_is_laid_out(var_decl_sptr, bool);
Get rid of class_decl::data_member * include/abg-fwd.h (has_scope): Delete the overloads for type_base. (get_member_is_static): Add an overload for decl_base*. ({is,get,set}_data_member,{get_,set}_data_member_is_laid_out) ({get,set}_data_member_offset): New access declarations. * include/abg-ir.h (class context_rel): Move up. (decl_base::set_context_rel): New definition. (class dm_context_rel): New type. (decl_base::hash_as_member): Remove. (var_decl::set_scope): Declare new virtual member. (class_decl::data_member): Remove. (ir_node_visitor::visit): Remove the overload for class_decl::data_member. (represent_data_member): Remove the represent overload for class_decl::data_member into this. Make it take a var_decl. (represent): Change the overload that takes two class_decl::data_member take two var_decl. And adjust it. (class_diff::report): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload that takes a class_decl::data_member*. Adjust the overload that takes a var_decl to recognize (static) data members. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_ir_node_from_die): Adjust. * src/abg-hash.cc (var_decl::hash::operator()): Adjust. (class_decl::data_member::hash::operator()): Remove. (decl_base::hash::operator()): Take the context relationship in account here. (decl_base::hash_as_member::operator()): Remove. ({enum_type_decl,typedef_decl}::hash::operator()): Adjust. (class_decl::member_function::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (dm_context_rel::~dm_context_rel): New definition. (has_scope): Remove overload for type_base. (get_member_is_static): New overload for decl_base*. (is_data_member): New function definition. ({get,set}_data_member_{offset,is_laid_out}): Define new accessors. (var_decl::set_scope): Define new member function. Make this set a dm_context_rel as the context relationship. (var_decl::operator==): Adjust to take in account the new data member relationship. (class_decl::class_decl): Adjust. (class_decl::insert_member_decl): Adjust. (class_decl::add_data_member): Remove the overload for class_decl::data_member. (class_decl::add_data_member): Adjust the overload for var_decl. (operator==): Remove overload for class_decl::data_member*. (class_decl::data_member::operator==): Likewise. (ir_node_visitor::visit): Remove overload for class_decl::data_member. * src/abg-writer.cc (write_layout_offset, write_class_decl): Adjust. * tests/data/test-read-write/test20.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-19 19:36:55 +00:00
bool
get_data_member_is_laid_out(const var_decl&);
bool
get_data_member_is_laid_out(const var_decl_sptr);
Get rid of class_decl::data_member * include/abg-fwd.h (has_scope): Delete the overloads for type_base. (get_member_is_static): Add an overload for decl_base*. ({is,get,set}_data_member,{get_,set}_data_member_is_laid_out) ({get,set}_data_member_offset): New access declarations. * include/abg-ir.h (class context_rel): Move up. (decl_base::set_context_rel): New definition. (class dm_context_rel): New type. (decl_base::hash_as_member): Remove. (var_decl::set_scope): Declare new virtual member. (class_decl::data_member): Remove. (ir_node_visitor::visit): Remove the overload for class_decl::data_member. (represent_data_member): Remove the represent overload for class_decl::data_member into this. Make it take a var_decl. (represent): Change the overload that takes two class_decl::data_member take two var_decl. And adjust it. (class_diff::report): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload that takes a class_decl::data_member*. Adjust the overload that takes a var_decl to recognize (static) data members. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir) (build_class_type_and_add_to_ir, build_ir_node_from_die): Adjust. * src/abg-hash.cc (var_decl::hash::operator()): Adjust. (class_decl::data_member::hash::operator()): Remove. (decl_base::hash::operator()): Take the context relationship in account here. (decl_base::hash_as_member::operator()): Remove. ({enum_type_decl,typedef_decl}::hash::operator()): Adjust. (class_decl::member_function::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (dm_context_rel::~dm_context_rel): New definition. (has_scope): Remove overload for type_base. (get_member_is_static): New overload for decl_base*. (is_data_member): New function definition. ({get,set}_data_member_{offset,is_laid_out}): Define new accessors. (var_decl::set_scope): Define new member function. Make this set a dm_context_rel as the context relationship. (var_decl::operator==): Adjust to take in account the new data member relationship. (class_decl::class_decl): Adjust. (class_decl::insert_member_decl): Adjust. (class_decl::add_data_member): Remove the overload for class_decl::data_member. (class_decl::add_data_member): Adjust the overload for var_decl. (operator==): Remove overload for class_decl::data_member*. (class_decl::data_member::operator==): Likewise. (ir_node_visitor::visit): Remove overload for class_decl::data_member. * src/abg-writer.cc (write_layout_offset, write_class_decl): Adjust. * tests/data/test-read-write/test20.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-19 19:36:55 +00:00
Get rid of class_decl::member_function * include/abg-fwd.h (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function declarations. * include/abg-ir.h (class_decl::member_function): Remove. (class_decl::member_functions): Adjust. This is now just a vector of method_decl_sptr. (class_decl::add_member_function): Remove the overload taking class_decl::member_function. Adjust the other overload to take a method_decl_sptr. (class mem_fn_context_rel): New class. (class_decl::method_decl::set_scope): New virtual overload. (class_decl::member_function): Remove. (operator==): Remove the overload taking a class_decl::member_function. (class_decl::member_function::hash): Remove. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust. * src/abg-comparison.cc (represent): Adjust the overload taking a class_decl::member_function to take a class_decl::method_decl. (class_diff::{report, ensure_lookup_tables_populated}): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload taking a class_decl::member_function. * src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Adjust. * src/abg-hash.cc (decl_base::hash::operator()): Use the fully qualified name of the decl in the hash, to increase the likelihood of avoiding hash collisions. (method_type::hash::operator()): Likewise. (function_decl::hash::operator()): Take member functions in account. (class_decl::member_function::hash::operator()): Remove. (class_decl::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function definitions. (function_decl::get_pretty_representation): Adjust. (function_decl::operator): Take member functions in account here. (class_decl::insert_member_decl): Adjust. (mem_fn_context_rel::~mem_fn_context_rel): New definition. (class_decl::member_function::*): Remove. (class_decl::method_decl::set_scope): New definition. (class_decl::get_num_virtual_functions): Adjust. (class_decl::add_member_function): Remove overload taking a class_decl::member_function. Define a new overload taking a class_decl::method_decl. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * src/abg-reader.cc (build_class_decl): Adjust. * src/abg-writer.cc (write_voffset, write_class_decl): Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-20 10:56:56 +00:00
bool
is_member_function(const function_decl&);
bool
is_member_function(const function_decl*);
bool
is_member_function(const function_decl_sptr&);
Get rid of class_decl::member_function * include/abg-fwd.h (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function declarations. * include/abg-ir.h (class_decl::member_function): Remove. (class_decl::member_functions): Adjust. This is now just a vector of method_decl_sptr. (class_decl::add_member_function): Remove the overload taking class_decl::member_function. Adjust the other overload to take a method_decl_sptr. (class mem_fn_context_rel): New class. (class_decl::method_decl::set_scope): New virtual overload. (class_decl::member_function): Remove. (operator==): Remove the overload taking a class_decl::member_function. (class_decl::member_function::hash): Remove. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust. * src/abg-comparison.cc (represent): Adjust the overload taking a class_decl::member_function to take a class_decl::method_decl. (class_diff::{report, ensure_lookup_tables_populated}): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload taking a class_decl::member_function. * src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Adjust. * src/abg-hash.cc (decl_base::hash::operator()): Use the fully qualified name of the decl in the hash, to increase the likelihood of avoiding hash collisions. (method_type::hash::operator()): Likewise. (function_decl::hash::operator()): Take member functions in account. (class_decl::member_function::hash::operator()): Remove. (class_decl::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function definitions. (function_decl::get_pretty_representation): Adjust. (function_decl::operator): Take member functions in account here. (class_decl::insert_member_decl): Adjust. (mem_fn_context_rel::~mem_fn_context_rel): New definition. (class_decl::member_function::*): Remove. (class_decl::method_decl::set_scope): New definition. (class_decl::get_num_virtual_functions): Adjust. (class_decl::add_member_function): Remove overload taking a class_decl::member_function. Define a new overload taking a class_decl::method_decl. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * src/abg-reader.cc (build_class_decl): Adjust. * src/abg-writer.cc (write_voffset, write_class_decl): Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-20 10:56:56 +00:00
bool
get_member_function_is_ctor(const function_decl&);
bool
get_member_function_is_ctor(const function_decl_sptr&);
Get rid of class_decl::member_function * include/abg-fwd.h (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function declarations. * include/abg-ir.h (class_decl::member_function): Remove. (class_decl::member_functions): Adjust. This is now just a vector of method_decl_sptr. (class_decl::add_member_function): Remove the overload taking class_decl::member_function. Adjust the other overload to take a method_decl_sptr. (class mem_fn_context_rel): New class. (class_decl::method_decl::set_scope): New virtual overload. (class_decl::member_function): Remove. (operator==): Remove the overload taking a class_decl::member_function. (class_decl::member_function::hash): Remove. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust. * src/abg-comparison.cc (represent): Adjust the overload taking a class_decl::member_function to take a class_decl::method_decl. (class_diff::{report, ensure_lookup_tables_populated}): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload taking a class_decl::member_function. * src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Adjust. * src/abg-hash.cc (decl_base::hash::operator()): Use the fully qualified name of the decl in the hash, to increase the likelihood of avoiding hash collisions. (method_type::hash::operator()): Likewise. (function_decl::hash::operator()): Take member functions in account. (class_decl::member_function::hash::operator()): Remove. (class_decl::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function definitions. (function_decl::get_pretty_representation): Adjust. (function_decl::operator): Take member functions in account here. (class_decl::insert_member_decl): Adjust. (mem_fn_context_rel::~mem_fn_context_rel): New definition. (class_decl::member_function::*): Remove. (class_decl::method_decl::set_scope): New definition. (class_decl::get_num_virtual_functions): Adjust. (class_decl::add_member_function): Remove overload taking a class_decl::member_function. Define a new overload taking a class_decl::method_decl. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * src/abg-reader.cc (build_class_decl): Adjust. * src/abg-writer.cc (write_voffset, write_class_decl): Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-20 10:56:56 +00:00
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
void
set_member_function_is_ctor(const function_decl&, bool);
void
set_member_function_is_ctor(const function_decl_sptr&, bool);
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
Get rid of class_decl::member_function * include/abg-fwd.h (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function declarations. * include/abg-ir.h (class_decl::member_function): Remove. (class_decl::member_functions): Adjust. This is now just a vector of method_decl_sptr. (class_decl::add_member_function): Remove the overload taking class_decl::member_function. Adjust the other overload to take a method_decl_sptr. (class mem_fn_context_rel): New class. (class_decl::method_decl::set_scope): New virtual overload. (class_decl::member_function): Remove. (operator==): Remove the overload taking a class_decl::member_function. (class_decl::member_function::hash): Remove. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust. * src/abg-comparison.cc (represent): Adjust the overload taking a class_decl::member_function to take a class_decl::method_decl. (class_diff::{report, ensure_lookup_tables_populated}): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload taking a class_decl::member_function. * src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Adjust. * src/abg-hash.cc (decl_base::hash::operator()): Use the fully qualified name of the decl in the hash, to increase the likelihood of avoiding hash collisions. (method_type::hash::operator()): Likewise. (function_decl::hash::operator()): Take member functions in account. (class_decl::member_function::hash::operator()): Remove. (class_decl::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function definitions. (function_decl::get_pretty_representation): Adjust. (function_decl::operator): Take member functions in account here. (class_decl::insert_member_decl): Adjust. (mem_fn_context_rel::~mem_fn_context_rel): New definition. (class_decl::member_function::*): Remove. (class_decl::method_decl::set_scope): New definition. (class_decl::get_num_virtual_functions): Adjust. (class_decl::add_member_function): Remove overload taking a class_decl::member_function. Define a new overload taking a class_decl::method_decl. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * src/abg-reader.cc (build_class_decl): Adjust. * src/abg-writer.cc (write_voffset, write_class_decl): Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-20 10:56:56 +00:00
bool
get_member_function_is_dtor(const function_decl&);
bool
get_member_function_is_dtor(const function_decl_sptr&);
Get rid of class_decl::member_function * include/abg-fwd.h (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function declarations. * include/abg-ir.h (class_decl::member_function): Remove. (class_decl::member_functions): Adjust. This is now just a vector of method_decl_sptr. (class_decl::add_member_function): Remove the overload taking class_decl::member_function. Adjust the other overload to take a method_decl_sptr. (class mem_fn_context_rel): New class. (class_decl::method_decl::set_scope): New virtual overload. (class_decl::member_function): Remove. (operator==): Remove the overload taking a class_decl::member_function. (class_decl::member_function::hash): Remove. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust. * src/abg-comparison.cc (represent): Adjust the overload taking a class_decl::member_function to take a class_decl::method_decl. (class_diff::{report, ensure_lookup_tables_populated}): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload taking a class_decl::member_function. * src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Adjust. * src/abg-hash.cc (decl_base::hash::operator()): Use the fully qualified name of the decl in the hash, to increase the likelihood of avoiding hash collisions. (method_type::hash::operator()): Likewise. (function_decl::hash::operator()): Take member functions in account. (class_decl::member_function::hash::operator()): Remove. (class_decl::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function definitions. (function_decl::get_pretty_representation): Adjust. (function_decl::operator): Take member functions in account here. (class_decl::insert_member_decl): Adjust. (mem_fn_context_rel::~mem_fn_context_rel): New definition. (class_decl::member_function::*): Remove. (class_decl::method_decl::set_scope): New definition. (class_decl::get_num_virtual_functions): Adjust. (class_decl::add_member_function): Remove overload taking a class_decl::member_function. Define a new overload taking a class_decl::method_decl. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * src/abg-reader.cc (build_class_decl): Adjust. * src/abg-writer.cc (write_voffset, write_class_decl): Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-20 10:56:56 +00:00
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
void
Make decl_base::get_context_rel() return a naked pointer Accessing the context relationship of declarations and setting some member properties appear to be high in performance profiles due to shared pointer handling. This patch makes the context relationship accessors return a naked pointer and also passes a bunch of shared pointer as references around. * include/abg-fwd.h (set_member_is_static): Add an overload that takes the member as a reference to a smart pointer. (set_member_function_{is_dtor, is_ctor, is_const, vtable_offset, is_virtual}): Pass the member function as a reference. (set_member_function_is_const, set_member_function_is_virtual): Pass the member function as a non-const reference. * include/abg-ir.h (decl_base::get_context_rel): Return a naked pointer. (set_member_is_static, set_member_function_is_virtual): Adjust this friend declaration. (set_member_access_specifier): Add an overload that takes a reference to the member. Pass a reference to smart pointer to the other overload. (set_member_function_is_{is_ctor,is_dtor,is_const,is_virtual,vtable_offset}): Take a non-const reference to function_decl. * src/abg-ir.cc (decl_base::get_context_rel): Likewise. (equals(const decl_base&, const decl_base&, change_kind*)): Adjust. (equals(const var_decl&, const var_decl&, change_kind*)): Likewise. (get_member_access_specifier, get_member_is_static) (set_data_member_offset, get_data_member_offset) (set_data_member_is_laid_out, get_data_member_is_laid_out) (get_member_function_is_ctor, set_member_function_is_ctor) (get_member_function_is_dtor, set_member_function_is_dtor) (get_member_function_is_const, set_member_function_is_const) (get_member_function_vtable_offset) (set_member_function_vtable_offset) (get_member_function_is_virtual, set_member_function_is_virtual): Likewise. (set_member_access_specifier): Add an overload that takes a reference to decl_base. (set_member_is_static, set_member_function_{is_dtor, is_ctor, is_const, vtable_offset, is_virtual}): Pass the member function as a reference.): Add an overload that takes the member as a reference, and write the older overload in terms of the new one. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-10 10:45:46 +00:00
set_member_function_is_dtor(function_decl&, bool);
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
void
set_member_function_is_dtor(const function_decl_sptr&, bool);
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
Get rid of class_decl::member_function * include/abg-fwd.h (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function declarations. * include/abg-ir.h (class_decl::member_function): Remove. (class_decl::member_functions): Adjust. This is now just a vector of method_decl_sptr. (class_decl::add_member_function): Remove the overload taking class_decl::member_function. Adjust the other overload to take a method_decl_sptr. (class mem_fn_context_rel): New class. (class_decl::method_decl::set_scope): New virtual overload. (class_decl::member_function): Remove. (operator==): Remove the overload taking a class_decl::member_function. (class_decl::member_function::hash): Remove. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust. * src/abg-comparison.cc (represent): Adjust the overload taking a class_decl::member_function to take a class_decl::method_decl. (class_diff::{report, ensure_lookup_tables_populated}): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload taking a class_decl::member_function. * src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Adjust. * src/abg-hash.cc (decl_base::hash::operator()): Use the fully qualified name of the decl in the hash, to increase the likelihood of avoiding hash collisions. (method_type::hash::operator()): Likewise. (function_decl::hash::operator()): Take member functions in account. (class_decl::member_function::hash::operator()): Remove. (class_decl::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function definitions. (function_decl::get_pretty_representation): Adjust. (function_decl::operator): Take member functions in account here. (class_decl::insert_member_decl): Adjust. (mem_fn_context_rel::~mem_fn_context_rel): New definition. (class_decl::member_function::*): Remove. (class_decl::method_decl::set_scope): New definition. (class_decl::get_num_virtual_functions): Adjust. (class_decl::add_member_function): Remove overload taking a class_decl::member_function. Define a new overload taking a class_decl::method_decl. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * src/abg-reader.cc (build_class_decl): Adjust. * src/abg-writer.cc (write_voffset, write_class_decl): Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-20 10:56:56 +00:00
bool
get_member_function_is_const(const function_decl&);
bool
get_member_function_is_const(const function_decl_sptr&);
Get rid of class_decl::member_function * include/abg-fwd.h (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function declarations. * include/abg-ir.h (class_decl::member_function): Remove. (class_decl::member_functions): Adjust. This is now just a vector of method_decl_sptr. (class_decl::add_member_function): Remove the overload taking class_decl::member_function. Adjust the other overload to take a method_decl_sptr. (class mem_fn_context_rel): New class. (class_decl::method_decl::set_scope): New virtual overload. (class_decl::member_function): Remove. (operator==): Remove the overload taking a class_decl::member_function. (class_decl::member_function::hash): Remove. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust. * src/abg-comparison.cc (represent): Adjust the overload taking a class_decl::member_function to take a class_decl::method_decl. (class_diff::{report, ensure_lookup_tables_populated}): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload taking a class_decl::member_function. * src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Adjust. * src/abg-hash.cc (decl_base::hash::operator()): Use the fully qualified name of the decl in the hash, to increase the likelihood of avoiding hash collisions. (method_type::hash::operator()): Likewise. (function_decl::hash::operator()): Take member functions in account. (class_decl::member_function::hash::operator()): Remove. (class_decl::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function definitions. (function_decl::get_pretty_representation): Adjust. (function_decl::operator): Take member functions in account here. (class_decl::insert_member_decl): Adjust. (mem_fn_context_rel::~mem_fn_context_rel): New definition. (class_decl::member_function::*): Remove. (class_decl::method_decl::set_scope): New definition. (class_decl::get_num_virtual_functions): Adjust. (class_decl::add_member_function): Remove overload taking a class_decl::member_function. Define a new overload taking a class_decl::method_decl. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * src/abg-reader.cc (build_class_decl): Adjust. * src/abg-writer.cc (write_voffset, write_class_decl): Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-20 10:56:56 +00:00
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
void
Make decl_base::get_context_rel() return a naked pointer Accessing the context relationship of declarations and setting some member properties appear to be high in performance profiles due to shared pointer handling. This patch makes the context relationship accessors return a naked pointer and also passes a bunch of shared pointer as references around. * include/abg-fwd.h (set_member_is_static): Add an overload that takes the member as a reference to a smart pointer. (set_member_function_{is_dtor, is_ctor, is_const, vtable_offset, is_virtual}): Pass the member function as a reference. (set_member_function_is_const, set_member_function_is_virtual): Pass the member function as a non-const reference. * include/abg-ir.h (decl_base::get_context_rel): Return a naked pointer. (set_member_is_static, set_member_function_is_virtual): Adjust this friend declaration. (set_member_access_specifier): Add an overload that takes a reference to the member. Pass a reference to smart pointer to the other overload. (set_member_function_is_{is_ctor,is_dtor,is_const,is_virtual,vtable_offset}): Take a non-const reference to function_decl. * src/abg-ir.cc (decl_base::get_context_rel): Likewise. (equals(const decl_base&, const decl_base&, change_kind*)): Adjust. (equals(const var_decl&, const var_decl&, change_kind*)): Likewise. (get_member_access_specifier, get_member_is_static) (set_data_member_offset, get_data_member_offset) (set_data_member_is_laid_out, get_data_member_is_laid_out) (get_member_function_is_ctor, set_member_function_is_ctor) (get_member_function_is_dtor, set_member_function_is_dtor) (get_member_function_is_const, set_member_function_is_const) (get_member_function_vtable_offset) (set_member_function_vtable_offset) (get_member_function_is_virtual, set_member_function_is_virtual): Likewise. (set_member_access_specifier): Add an overload that takes a reference to decl_base. (set_member_is_static, set_member_function_{is_dtor, is_ctor, is_const, vtable_offset, is_virtual}): Pass the member function as a reference.): Add an overload that takes the member as a reference, and write the older overload in terms of the new one. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-10 10:45:46 +00:00
set_member_function_is_const(function_decl&, bool);
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
void
set_member_function_is_const(const function_decl_sptr&, bool);
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
Support virtual member functions with vtable offset not yet set When reading C++ class informatin DWARF, it can happen that a given virtual member function does not yet have a vtable offset. Right now, that offset is set to zero. Just like a virtual member function which actual vtable offset is zero. So we don't make a difference between a virtual function with no vtable offset and a virtual function with a vtable offset set to zero. This can lead to confusions during class comparison. This patch fixes that problem by setting the default vtable offset to -1. So whenever a vtable offset is -1 it means that the virtual member function doesn't yet have a vtable offset. * include/abg-fwd.h (member_function_has_vtable_offset): Declare new function. (get_member_function_vtable_offset): Return a ssize_t, not a size_t. (set_member_function_vtable_offset): Take a ssize_t, not a size_t. * include/abg-ir.h (class_decl::virtual_mem_fn_map_type): Adjust the map typedef to make it take ssize_t as the type of the key. (mem_fn_context_rel::vtable_offset_in_bits_): Make this data member be of ssize_t type, not size_t. (mem_fn_context_rel::mem_fn_context_rel): Initialize the vtable_offset_in_bits_ data member to -1. * src/abg-ir.cc (member_function_has_vtable_offset): Define new function. (get_member_function_vtable_offset): Return a ssize_t, not a size_t. (set_member_function_vtable_offset): Take a ssize_t, not a size_t. * src/abg-dwarf-reader.cc (die_virtual_function_index): Take an int64_t& rather than a uint64_t&. (finish_member_function_reading): Don't set the vtable offset if it's -1. * src/abg-reader.cc (build_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 12:40:47 +00:00
bool
member_function_has_vtable_offset(const function_decl&);
ssize_t
Get rid of class_decl::member_function * include/abg-fwd.h (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function declarations. * include/abg-ir.h (class_decl::member_function): Remove. (class_decl::member_functions): Adjust. This is now just a vector of method_decl_sptr. (class_decl::add_member_function): Remove the overload taking class_decl::member_function. Adjust the other overload to take a method_decl_sptr. (class mem_fn_context_rel): New class. (class_decl::method_decl::set_scope): New virtual overload. (class_decl::member_function): Remove. (operator==): Remove the overload taking a class_decl::member_function. (class_decl::member_function::hash): Remove. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust. * src/abg-comparison.cc (represent): Adjust the overload taking a class_decl::member_function to take a class_decl::method_decl. (class_diff::{report, ensure_lookup_tables_populated}): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload taking a class_decl::member_function. * src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Adjust. * src/abg-hash.cc (decl_base::hash::operator()): Use the fully qualified name of the decl in the hash, to increase the likelihood of avoiding hash collisions. (method_type::hash::operator()): Likewise. (function_decl::hash::operator()): Take member functions in account. (class_decl::member_function::hash::operator()): Remove. (class_decl::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function definitions. (function_decl::get_pretty_representation): Adjust. (function_decl::operator): Take member functions in account here. (class_decl::insert_member_decl): Adjust. (mem_fn_context_rel::~mem_fn_context_rel): New definition. (class_decl::member_function::*): Remove. (class_decl::method_decl::set_scope): New definition. (class_decl::get_num_virtual_functions): Adjust. (class_decl::add_member_function): Remove overload taking a class_decl::member_function. Define a new overload taking a class_decl::method_decl. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * src/abg-reader.cc (build_class_decl): Adjust. * src/abg-writer.cc (write_voffset, write_class_decl): Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-20 10:56:56 +00:00
get_member_function_vtable_offset(const function_decl&);
Support virtual member functions with vtable offset not yet set When reading C++ class informatin DWARF, it can happen that a given virtual member function does not yet have a vtable offset. Right now, that offset is set to zero. Just like a virtual member function which actual vtable offset is zero. So we don't make a difference between a virtual function with no vtable offset and a virtual function with a vtable offset set to zero. This can lead to confusions during class comparison. This patch fixes that problem by setting the default vtable offset to -1. So whenever a vtable offset is -1 it means that the virtual member function doesn't yet have a vtable offset. * include/abg-fwd.h (member_function_has_vtable_offset): Declare new function. (get_member_function_vtable_offset): Return a ssize_t, not a size_t. (set_member_function_vtable_offset): Take a ssize_t, not a size_t. * include/abg-ir.h (class_decl::virtual_mem_fn_map_type): Adjust the map typedef to make it take ssize_t as the type of the key. (mem_fn_context_rel::vtable_offset_in_bits_): Make this data member be of ssize_t type, not size_t. (mem_fn_context_rel::mem_fn_context_rel): Initialize the vtable_offset_in_bits_ data member to -1. * src/abg-ir.cc (member_function_has_vtable_offset): Define new function. (get_member_function_vtable_offset): Return a ssize_t, not a size_t. (set_member_function_vtable_offset): Take a ssize_t, not a size_t. * src/abg-dwarf-reader.cc (die_virtual_function_index): Take an int64_t& rather than a uint64_t&. (finish_member_function_reading): Don't set the vtable offset if it's -1. * src/abg-reader.cc (build_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 12:40:47 +00:00
ssize_t
get_member_function_vtable_offset(const function_decl_sptr&);
Get rid of class_decl::member_function * include/abg-fwd.h (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function declarations. * include/abg-ir.h (class_decl::member_function): Remove. (class_decl::member_functions): Adjust. This is now just a vector of method_decl_sptr. (class_decl::add_member_function): Remove the overload taking class_decl::member_function. Adjust the other overload to take a method_decl_sptr. (class mem_fn_context_rel): New class. (class_decl::method_decl::set_scope): New virtual overload. (class_decl::member_function): Remove. (operator==): Remove the overload taking a class_decl::member_function. (class_decl::member_function::hash): Remove. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * include/abg-comparison.h (changed_member_function_sptr) (string_member_function_sptr_map): Adjust. * src/abg-comparison.cc (represent): Adjust the overload taking a class_decl::member_function to take a class_decl::method_decl. (class_diff::{report, ensure_lookup_tables_populated}): Adjust. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Remove the overload taking a class_decl::member_function. * src/abg-dwarf-reader.cc (build_class_type_and_add_to_ir): Adjust. * src/abg-hash.cc (decl_base::hash::operator()): Use the fully qualified name of the decl in the hash, to increase the likelihood of avoiding hash collisions. (method_type::hash::operator()): Likewise. (function_decl::hash::operator()): Take member functions in account. (class_decl::member_function::hash::operator()): Remove. (class_decl::hash::operator()): Adjust. (type_base::dynamic_hash::operator()): Adjust. * src/abg-ir.cc (is_member_function) (get_member_function_is_{ctor,dtor,const}) (get_member_function_vtable_offset): New function definitions. (function_decl::get_pretty_representation): Adjust. (function_decl::operator): Take member functions in account here. (class_decl::insert_member_decl): Adjust. (mem_fn_context_rel::~mem_fn_context_rel): New definition. (class_decl::member_function::*): Remove. (class_decl::method_decl::set_scope): New definition. (class_decl::get_num_virtual_functions): Adjust. (class_decl::add_member_function): Remove overload taking a class_decl::member_function. Define a new overload taking a class_decl::method_decl. (ir_node_visitor::visit): Remove the overload taking a class_decl::member_function. * src/abg-reader.cc (build_class_decl): Adjust. * src/abg-writer.cc (write_voffset, write_class_decl): Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-03-20 10:56:56 +00:00
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
void
set_member_function_vtable_offset(const function_decl& f,
Support virtual member functions with vtable offset not yet set When reading C++ class informatin DWARF, it can happen that a given virtual member function does not yet have a vtable offset. Right now, that offset is set to zero. Just like a virtual member function which actual vtable offset is zero. So we don't make a difference between a virtual function with no vtable offset and a virtual function with a vtable offset set to zero. This can lead to confusions during class comparison. This patch fixes that problem by setting the default vtable offset to -1. So whenever a vtable offset is -1 it means that the virtual member function doesn't yet have a vtable offset. * include/abg-fwd.h (member_function_has_vtable_offset): Declare new function. (get_member_function_vtable_offset): Return a ssize_t, not a size_t. (set_member_function_vtable_offset): Take a ssize_t, not a size_t. * include/abg-ir.h (class_decl::virtual_mem_fn_map_type): Adjust the map typedef to make it take ssize_t as the type of the key. (mem_fn_context_rel::vtable_offset_in_bits_): Make this data member be of ssize_t type, not size_t. (mem_fn_context_rel::mem_fn_context_rel): Initialize the vtable_offset_in_bits_ data member to -1. * src/abg-ir.cc (member_function_has_vtable_offset): Define new function. (get_member_function_vtable_offset): Return a ssize_t, not a size_t. (set_member_function_vtable_offset): Take a ssize_t, not a size_t. * src/abg-dwarf-reader.cc (die_virtual_function_index): Take an int64_t& rather than a uint64_t&. (finish_member_function_reading): Don't set the vtable offset if it's -1. * src/abg-reader.cc (build_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 12:40:47 +00:00
ssize_t s);
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
void
set_member_function_vtable_offset(const function_decl_sptr &f,
Support virtual member functions with vtable offset not yet set When reading C++ class informatin DWARF, it can happen that a given virtual member function does not yet have a vtable offset. Right now, that offset is set to zero. Just like a virtual member function which actual vtable offset is zero. So we don't make a difference between a virtual function with no vtable offset and a virtual function with a vtable offset set to zero. This can lead to confusions during class comparison. This patch fixes that problem by setting the default vtable offset to -1. So whenever a vtable offset is -1 it means that the virtual member function doesn't yet have a vtable offset. * include/abg-fwd.h (member_function_has_vtable_offset): Declare new function. (get_member_function_vtable_offset): Return a ssize_t, not a size_t. (set_member_function_vtable_offset): Take a ssize_t, not a size_t. * include/abg-ir.h (class_decl::virtual_mem_fn_map_type): Adjust the map typedef to make it take ssize_t as the type of the key. (mem_fn_context_rel::vtable_offset_in_bits_): Make this data member be of ssize_t type, not size_t. (mem_fn_context_rel::mem_fn_context_rel): Initialize the vtable_offset_in_bits_ data member to -1. * src/abg-ir.cc (member_function_has_vtable_offset): Define new function. (get_member_function_vtable_offset): Return a ssize_t, not a size_t. (set_member_function_vtable_offset): Take a ssize_t, not a size_t. * src/abg-dwarf-reader.cc (die_virtual_function_index): Take an int64_t& rather than a uint64_t&. (finish_member_function_reading): Don't set the vtable offset if it's -1. * src/abg-reader.cc (build_class_decl): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-16 12:40:47 +00:00
ssize_t s);
Fix reading several clones of the same member function from DWARF * include/abg-fwd.h (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset): Declare new functions. * include/abg-ir.h (class_decl::sort_virtual_mem_fns): Declare new member function. (mem_fn_context_rel::{vtable_offset, is_constructor is_destructor, is_const}): Add these setters. (set_member_function_is_ctor, set_member_function_is_dtor) (set_member_function_is_static, set_member_function_is_const) (set_member_function_vtable_offset) (set_member_function_is_virtual): Declare these new friend function to class class_decl::method_decl. * src/abg-dwarf-reader.cc (finish_member_function_reading): Split this out from build_class_type_and_add_to_ir. Use the new setters for member functions properties introduced above. (build_class_type_and_add_to_ir): Factorize the creation of member function by using build_ir_node_from_die. Once that function has created the member function in a rather generic way, use the new finish_member_function_reading to set the remaining specific properties for member functions. (build_function_decl): When called to read additional properties of a function_decl, allow this to read and update the elf symbol properties too. This is useful for building a clone of a function that already has an elf symbol. (build_ir_node_from_die): When building a function decl, consider the case of a DIE that has both DW_AT_specification and DW_AT_abstract_origin set. That is, DW_AT_abstract_origin is set, and the origin has DW_AT_specification set. This is basically a clone of a function that implements an interface (this happens for destructors, for instance). In this case, really do the cloning of the interface implementation. If the cloned function happens to be member function, use finish_member_function_reading to read the properties relevant to its method-ness. * src/abg-ir.cc (set_member_function_is_ctor) (set_member_function_is_dtor, set_member_function_is_const) (set_member_function_vtable_offset) (class_decl::sort_virtual_mem_fns): Define new functions. (sort_virtual_member_functions): Define new static function. (struct virtual_member_function_less_than): New functor. (class_decl::add_member_function): Keep virtual member functions vector sorted. * data/test-read-dwarf/test1.abi: Adjust. Now, both the cdtor specification and all the clones that implements the different are emitted. * data/test-read-dwarf/test2.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-10-01 15:42:45 +00:00
Filter non-virtual member fns insertions/deletions from class changes * include/abg-fwd.h (member_function_is_virtual): Declare new function. * include/abg-comparison.h (diff_category::{NON_VIRT_MEM_FUN_CHANGE_CATEGORY, VIRTUAL_MEMBER_CHANGE_CATEGORY}): New enumerators. (diff_category::EVERYTHING_CATEGORY): Adjust. (class_diff::{changed, deleted, inserted}_member_fns): Declare new member functions. * src/abg-comp-filter.cc (data_member_added_or_removed): Add missing comments. (has_non_virtual_mem_fn_change): New static predicate function. (harmless_filter::visit): Categorize non-virtual member function changes in a diff into NON_VIRT_MEM_FUN_CHANGE_CATEGORY. * src/abg-comparison.cc (TRAVERSE_MEM_FN_DIFF_NODE_AND_PROPAGATE_CATEGORY): New macro. (report_mem_header): Count filtered functions for added/deleted functions as well. (class_diff::priv::count_filtered_changed_mem_fns): Renamed priv::count_filtered_member_functions into this. Filter out changes to non-virtual member functions here. (class_diff::priv::count_filtered_{inserted, deleted}_mem_fns): New member functions. (class_diff::{deleted, inserted, changed}_member_fns): Define new member functions. (class_diff::report): Adjust count for filtered inserted/deleted member functions. Do not report NON_VIRT_MEM_FUN_CHANGE_CATEGORY if it's disallowed. (class_diff::traverse): Propagate only VIRTUAL_MEMBER_CHANGE_CATEGORY from member functions to their enclosing class. * src/abg-ir.cc (member_function_is_virtual): Define new functions. * tools/bidiff.cc (set_diff_context_from_opts): Adjust to add NON_VIRT_MEM_FUN_CHANGE_CATEGORY into the harmless group and VIRTUAL_MEMBER_CHANGE_CATEGORY into the harmful one. * tests/data/test-diff-filter/test0-report.txt: New test input. * tests/data/test-diff-filter/test10-report.txt: Likewise. * tests/data/test-diff-filter/test10-v0.cc: Likewise. * tests/data/test-diff-filter/test10-v0.o: Likewise. * tests/data/test-diff-filter/test10-v1.cc: Likewise. * tests/data/test-diff-filter/test10-v1.o: Likewise. * tests/data/test-diff-filter/test11-report.txt: Likewise. * tests/data/test-diff-filter/test11-v0.cc: Likewise. * tests/data/test-diff-filter/test11-v0.o: Likewise. * tests/data/test-diff-filter/test11-v1.cc: Likewise. * tests/data/test-diff-filter/test11-v1.o: Likewise. * tests/data/test-diff-filter/test2-report.txt: Likewise. * tests/data/test-diff-filter/test9-report.txt: Likewise. * tests/data/test-diff-filter/test9-v0.cc: Likewise. * tests/data/test-diff-filter/test9-v0.o: Likewise. * tests/data/test-diff-filter/test9-v1.cc: Likewise. * tests/data/test-diff-filter/test9-v1.o: Likewise. * tests/test-diff-filter.cc: Consume the test input above to run more tests. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-04-13 21:09:02 +00:00
bool
get_member_function_is_virtual(const function_decl&);
Filter non-virtual member fns insertions/deletions from class changes * include/abg-fwd.h (member_function_is_virtual): Declare new function. * include/abg-comparison.h (diff_category::{NON_VIRT_MEM_FUN_CHANGE_CATEGORY, VIRTUAL_MEMBER_CHANGE_CATEGORY}): New enumerators. (diff_category::EVERYTHING_CATEGORY): Adjust. (class_diff::{changed, deleted, inserted}_member_fns): Declare new member functions. * src/abg-comp-filter.cc (data_member_added_or_removed): Add missing comments. (has_non_virtual_mem_fn_change): New static predicate function. (harmless_filter::visit): Categorize non-virtual member function changes in a diff into NON_VIRT_MEM_FUN_CHANGE_CATEGORY. * src/abg-comparison.cc (TRAVERSE_MEM_FN_DIFF_NODE_AND_PROPAGATE_CATEGORY): New macro. (report_mem_header): Count filtered functions for added/deleted functions as well. (class_diff::priv::count_filtered_changed_mem_fns): Renamed priv::count_filtered_member_functions into this. Filter out changes to non-virtual member functions here. (class_diff::priv::count_filtered_{inserted, deleted}_mem_fns): New member functions. (class_diff::{deleted, inserted, changed}_member_fns): Define new member functions. (class_diff::report): Adjust count for filtered inserted/deleted member functions. Do not report NON_VIRT_MEM_FUN_CHANGE_CATEGORY if it's disallowed. (class_diff::traverse): Propagate only VIRTUAL_MEMBER_CHANGE_CATEGORY from member functions to their enclosing class. * src/abg-ir.cc (member_function_is_virtual): Define new functions. * tools/bidiff.cc (set_diff_context_from_opts): Adjust to add NON_VIRT_MEM_FUN_CHANGE_CATEGORY into the harmless group and VIRTUAL_MEMBER_CHANGE_CATEGORY into the harmful one. * tests/data/test-diff-filter/test0-report.txt: New test input. * tests/data/test-diff-filter/test10-report.txt: Likewise. * tests/data/test-diff-filter/test10-v0.cc: Likewise. * tests/data/test-diff-filter/test10-v0.o: Likewise. * tests/data/test-diff-filter/test10-v1.cc: Likewise. * tests/data/test-diff-filter/test10-v1.o: Likewise. * tests/data/test-diff-filter/test11-report.txt: Likewise. * tests/data/test-diff-filter/test11-v0.cc: Likewise. * tests/data/test-diff-filter/test11-v0.o: Likewise. * tests/data/test-diff-filter/test11-v1.cc: Likewise. * tests/data/test-diff-filter/test11-v1.o: Likewise. * tests/data/test-diff-filter/test2-report.txt: Likewise. * tests/data/test-diff-filter/test9-report.txt: Likewise. * tests/data/test-diff-filter/test9-v0.cc: Likewise. * tests/data/test-diff-filter/test9-v0.o: Likewise. * tests/data/test-diff-filter/test9-v1.cc: Likewise. * tests/data/test-diff-filter/test9-v1.o: Likewise. * tests/test-diff-filter.cc: Consume the test input above to run more tests. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-04-13 21:09:02 +00:00
bool
get_member_function_is_virtual(const function_decl_sptr&);
Filter non-virtual member fns insertions/deletions from class changes * include/abg-fwd.h (member_function_is_virtual): Declare new function. * include/abg-comparison.h (diff_category::{NON_VIRT_MEM_FUN_CHANGE_CATEGORY, VIRTUAL_MEMBER_CHANGE_CATEGORY}): New enumerators. (diff_category::EVERYTHING_CATEGORY): Adjust. (class_diff::{changed, deleted, inserted}_member_fns): Declare new member functions. * src/abg-comp-filter.cc (data_member_added_or_removed): Add missing comments. (has_non_virtual_mem_fn_change): New static predicate function. (harmless_filter::visit): Categorize non-virtual member function changes in a diff into NON_VIRT_MEM_FUN_CHANGE_CATEGORY. * src/abg-comparison.cc (TRAVERSE_MEM_FN_DIFF_NODE_AND_PROPAGATE_CATEGORY): New macro. (report_mem_header): Count filtered functions for added/deleted functions as well. (class_diff::priv::count_filtered_changed_mem_fns): Renamed priv::count_filtered_member_functions into this. Filter out changes to non-virtual member functions here. (class_diff::priv::count_filtered_{inserted, deleted}_mem_fns): New member functions. (class_diff::{deleted, inserted, changed}_member_fns): Define new member functions. (class_diff::report): Adjust count for filtered inserted/deleted member functions. Do not report NON_VIRT_MEM_FUN_CHANGE_CATEGORY if it's disallowed. (class_diff::traverse): Propagate only VIRTUAL_MEMBER_CHANGE_CATEGORY from member functions to their enclosing class. * src/abg-ir.cc (member_function_is_virtual): Define new functions. * tools/bidiff.cc (set_diff_context_from_opts): Adjust to add NON_VIRT_MEM_FUN_CHANGE_CATEGORY into the harmless group and VIRTUAL_MEMBER_CHANGE_CATEGORY into the harmful one. * tests/data/test-diff-filter/test0-report.txt: New test input. * tests/data/test-diff-filter/test10-report.txt: Likewise. * tests/data/test-diff-filter/test10-v0.cc: Likewise. * tests/data/test-diff-filter/test10-v0.o: Likewise. * tests/data/test-diff-filter/test10-v1.cc: Likewise. * tests/data/test-diff-filter/test10-v1.o: Likewise. * tests/data/test-diff-filter/test11-report.txt: Likewise. * tests/data/test-diff-filter/test11-v0.cc: Likewise. * tests/data/test-diff-filter/test11-v0.o: Likewise. * tests/data/test-diff-filter/test11-v1.cc: Likewise. * tests/data/test-diff-filter/test11-v1.o: Likewise. * tests/data/test-diff-filter/test2-report.txt: Likewise. * tests/data/test-diff-filter/test9-report.txt: Likewise. * tests/data/test-diff-filter/test9-v0.cc: Likewise. * tests/data/test-diff-filter/test9-v0.o: Likewise. * tests/data/test-diff-filter/test9-v1.cc: Likewise. * tests/data/test-diff-filter/test9-v1.o: Likewise. * tests/test-diff-filter.cc: Consume the test input above to run more tests. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-04-13 21:09:02 +00:00
bool
get_member_function_is_virtual(const function_decl*);
void
Make decl_base::get_context_rel() return a naked pointer Accessing the context relationship of declarations and setting some member properties appear to be high in performance profiles due to shared pointer handling. This patch makes the context relationship accessors return a naked pointer and also passes a bunch of shared pointer as references around. * include/abg-fwd.h (set_member_is_static): Add an overload that takes the member as a reference to a smart pointer. (set_member_function_{is_dtor, is_ctor, is_const, vtable_offset, is_virtual}): Pass the member function as a reference. (set_member_function_is_const, set_member_function_is_virtual): Pass the member function as a non-const reference. * include/abg-ir.h (decl_base::get_context_rel): Return a naked pointer. (set_member_is_static, set_member_function_is_virtual): Adjust this friend declaration. (set_member_access_specifier): Add an overload that takes a reference to the member. Pass a reference to smart pointer to the other overload. (set_member_function_is_{is_ctor,is_dtor,is_const,is_virtual,vtable_offset}): Take a non-const reference to function_decl. * src/abg-ir.cc (decl_base::get_context_rel): Likewise. (equals(const decl_base&, const decl_base&, change_kind*)): Adjust. (equals(const var_decl&, const var_decl&, change_kind*)): Likewise. (get_member_access_specifier, get_member_is_static) (set_data_member_offset, get_data_member_offset) (set_data_member_is_laid_out, get_data_member_is_laid_out) (get_member_function_is_ctor, set_member_function_is_ctor) (get_member_function_is_dtor, set_member_function_is_dtor) (get_member_function_is_const, set_member_function_is_const) (get_member_function_vtable_offset) (set_member_function_vtable_offset) (get_member_function_is_virtual, set_member_function_is_virtual): Likewise. (set_member_access_specifier): Add an overload that takes a reference to decl_base. (set_member_is_static, set_member_function_{is_dtor, is_ctor, is_const, vtable_offset, is_virtual}): Pass the member function as a reference.): Add an overload that takes the member as a reference, and write the older overload in terms of the new one. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-10 10:45:46 +00:00
set_member_function_is_virtual(function_decl&, bool);
void
set_member_function_is_virtual(const function_decl_sptr&, bool);
type_base_sptr
strip_typedef(const type_base_sptr);
Add a COMPATIBLE_TYPE_CHANGE_CATEGORY to bidiff --no-harmless * include/abg-comparison.h (diff_category::COMPATIBLE_TYPE_CHANGE_CATEGORY): New enumerator. (operator|=(diff_category&, diff_category)): New declaration. * include/abg-fwd.h (is_typedef, strip_typedef) (types_are_compatible): New declarations. * include/abg-ir.h (operator==(const decl_base_sptr, const decl_base_sptr)): Added the consts here. (operator==(const type_base_sptr, const type_base_sptr)): New declaration. * src/abg-comp-filter.cc (is_compatible_change): New static function. (harmless_filter::visit): Detect compatible changes and add the sub-tree into the new COMPATIBLE_TYPE_CHANGE_CATEGORY if applicable. Cleanup the logic. * src/abg-comparison.cc (operator|=(diff_category&, diff_category)): Define new function. (operator==(const decl_base_sptr l, const decl_base_sptr r)): Add consts. (operator==(const type_base_sptr l, const type_base_sptr r)): Define new operator. (is_typedef, strip_typedef, types_are_compatible): New function definitions. * tests/data/test-diff-filter/test3-report.txt: New test report reference. * tests/data/test-diff-filter/test3-v0.cc: Source code for new test input. * tests/data/test-diff-filter/test3-v0.o: New test input. * tests/data/test-diff-filter/test3-v1.cc: Source code for new test input. * tests/data/test-diff-filter/test3-v1.o: New test input. * tests/test-diff-filter.cc: Adjust to consume the new tests inputs above. * tools/bidiff.cc: Add the new COMPATIBLE_TYPE_CHANGE_CATEGORY into the --harmless group. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-04-02 15:23:56 +00:00
type_base_sptr
peel_typedef_type(const type_base_sptr&);
Make type_has_non_canonicalized_subtype() tighter type_has_non_canonicalized_subtype() gives up too quickly. For instance, suppose it's looking a type 'foo'. If foo has no canonicalized type yet and has a data member which type is foo* (for instance), then type_has_non_canonicalized_subtype() just sees that type 'foo*' has no canonicalized type, and so it returns, saying that he found a non-canonicalized subtype for foo. In that case though, what type_has_non_canonicalized_subtype() should do is detect that foo* is a pointer to foo itself, so it shouldn't count as a non-canonicalized sub-type. It should keep going and look for other meaningful non-canonicalized sub-types. And this what this patch does. It changes the sub-type walker that type_has_non_canonicalized_subtype() uses, so that - it doesn't flag sub-types that refer to the type we are looking at as non-canonicalized sub-types. This is for sub-types that are combinations of pointers, references and typedefs. - it doesn't consider sub-types of member functions of the type we are looking at, unless that member function is virtual. The result is that more types are canonicalized early during DWARF reading, and so there are less types to store on the side for late canonicalization. This can have a big impact on, e.g, C++ libraries with tens of thousands of types. * include/abg-fwd.h (is_typedef, is_pointer_type) (is_reference_type): Declare new overloads. (peel_typedef_type): Renamed get_typedef_underlying_type into this. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Declare new functions. * src/abg-ir.cc (peel_typedef_type): Renamed get_typedef_underlying_type into this. (is_typedef, is_pointer_type, is_reference_type): Define new overloads. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Define new functions. (non_canonicalized_subtype_detector::has_non_canonical_type_): Make the type of this data member be a type_base*, not a bool. This is so that we can return the first non-canonicalized subtype of the type we are looking at. (non_canonicalized_subtype_detector::non_canonicalized_subtype_detector): Adjust the data member initialization. (non_canonicalized_subtype_detector::visit_begin): Add an overload for function_decl*, to avoid looking into non-virtual member functions. In the overload for type_base*, peel typedefs, pointers and reference of each sub-type that has no canonical type, to see if refers to the type we are actually walking. If yes, then keep going. (type_has_non_canonicalized_subtype): Return the non-canonicalized sub-type found. * src/abg-comparison.cc (type_suppression::suppresses_diff): Adjust for the get_typedef_underlying_type -> peel_typedef_type renaming. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-19 14:15:28 +00:00
const type_base*
peel_typedef_type(const type_base*);
type_base_sptr
peel_pointer_type(const type_base_sptr&);
Make type_has_non_canonicalized_subtype() tighter type_has_non_canonicalized_subtype() gives up too quickly. For instance, suppose it's looking a type 'foo'. If foo has no canonicalized type yet and has a data member which type is foo* (for instance), then type_has_non_canonicalized_subtype() just sees that type 'foo*' has no canonicalized type, and so it returns, saying that he found a non-canonicalized subtype for foo. In that case though, what type_has_non_canonicalized_subtype() should do is detect that foo* is a pointer to foo itself, so it shouldn't count as a non-canonicalized sub-type. It should keep going and look for other meaningful non-canonicalized sub-types. And this what this patch does. It changes the sub-type walker that type_has_non_canonicalized_subtype() uses, so that - it doesn't flag sub-types that refer to the type we are looking at as non-canonicalized sub-types. This is for sub-types that are combinations of pointers, references and typedefs. - it doesn't consider sub-types of member functions of the type we are looking at, unless that member function is virtual. The result is that more types are canonicalized early during DWARF reading, and so there are less types to store on the side for late canonicalization. This can have a big impact on, e.g, C++ libraries with tens of thousands of types. * include/abg-fwd.h (is_typedef, is_pointer_type) (is_reference_type): Declare new overloads. (peel_typedef_type): Renamed get_typedef_underlying_type into this. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Declare new functions. * src/abg-ir.cc (peel_typedef_type): Renamed get_typedef_underlying_type into this. (is_typedef, is_pointer_type, is_reference_type): Define new overloads. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Define new functions. (non_canonicalized_subtype_detector::has_non_canonical_type_): Make the type of this data member be a type_base*, not a bool. This is so that we can return the first non-canonicalized subtype of the type we are looking at. (non_canonicalized_subtype_detector::non_canonicalized_subtype_detector): Adjust the data member initialization. (non_canonicalized_subtype_detector::visit_begin): Add an overload for function_decl*, to avoid looking into non-virtual member functions. In the overload for type_base*, peel typedefs, pointers and reference of each sub-type that has no canonical type, to see if refers to the type we are actually walking. If yes, then keep going. (type_has_non_canonicalized_subtype): Return the non-canonicalized sub-type found. * src/abg-comparison.cc (type_suppression::suppresses_diff): Adjust for the get_typedef_underlying_type -> peel_typedef_type renaming. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-19 14:15:28 +00:00
const type_base*
peel_pointer_type(const type_base*);
type_base_sptr
peel_reference_type(const type_base_sptr&);
Make type_has_non_canonicalized_subtype() tighter type_has_non_canonicalized_subtype() gives up too quickly. For instance, suppose it's looking a type 'foo'. If foo has no canonicalized type yet and has a data member which type is foo* (for instance), then type_has_non_canonicalized_subtype() just sees that type 'foo*' has no canonicalized type, and so it returns, saying that he found a non-canonicalized subtype for foo. In that case though, what type_has_non_canonicalized_subtype() should do is detect that foo* is a pointer to foo itself, so it shouldn't count as a non-canonicalized sub-type. It should keep going and look for other meaningful non-canonicalized sub-types. And this what this patch does. It changes the sub-type walker that type_has_non_canonicalized_subtype() uses, so that - it doesn't flag sub-types that refer to the type we are looking at as non-canonicalized sub-types. This is for sub-types that are combinations of pointers, references and typedefs. - it doesn't consider sub-types of member functions of the type we are looking at, unless that member function is virtual. The result is that more types are canonicalized early during DWARF reading, and so there are less types to store on the side for late canonicalization. This can have a big impact on, e.g, C++ libraries with tens of thousands of types. * include/abg-fwd.h (is_typedef, is_pointer_type) (is_reference_type): Declare new overloads. (peel_typedef_type): Renamed get_typedef_underlying_type into this. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Declare new functions. * src/abg-ir.cc (peel_typedef_type): Renamed get_typedef_underlying_type into this. (is_typedef, is_pointer_type, is_reference_type): Define new overloads. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Define new functions. (non_canonicalized_subtype_detector::has_non_canonical_type_): Make the type of this data member be a type_base*, not a bool. This is so that we can return the first non-canonicalized subtype of the type we are looking at. (non_canonicalized_subtype_detector::non_canonicalized_subtype_detector): Adjust the data member initialization. (non_canonicalized_subtype_detector::visit_begin): Add an overload for function_decl*, to avoid looking into non-virtual member functions. In the overload for type_base*, peel typedefs, pointers and reference of each sub-type that has no canonical type, to see if refers to the type we are actually walking. If yes, then keep going. (type_has_non_canonicalized_subtype): Return the non-canonicalized sub-type found. * src/abg-comparison.cc (type_suppression::suppresses_diff): Adjust for the get_typedef_underlying_type -> peel_typedef_type renaming. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-19 14:15:28 +00:00
const type_base*
peel_reference_type(const type_base*);
const type_base_sptr
peel_array_type(const type_base_sptr&);
const type_base*
peel_array_type(const type_base*);
const type_base*
peel_qualified_type(const type_base*);
const type_base_sptr
peel_qualified_type(const type_base_sptr&);
Better detect when diff nodes only carry local type changes For some fine grain redundancy filtering, we need to know when a diff node carries *only* a basic type change. This is because basic type changes should not be marked as redundant; we want to see all of them -- unlike for class or union (user defined) type changes. And so to know if a diff node carries only a basic type change, we need to know if a diff node only carries a local type change. If it carries only a type change, we can safely just look at that type change and see if it's a basic type change or not. So, we then need to know what kind of local changes a diff node carries: type change or non-type change. That way, we can analyze the local changes a node carries and infer that it only carries a local type change or if it also carries a non-type change. This patch thus changes the diff::has_local_changes() pure virtual member function to make it return the enum change_kind bitmask, which describes the different kinds of local changes the diff node has. Note that two new bit values were added to that enum: LOCAL_TYPE_CHANGE_KIND and LOCAL_NON_TYPE_CHANGE_KIND. The first one says that the diff node carries a local type change, while the second one says that the diff node carries a local non-type change kind. The various implementations of that interface are thus amended to make them return the right bitmask. To do this, the patch updates the various 'equals' overloads to make them return the proper enum change_kind bitmap with the LOCAL_TYPE_CHANGE_KIND and LOCAL_NON_TYPE_CHANGE_KIND set, if need be. * include/abg-comparison.h ({diff, type_diff_base, decl_diff_base, distinct_diff, var_diff, pointer_diff, reference_diff, array_diff, qualified_type, enum_diff, class_or_union_diff, class_diff, base_diff, scope_diff, fn_parm_diff, function_type_diff, function_decl_diff, typedef_diff, translation_unit_diff}::has_local_changes): Return an enum change_kind, rather than just a bool. (is_diff_of_basic_type): Declare an overload that takes a boolean flag. (is_qualified_type_diff, peel_pointer_diff, peel_reference_diff) (peel_qualified_type, peel_pointer_or_qualified_type): Declare new functions * include/abg-fwd.h (peel_qualified_type): * include/abg-ir.h (enum change_kind::{LOCAL_TYPE_CHANGE_KIND, LOCAL_NON_TYPE_CHANGE_KIND, ALL_LOCAL_CHANGES_MASK}): Add these three new enumerators. * src/abg-comparison.cc ({distinct_diff, var_diff, pointer_diff, array_diff, reference_diff, qualified_type_diff, enum_diff, class_or_union_diff, class_diff, base_diff, scope_diff, fn_parm_diff, function_type_diff, function_decl_diff, type_decl_diff, typedef_diff, translation_unit_diff}::has_local_changes): Adjust to return an enum change_kind, rather than just a bool. (has_local_type_change_only): Define new functions. (has_basic_type_change_only): Use the new has_local_type_change_only function and the new overload for is_diff_of_basic_type. (is_diff_of_basic_type): Define an overload that takes a boolean flag. (is_qualified_type_diff, peel_pointer_diff, peel_reference_diff) (peel_qualified_type, peel_pointer_or_qualified_type): Define new functions. * src/abg-ir.cc (equals): In the overloads for decl_base, scope_decl, type_base, qualified_type_diff, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, function_decl, function_decl::parameter, class_or_union, class_decl::base_spec and class_decl, properly set the new abigail::ir::{LOCAL_CHANGE_KIND, LOCAL_NON_TYPE_CHANGE_KIND, LOCAL_TYPE_CHANGE_KIND} bits. (types_have_similar_structure): Peel qualified types and typedefs off, first thing. (peel_qualified_or_typedef_type): Define new function. * 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. * tests/data/test-diff-filter/libtest45-basic-type-change-report-{0,1}.txt: New reference test reports. * tests/data/test-diff-filter/libtest45-basic-type-change-v{0,1}.so: New input test binaries. * tests/data/test-diff-filter/test45-basic-type-change-v{0,1}.cc: Source code of the input test binaries above. * tests/data/Makefile.am: Add the new test file above to source distribution. * tests/test-diff-filter.cc: Add the test input above to the test harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-23 09:43:29 +00:00
type_base*
peel_qualified_or_typedef_type(const type_base* type);
type_base_sptr
Do not mark "distinct" diff nodes as being redundant When a char is changed into a const char several times in different spots of the type graph, we want to see all the occurence of those changes. Generalizing this in Abigail parlance, we'd say that we want to see all occurences of distinct diff nodes, so we don't want to mark them as being redundant. Right now, libabigail will only show the first occurence of that change will flag subsequent onces as being redundant, by virtue of the redundancy marking pass. This patch avoids marking distinct diff nodes as being redundant. This patch is part of the set of patches whose titles are: Do not show decl-only-to-def changes in the leaf reporter Overhaul of the report diff stats summary Do not mark "distinct" diff nodes as being redundant Fix meaning of "harmless name change" to avoid overfiltering Better handle category propagation of pointer changes Improve function changes reporting in leaf and default mode Don't filter out typedef changes with redundant underlying type changes Only show leaf type changes in the leaf type changes section Fix leaf report of class data member changes Always show redundant changes in leaf mode Avoid reporting an enum change if it has already been reported When we say an a change was reported earlier give its source location [abipkgdiff]: in leaf mode we always show redundant changes Update tests for the "better leaf mode redundancy management" patchset * include/abg-comp-filter.h (is_mostly_distinct_diff): Declare new function. * include/abg-fwd.h (peel_typedef_pointer_or_reference_type): Take a boolean to decide to peel qualified types or not. * src/abg-comp-filter.cc (is_mostly_distinct_diff): Define this function. * src/abg-comparison.cc (redundancy_marking_visitor::visit_begin): Do not mark distinct_diff nodes as being redundant. * src/abg-ir.cc (peel_typedef_pointer_or_reference_type): Implement taking a boolean to decide to peel qualified types or not. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-04-11 10:45:25 +00:00
peel_typedef_pointer_or_reference_type(const type_base_sptr,
bool peel_qualified_type = true);
Make type_has_non_canonicalized_subtype() tighter type_has_non_canonicalized_subtype() gives up too quickly. For instance, suppose it's looking a type 'foo'. If foo has no canonicalized type yet and has a data member which type is foo* (for instance), then type_has_non_canonicalized_subtype() just sees that type 'foo*' has no canonicalized type, and so it returns, saying that he found a non-canonicalized subtype for foo. In that case though, what type_has_non_canonicalized_subtype() should do is detect that foo* is a pointer to foo itself, so it shouldn't count as a non-canonicalized sub-type. It should keep going and look for other meaningful non-canonicalized sub-types. And this what this patch does. It changes the sub-type walker that type_has_non_canonicalized_subtype() uses, so that - it doesn't flag sub-types that refer to the type we are looking at as non-canonicalized sub-types. This is for sub-types that are combinations of pointers, references and typedefs. - it doesn't consider sub-types of member functions of the type we are looking at, unless that member function is virtual. The result is that more types are canonicalized early during DWARF reading, and so there are less types to store on the side for late canonicalization. This can have a big impact on, e.g, C++ libraries with tens of thousands of types. * include/abg-fwd.h (is_typedef, is_pointer_type) (is_reference_type): Declare new overloads. (peel_typedef_type): Renamed get_typedef_underlying_type into this. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Declare new functions. * src/abg-ir.cc (peel_typedef_type): Renamed get_typedef_underlying_type into this. (is_typedef, is_pointer_type, is_reference_type): Define new overloads. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Define new functions. (non_canonicalized_subtype_detector::has_non_canonical_type_): Make the type of this data member be a type_base*, not a bool. This is so that we can return the first non-canonicalized subtype of the type we are looking at. (non_canonicalized_subtype_detector::non_canonicalized_subtype_detector): Adjust the data member initialization. (non_canonicalized_subtype_detector::visit_begin): Add an overload for function_decl*, to avoid looking into non-virtual member functions. In the overload for type_base*, peel typedefs, pointers and reference of each sub-type that has no canonical type, to see if refers to the type we are actually walking. If yes, then keep going. (type_has_non_canonicalized_subtype): Return the non-canonicalized sub-type found. * src/abg-comparison.cc (type_suppression::suppresses_diff): Adjust for the get_typedef_underlying_type -> peel_typedef_type renaming. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-19 14:15:28 +00:00
type_base*
Do not mark "distinct" diff nodes as being redundant When a char is changed into a const char several times in different spots of the type graph, we want to see all the occurence of those changes. Generalizing this in Abigail parlance, we'd say that we want to see all occurences of distinct diff nodes, so we don't want to mark them as being redundant. Right now, libabigail will only show the first occurence of that change will flag subsequent onces as being redundant, by virtue of the redundancy marking pass. This patch avoids marking distinct diff nodes as being redundant. This patch is part of the set of patches whose titles are: Do not show decl-only-to-def changes in the leaf reporter Overhaul of the report diff stats summary Do not mark "distinct" diff nodes as being redundant Fix meaning of "harmless name change" to avoid overfiltering Better handle category propagation of pointer changes Improve function changes reporting in leaf and default mode Don't filter out typedef changes with redundant underlying type changes Only show leaf type changes in the leaf type changes section Fix leaf report of class data member changes Always show redundant changes in leaf mode Avoid reporting an enum change if it has already been reported When we say an a change was reported earlier give its source location [abipkgdiff]: in leaf mode we always show redundant changes Update tests for the "better leaf mode redundancy management" patchset * include/abg-comp-filter.h (is_mostly_distinct_diff): Declare new function. * include/abg-fwd.h (peel_typedef_pointer_or_reference_type): Take a boolean to decide to peel qualified types or not. * src/abg-comp-filter.cc (is_mostly_distinct_diff): Define this function. * src/abg-comparison.cc (redundancy_marking_visitor::visit_begin): Do not mark distinct_diff nodes as being redundant. * src/abg-ir.cc (peel_typedef_pointer_or_reference_type): Implement taking a boolean to decide to peel qualified types or not. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-04-11 10:45:25 +00:00
peel_typedef_pointer_or_reference_type(const type_base* type,
bool peel_qualified_type = true);
Make applying supp specs through pointer access look through typedefs Consider the declaration of the exported function bar() below: struct _OpaqueType {int member;}; typedef struct _OpaqueType Type; void bar(Type*); Once the *definition of struct _OpaqueType and bar() are compiled into a shared library, if a layout change happens to struct _OpaqueType, then abidiff rightfully reports that bar() is impacted by the layout change to struct _OpaqueType. But then, the following suppression specification won't silence the ABI change report: [suppress_type] name = _OpaqueType type_kind = struct accessed_through = pointer This is because strictly speaking, it's not struct _OpaqueType that is accessed through a pointer, from function bar(); it's the type 'Type', (which is a typedef of struct _OpaqueType) that is accessed though a pointer. But then, as 'Type' and 'struct _OpaqueType' are the same type (modulo the typedef), this behaviour is not super useful. It would be more interesting if the suppression specification could silence the ABI change report. And this is what this patch does. * include/abg-comparison.h (type_suppression::suppresses_type): Declare new member function. (get_typedef_diff_underlying_type_diff): Declare new function. * include/abg-fwd.h (get_typedef_underlying_type): Likewise. * src/abg-comparison.cc (type_suppression::suppresses_type): Define new member function. (get_typedef_diff_underlying_type_diff): Define new function. (type_suppression::suppresses_diff): After looking through the different kind of access methods, use the new type_suppression::suppresses_type(), rather than doing lots of stuff ourselves here. But then, if the suppression doesn't apply to the subjects of the diff, look through typedefs and try to apply the suppression again. * src/abg-ir.cc (get_typedef_underlying_type): Define new function. * tests/data/test-diff-suppr/libtest25-typedef-v{0,1}.so: New binary test input files. * tests/data/test-diff-suppr/test25-typedef-v{0,1}.c: Source code for the binary test input files above. * tests/data/test-diff-suppr/test25-typedef-report-{0, 1}.txt: New test input files. * tests/data/test-diff-suppr/test25-typedef-suppr-0.txt: New test input file. * tests/data/Makefile.am: Add the new test material to the source distribution. * tests/test-diff-suppr.cc (in_out_specs): Add the test inputs above to the set of test inputs this harness has to run over. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-31 10:58:08 +00:00
Serialize canonical types to avoid testing if types have been emitted When emitting abixml, profiling shows that we spend a great deal of time testing if a given type has been emitted already, to avoid emitting a given type more than once. This makes the serialization phase take more time than the binary analysis phase! This patch leverages the fact that we already have the set of canonical types in the system. While emitting that set entirely, we don't need to test if a type has been emitted already because we know by definition that every type is present just once in that set, more or less. OK, because there are also types that don't have canonical types (for instance, declaration-only class/structs), we'll still have to check of those types have already been emitted, but this is a very small set to handle. The patch thus organizes the canonical types per scope, so that when emitting a scope and the canonical types within it, the type is emitted in its correct namespace. Then, when emitting a translation unit and each namespaces in it, the patch emits the canonical types of those namespaces. The patch arranges for some ancillary things that are needed to make the whole picture be coherent enough for things to keep working. Testing shows that we gained ~ 30% of performance by doing this, while analysing the whole linux kernel 5.1 version. We went from ~ 3m30s minutes to less than 2m30s. With this patch, the serialization phase now takes less time than the analysis time. * include/abg-fwd.h (is_decl_slow) (peel_pointer_or_reference_type): Declare new functions. * include/abg-ir.h (struct canonical_type_hash): Define new type. (type_base_ptr_set_type, type_base_ptrs_type) (type_base_sptrs_type, canonical_type_sptr_set_type): Define new typedefs. (environment::get_canonical_types_map): Declare new member function. (scope_decl::{get_canonical_types, get_sorted_canonical_types}): Declare new member functions. * src/abg-ir.cc (is_ptr_ref_or_qual_type) (peel_pointer_or_reference_type, is_decl_slow): Define new functions. (environment::{get_canonical_types_map}): Define new member functions. (canonical_type_hash::operator()): Likewise. (scope_decl::{get_canonical_types, get_sorted_canonical_types}): Likewise. (struct type_topo_comp): Define new comparison functor type. (environment::{sorted_canonical_types_}): Define new data member. (scope_decl::priv::{canonical_types_, sorted_canonical_types_}): Likewise. (scope_decl::is_empty): Take the presence of canonical types into account when determining if a scope is empty or not. (is_decl): Make this work for cases where the artifact at hand is a type which has a declaration, as opposed to being a pure declaration like a variable or a function. (canonicalize): Add the canonical type the list of canonical types of its scope. * src/abg-dwarf-reader.cc (read_context::die_is_in_cplus_plus): Define new member function. * src/abg-writer.cc (write_type, write_canonical_types_of_scope): Define new static functions. (fn_type_ptr_set_type): Define new typedef. (write_context::{m_referenced_fn_types_set, m_referenced_non_canonical_types_set}): Add new data members. (write_context::m_referenced_types_set): Renamed m_referenced_types_map into this. (write_context::get_referenced_types): Adjust. (write_context::get_referenced_{function_types, non_canonical_types}): (write_context::record_type_as_referenced): Adjust to add the referenced type in the proper set which would be one of the three following: write_context::{get_referenced_types, get_referenced_function_types, get_referenced_non_canonical_types}. (write_context::{type_is_referenced, clear_referenced}): Adjust. (write_translation_unit): Use the new write_canonical_types_of_scope. Also emit declaration-only classes that have member types. Do not test if a given type of a given scope has been emitted, in general, as this was super slow given the number of types. Emit referenced function types (as these don't belong to any scope). Rather than using the expensive "is_function_type" on *all* the referenced types, just walk the set write_context::get_referenced_function_types. Likewise, rather than using type_base::get_naked_canonical_type on *all* the referenced types, just walk the set write_context::get_referenced_non_canonical_types (write_class): Use write_canonical_types_of_scope here. * tools/abilint.cc (main): Support linting corpus group abixml files. * tests/data/test-annotate/libtest23.so.abi: Adjust. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test-anonymous-members-0.o.abi: Likewise. * tests/data/test-annotate/test0.abi: Likewise. * tests/data/test-annotate/test1.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test2.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-annotate/test4.so.abi: Likewise. * tests/data/test-annotate/test6.so.abi: Likewise. * tests/data/test-annotate/test7.so.abi: Likewise. * tests/data/test-annotate/test8-qualified-this-pointer.so.abi: Likewise. * tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi: Likewise. * tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise. * tests/data/test-read-dwarf/PR24378-fn-is-not-scope.abi: Likewise. * tests/data/test-read-dwarf/libtest23.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-read-dwarf/test0.abi: Likewise. * tests/data/test-read-dwarf/test1.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test2.so.abi: Likewise. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/data/test-read-dwarf/test4.so.abi: Likewise. * tests/data/test-read-dwarf/test6.so.abi: Likewise. * tests/data/test-read-dwarf/test7.so.abi: Likewise. * tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi: Likewise. * tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise. * tests/data/test-read-write/test10.xml: Likewise. * tests/data/test-read-write/test14.xml: Likewise. * tests/data/test-read-write/test15.xml: Likewise. * tests/data/test-read-write/test17.xml: Likewise. * tests/data/test-read-write/test18.xml: Likewise. * tests/data/test-read-write/test19.xml: Likewise. * tests/data/test-read-write/test2.xml: Likewise. * tests/data/test-read-write/test20.xml: Likewise. * tests/data/test-read-write/test21.xml: Likewise. * tests/data/test-read-write/test22.xml: Likewise. * tests/data/test-read-write/test23.xml: Likewise. * tests/data/test-read-write/test24.xml: Likewise. * tests/data/test-read-write/test25.xml: Likewise. * tests/data/test-read-write/test26.xml: Likewise. * tests/data/test-read-write/test27.xml: Likewise. * tests/data/test-read-write/test28-without-std-fns-ref.xml: Likewise. * tests/data/test-read-write/test28-without-std-vars-ref.xml: Likewise. * tests/data/test-read-write/test3.xml: Likewise. * tests/data/test-read-write/test6.xml: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-08-02 15:06:37 +00:00
type_base*
peel_pointer_or_reference_type(const type_base *type,
bool peel_qualified_type = true);
Initial implementation of a --leaf-changes-only option to abidiff 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>
2017-08-02 16:00:23 +00:00
string
get_name(const type_or_decl_base*, bool qualified = true);
Support diff/reporting for functions & better diff/report in general * include/abg-ir.h ({decl_base, class_decl, function_decl}::get_pretty_representation): New virtual member to get a pretty string name for decls & types. (class_decl::parameter): Add an index to the parameter type. (class_decl::parameter::parameter): Update the constructor for the change above. (class_decl::parameter::{get_index, set_index}): Accessors for the new index. (class_decl::parameter::operator==): Take in account the index. (function_type::append_parameter): Set the index of the parameter here. * include/abg-fwd.h (get_type_name): New declaration. * src/abg-ir.cc (get_type_name): New definition. ({decl_base, function_decl, class_decl}::get_pretty_representation): New implementations. (method_type::set_class_type): Update this to set function parameter's index by default. (function_decl::append_parameters): Use the append_parameter method from function_type. * include/abg-comparison.h (class function_decl_diff): New type declaration. * src/abg-comparison.cc (compute_diff_for_decls, compute_diff): New definitions. ({pointer_diff, class_diff, scope_diff}::report): Use the new get_pretty_representation. Output a prettier report. (function_decl_diff::priv): New type. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at, ensure_lookup_tables_populated, function_decl_diff, first_function_decl, second_function_decl, changed_parms, removed_parms, added_parms, length, report}): New member function definitions. * src/abg-hash.cc (function_decl::parameter::hash): Update this to take the index in account. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2013-10-19 14:33:40 +00:00
string
get_name(const type_or_decl_base_sptr&,
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
bool qualified = true);
location
get_location(const type_base_sptr& type);
location
get_location(const decl_base_sptr& decl);
string
build_qualified_name(const scope_decl* scope, const string& name);
string
build_qualified_name(const scope_decl* scope,
const type_base_sptr& type);
More type degradation fixes (from DWARF to abixml) The series of fixes to make "abidw foo > foo.abi && abidiff foo foo.abi" work continues. On a binary submitted as part of bug 18904, I am still seeing type degradation. This patch addresses the different cases of degradation that are happening. * include/abg-fwd.h (get_type_scope): Declare new function. * src/abg-hash.cc (var_decl::hash::operator()): Do not cache the hash because that can alter the hash computing of a larger type which embeds a var decl as a member declaration. This is especially true if the var decl indirectly references the larger type. The only way to cache the value of a var decl would be to wait after all canonical types have been computed. We'd then seal all types. After that sealing happens, we can cache var decls starting from the top-level ones. (function_decl::hash::operator()): Likewise. * src/abg-ir.cc (get_type_scope): Define new functions. * src/abg-reader.cc (read_is_declaration_only): Declare this function earlier. (typedef const_types_map_it): Adjust this to make it point to a map of string and vector of types, as opposed to a map to string and type as it was before. (typedef types_map_it): New typedef. (read_context::map_id_and_node): Map a type id to the last xmlNodePtr that represent a *declaration*. That gives more leeway to the declaration resolution code to choose the right definition later. Otherwise, there are cases where the wrong definition. By wrong definition, I mean a definition that is different from the one chosen by the DWARF reading code, for a given declaration. Basically for a given ABI corpus, a type declaration resolve to the first definition seen in the corpus. (read_context::get_all_type_decls): Define new member function. (read_context::types_equal): Use qualified names only if both types have a scope. (read_context::key_type_decl): Now a given ID is associated to *all* the declarations and definition that have that ID. (read_translation_unit_from_input): Make sure the current corpus node points to the right node. (build_class_decl): Resolve class declarations to the first definition seen in the corpus. Key a type decl before reading its members as a reading a member can request the current decl. No need to try and canonicalize a member type, as build_class_decl() does that already. * tests/data/test-read-dwarf/test16-pr18904.so: New test binary input. * tests/data/test-read-dwarf/test16-pr18904.so.abi: New test output reference. * tests/test-read-dwarf.cc: Run the test above. * tests/data/Makefile.am: Add the new test input to source distribution. * tests/data/test-abidiff/test-PR18791-report0.txt: Adjust. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-02 11:41:34 +00:00
scope_decl*
get_type_scope(type_base*);
scope_decl*
get_type_scope(const type_base_sptr&);
More type degradation fixes (from DWARF to abixml) The series of fixes to make "abidw foo > foo.abi && abidiff foo foo.abi" work continues. On a binary submitted as part of bug 18904, I am still seeing type degradation. This patch addresses the different cases of degradation that are happening. * include/abg-fwd.h (get_type_scope): Declare new function. * src/abg-hash.cc (var_decl::hash::operator()): Do not cache the hash because that can alter the hash computing of a larger type which embeds a var decl as a member declaration. This is especially true if the var decl indirectly references the larger type. The only way to cache the value of a var decl would be to wait after all canonical types have been computed. We'd then seal all types. After that sealing happens, we can cache var decls starting from the top-level ones. (function_decl::hash::operator()): Likewise. * src/abg-ir.cc (get_type_scope): Define new functions. * src/abg-reader.cc (read_is_declaration_only): Declare this function earlier. (typedef const_types_map_it): Adjust this to make it point to a map of string and vector of types, as opposed to a map to string and type as it was before. (typedef types_map_it): New typedef. (read_context::map_id_and_node): Map a type id to the last xmlNodePtr that represent a *declaration*. That gives more leeway to the declaration resolution code to choose the right definition later. Otherwise, there are cases where the wrong definition. By wrong definition, I mean a definition that is different from the one chosen by the DWARF reading code, for a given declaration. Basically for a given ABI corpus, a type declaration resolve to the first definition seen in the corpus. (read_context::get_all_type_decls): Define new member function. (read_context::types_equal): Use qualified names only if both types have a scope. (read_context::key_type_decl): Now a given ID is associated to *all* the declarations and definition that have that ID. (read_translation_unit_from_input): Make sure the current corpus node points to the right node. (build_class_decl): Resolve class declarations to the first definition seen in the corpus. Key a type decl before reading its members as a reading a member can request the current decl. No need to try and canonicalize a member type, as build_class_decl() does that already. * tests/data/test-read-dwarf/test16-pr18904.so: New test binary input. * tests/data/test-read-dwarf/test16-pr18904.so.abi: New test output reference. * tests/test-read-dwarf.cc: Run the test above. * tests/data/Makefile.am: Add the new test input to source distribution. * tests/data/test-abidiff/test-PR18791-report0.txt: Adjust. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-02 11:41:34 +00:00
Implement string interning for Libabigail This patch implements string interning optimization. One can read about the principles of this optimization at https://en.wikipedia.org/wiki/String_interning. The patch introduces an abigail::interned_string type, as well as an abigail::interned_string_pool type. Each environment type owns a string pool and strings are interned in that pool for all types and decls of that environments. The interned_string has methods to interact seemingly with std::string including a hashing function. Of course hashing and comparing interned_string is faster than for std::string. To enable ABI artifacts to intern strings, each constructor of ABI artifacts now takes the environment it's constructed in as parameter. From the environment, it can thus use the interned string pool. The patch then changes declaration names to be of type interned_string, and performs the necessary adjustments. The hash maps that hash strings coming from those declaration names are adjusted to hash interned_string. * include/Makefile.am: Add the new abg-interned-str.h file to source distribution. * include/abg-corpus.h (corpus::corpus): Re-arrange the order of * src/abg-corpus.cc (corpus::exported_decls_builder::priv::get_id): Return interned_string rather than std::string. (corpus::corpus): Re-arrange the order of parameters: take an environment as first parameter. parameters: take an environment as first parameter. * include/abg-dwarf-reader.h (lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Likewise. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab) (lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab) (lookup_symbol_from_elf, lookup_public_function_symbol_from_elf) (lookup_public_variable_symbol_from_elf, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Take an environment as first parameter and adjust. (build_translation_unit_and_add_to_ir) (build_namespace_decl_and_add_to_ir, build_type_decl) (build_enum_type, finish_member_function_reading) (build_class_type_and_add_to_ir, build_function_type) (read_debug_info_into_corpus, read_corpus_from_elf): Adjust. * include/abg-fwd.h: Include abg-interned-str.h (get_type_name, get_function_type_name, get_method_type_name): Return a interned_string, rather than a std::string. * include/abg-interned-str.h: New declarations for interned strings and their pool. * include/abg-ir.h (environment::intern): Declare new method. (elf_symbol::{g,s}et_environment): Likewise. (type_or_decl_base::type_or_decl_base): Make the default constructor private. ({translation, type_or_decl_base}::set_environment) (set_environment_for_artifact): Take a const environment*. (elf_symbol::elf_symbol) (elf_symbol::create) (type_or_decl_base::type_or_decl_base) (translation::translation, decl_base::decl_base) (scope_decl::scope_decl, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator) (function_type::function_type, method_type::method_type) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl, class_decl::class_decl): Take an environment. (type_or_decl_base::operator=) (enum_type_decl::enumerator::get_environment): Declare new method. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_qualified_name, get_name, get_qualified_parent_name, get_linkage_name}, qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::{get_name, get_qualified_name}) ({var,function}_decl::get_id) (function_decl::parameter::{get_type_name, get_name_id}): Return an interned_string, rather than a std::string. (decl_base::{set_qualified_name, set_temporary_qualified_name, get_qualified_name, set_linkage_name}) (qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string, rather than a std::string. (class_decl::member_{class,function}_template::member_{class,function}_template): Adjust. * src/abg-ir.cc (environment_setter::env_): Make this be a pointer to const environment. (environment_setter::visit_begin): Adjust. (interned_string_pool::priv): Define new type. (interned_string_pool::*): Define the method declared in abg-interned-str. h. (operator==, operator!=, operator+): Define operator for interned_string and std::string (operator<<): Define for interned_string. (translation_unit::priv::env_): Make this be a pointer to const environment. (translation_unit::priv::priv): Take a pointer to const environment. (elf_symbol::priv::env_): New data member. (elf_symbol::priv::priv): Adjust. Make an overoad take an environment. (translation_unit::{g,s}et_environment): Adjust. (interned_string_bool_map_type): New typedef. (environment::priv::classes_being_compared_): Make this hastable of string be a hashtable of interned_string. (environment::priv::string_pool_): New data member. (environment::{get_void_type_decl, get_variadic_parameter_type_decl}): Adjust. (type_or_decl_base::priv::env_): Make this be a pointer to const environment. (type_or_decl::base::priv::priv): Adjust. (type_or_decl_base::set_environment) (set_environment_for_artifact): Take a pointer to const environment. (elf_symbol::{g,s}et_environment, environment::intern) (type_or_decl_base::operator=): Define new methods. (decl_base::priv::{name_, qualified_parent_name_, temporary_qualified_name_, qualified_name_, linkage_name_}): Make these data member be of tpe interned_string. (decl_base::priv::priv): Make this take an environment. Adjust. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_linkage_name, get_qualified_parent_name, get_name, get_qualified_name}, get_type_name, get_function_type_name) (get_method_type_name, get_node_name) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::get_qualified_name) (var_decl::get_id, function_decl::get_id) (function_decl::parameter::get_{name_id, type_name}): Return an interned_string. (decl_base::{set_qualified_name, set_temporary_qualified_name}) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string. (decl_base::{set_name, set_linkage_name}): Intern the std::string passed in parameter. (equals): In the overload for decl_base, adjust for a little speed optimization that is justified by profiling. (pointer_type_def::priv::{internal_qualified_name_, temp_internal_qualified_name_}): Make these data member be interned_string. (enum_type_decl::enumerator::priv::env_): New data member. (enum_type_decl::enumerator::priv::{name_, qualified_name}): Make these data member be of type interned_string. (enum_type_decl::enumerator::get_environment): New method. (enum_type_decl::enumerator::priv::priv) Adjust. (typedef_decl::operator==): Implement a little speed optimization. (var_decl::priv::nake_type_): New data member. (var_decl::priv::id_): Make this data member be of type interned_string. (equals): In the overload for var_decl, function_type, function_decl, adjust for the use of interned_string. (function_decl::priv::id_): Make this be of type interned_string. (scope_decl::{add_member_decl, insert_member_decl}) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit, lookup_node_in_scope) (lookup_type_in_scope, scope_decl::scope_decl) (qualified_type_def::qualified_type_def) (qualified_type_def::get_qualified_name) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def) (array_type_def::array_type_def, array_type_def::append_subrange) (array_type_def::get_qualified_name) (enum_type_decl::enum_type_decl) (enum_type_decl::enumerator::get_qualified_name) (enum_type_decl::enumerator::set_name) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter) (class_decl::priv::comparison_started) (class_decl::add_base_specifier) (class_decl::base_spec::base_spec) (class_decl::method_decl::method_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, class_tdecl::class_tdecl) (qualified_name_setter::do_update): Adjust. (translation_unit::translation_unit, elf_symbol::elf_symbol) (elf_symbol::create, type_or_decl_base::type_or_decl_base) (decl_base::decl_base, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator, class_decl::class_decl) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Take an environment. * src/abg-comparison.cc (function_suppression::suppresses_function): Adjust. * src/abg-reader.cc (read_translation_unit) (read_corpus_from_input, build_namespace_decl, build_elf_symbol) (build_function_parameter, build_function_decl, build_type_decl) (build_function_type, build_enum_type_decl, build_enum_type_decl) (build_class_decl, build_function_tdecl, build_class_tdecl) (read_corpus_from_native_xml): Likewise. * src/abg-writer.cc (id_manager::m_cur_id): Make this mutable. (id_manager::m_env): New data member. (id_manager::id_manager): Adjust. (id_manager::get_environment): New method. (id_manager::{get_id, get_id_with_prefix}): Return an interned_string. (type_ptr_map): Make this be a hash map of type_base* -> interned_string, rather a type_base* -> string. (write_context::m_env): New data member. (write_context::m_type_id_map): Make this data member be mutable. (write_context::m_emitted_type_id_map): Make this be a hash map of interned_string -> bool, rather than string -> bool. (write_context::write_context): Take an environment and adjust. (write_context::get_environment): New method. (write_context::get_id_manager): New const overload. (write_context::get_id_for_type): Return an interned_string; adjust. (write_context::{record_type_id_as_emitted, record_type_as_referenced}): Adjust. (write_context::type_id_is_emitted): Take an interned_string. (write_context::{type_is_emitted, record_decl_only_type_as_emitted}): Adjust. (write_translation_unit, write_corpus_to_native_xml, dump): Adjust. * tools/abisym.cc (main): Adjust. * tests/data/test-read-write/test22.xml: Adjust. * tests/data/test-read-write/test23.xml: Adjust. * tests/data/test-read-write/test26.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-24 06:44:29 +00:00
interned_string
get_type_name(const type_base_sptr&,
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
bool qualified = true,
bool internal = false);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
Implement string interning for Libabigail This patch implements string interning optimization. One can read about the principles of this optimization at https://en.wikipedia.org/wiki/String_interning. The patch introduces an abigail::interned_string type, as well as an abigail::interned_string_pool type. Each environment type owns a string pool and strings are interned in that pool for all types and decls of that environments. The interned_string has methods to interact seemingly with std::string including a hashing function. Of course hashing and comparing interned_string is faster than for std::string. To enable ABI artifacts to intern strings, each constructor of ABI artifacts now takes the environment it's constructed in as parameter. From the environment, it can thus use the interned string pool. The patch then changes declaration names to be of type interned_string, and performs the necessary adjustments. The hash maps that hash strings coming from those declaration names are adjusted to hash interned_string. * include/Makefile.am: Add the new abg-interned-str.h file to source distribution. * include/abg-corpus.h (corpus::corpus): Re-arrange the order of * src/abg-corpus.cc (corpus::exported_decls_builder::priv::get_id): Return interned_string rather than std::string. (corpus::corpus): Re-arrange the order of parameters: take an environment as first parameter. parameters: take an environment as first parameter. * include/abg-dwarf-reader.h (lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Likewise. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab) (lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab) (lookup_symbol_from_elf, lookup_public_function_symbol_from_elf) (lookup_public_variable_symbol_from_elf, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Take an environment as first parameter and adjust. (build_translation_unit_and_add_to_ir) (build_namespace_decl_and_add_to_ir, build_type_decl) (build_enum_type, finish_member_function_reading) (build_class_type_and_add_to_ir, build_function_type) (read_debug_info_into_corpus, read_corpus_from_elf): Adjust. * include/abg-fwd.h: Include abg-interned-str.h (get_type_name, get_function_type_name, get_method_type_name): Return a interned_string, rather than a std::string. * include/abg-interned-str.h: New declarations for interned strings and their pool. * include/abg-ir.h (environment::intern): Declare new method. (elf_symbol::{g,s}et_environment): Likewise. (type_or_decl_base::type_or_decl_base): Make the default constructor private. ({translation, type_or_decl_base}::set_environment) (set_environment_for_artifact): Take a const environment*. (elf_symbol::elf_symbol) (elf_symbol::create) (type_or_decl_base::type_or_decl_base) (translation::translation, decl_base::decl_base) (scope_decl::scope_decl, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator) (function_type::function_type, method_type::method_type) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl, class_decl::class_decl): Take an environment. (type_or_decl_base::operator=) (enum_type_decl::enumerator::get_environment): Declare new method. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_qualified_name, get_name, get_qualified_parent_name, get_linkage_name}, qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::{get_name, get_qualified_name}) ({var,function}_decl::get_id) (function_decl::parameter::{get_type_name, get_name_id}): Return an interned_string, rather than a std::string. (decl_base::{set_qualified_name, set_temporary_qualified_name, get_qualified_name, set_linkage_name}) (qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string, rather than a std::string. (class_decl::member_{class,function}_template::member_{class,function}_template): Adjust. * src/abg-ir.cc (environment_setter::env_): Make this be a pointer to const environment. (environment_setter::visit_begin): Adjust. (interned_string_pool::priv): Define new type. (interned_string_pool::*): Define the method declared in abg-interned-str. h. (operator==, operator!=, operator+): Define operator for interned_string and std::string (operator<<): Define for interned_string. (translation_unit::priv::env_): Make this be a pointer to const environment. (translation_unit::priv::priv): Take a pointer to const environment. (elf_symbol::priv::env_): New data member. (elf_symbol::priv::priv): Adjust. Make an overoad take an environment. (translation_unit::{g,s}et_environment): Adjust. (interned_string_bool_map_type): New typedef. (environment::priv::classes_being_compared_): Make this hastable of string be a hashtable of interned_string. (environment::priv::string_pool_): New data member. (environment::{get_void_type_decl, get_variadic_parameter_type_decl}): Adjust. (type_or_decl_base::priv::env_): Make this be a pointer to const environment. (type_or_decl::base::priv::priv): Adjust. (type_or_decl_base::set_environment) (set_environment_for_artifact): Take a pointer to const environment. (elf_symbol::{g,s}et_environment, environment::intern) (type_or_decl_base::operator=): Define new methods. (decl_base::priv::{name_, qualified_parent_name_, temporary_qualified_name_, qualified_name_, linkage_name_}): Make these data member be of tpe interned_string. (decl_base::priv::priv): Make this take an environment. Adjust. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_linkage_name, get_qualified_parent_name, get_name, get_qualified_name}, get_type_name, get_function_type_name) (get_method_type_name, get_node_name) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::get_qualified_name) (var_decl::get_id, function_decl::get_id) (function_decl::parameter::get_{name_id, type_name}): Return an interned_string. (decl_base::{set_qualified_name, set_temporary_qualified_name}) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string. (decl_base::{set_name, set_linkage_name}): Intern the std::string passed in parameter. (equals): In the overload for decl_base, adjust for a little speed optimization that is justified by profiling. (pointer_type_def::priv::{internal_qualified_name_, temp_internal_qualified_name_}): Make these data member be interned_string. (enum_type_decl::enumerator::priv::env_): New data member. (enum_type_decl::enumerator::priv::{name_, qualified_name}): Make these data member be of type interned_string. (enum_type_decl::enumerator::get_environment): New method. (enum_type_decl::enumerator::priv::priv) Adjust. (typedef_decl::operator==): Implement a little speed optimization. (var_decl::priv::nake_type_): New data member. (var_decl::priv::id_): Make this data member be of type interned_string. (equals): In the overload for var_decl, function_type, function_decl, adjust for the use of interned_string. (function_decl::priv::id_): Make this be of type interned_string. (scope_decl::{add_member_decl, insert_member_decl}) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit, lookup_node_in_scope) (lookup_type_in_scope, scope_decl::scope_decl) (qualified_type_def::qualified_type_def) (qualified_type_def::get_qualified_name) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def) (array_type_def::array_type_def, array_type_def::append_subrange) (array_type_def::get_qualified_name) (enum_type_decl::enum_type_decl) (enum_type_decl::enumerator::get_qualified_name) (enum_type_decl::enumerator::set_name) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter) (class_decl::priv::comparison_started) (class_decl::add_base_specifier) (class_decl::base_spec::base_spec) (class_decl::method_decl::method_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, class_tdecl::class_tdecl) (qualified_name_setter::do_update): Adjust. (translation_unit::translation_unit, elf_symbol::elf_symbol) (elf_symbol::create, type_or_decl_base::type_or_decl_base) (decl_base::decl_base, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator, class_decl::class_decl) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Take an environment. * src/abg-comparison.cc (function_suppression::suppresses_function): Adjust. * src/abg-reader.cc (read_translation_unit) (read_corpus_from_input, build_namespace_decl, build_elf_symbol) (build_function_parameter, build_function_decl, build_type_decl) (build_function_type, build_enum_type_decl, build_enum_type_decl) (build_class_decl, build_function_tdecl, build_class_tdecl) (read_corpus_from_native_xml): Likewise. * src/abg-writer.cc (id_manager::m_cur_id): Make this mutable. (id_manager::m_env): New data member. (id_manager::id_manager): Adjust. (id_manager::get_environment): New method. (id_manager::{get_id, get_id_with_prefix}): Return an interned_string. (type_ptr_map): Make this be a hash map of type_base* -> interned_string, rather a type_base* -> string. (write_context::m_env): New data member. (write_context::m_type_id_map): Make this data member be mutable. (write_context::m_emitted_type_id_map): Make this be a hash map of interned_string -> bool, rather than string -> bool. (write_context::write_context): Take an environment and adjust. (write_context::get_environment): New method. (write_context::get_id_manager): New const overload. (write_context::get_id_for_type): Return an interned_string; adjust. (write_context::{record_type_id_as_emitted, record_type_as_referenced}): Adjust. (write_context::type_id_is_emitted): Take an interned_string. (write_context::{type_is_emitted, record_decl_only_type_as_emitted}): Adjust. (write_translation_unit, write_corpus_to_native_xml, dump): Adjust. * tools/abisym.cc (main): Adjust. * tests/data/test-read-write/test22.xml: Adjust. * tests/data/test-read-write/test23.xml: Adjust. * tests/data/test-read-write/test26.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-24 06:44:29 +00:00
interned_string
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
get_type_name(const type_base*,
bool qualified = true,
bool internal = false);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
Implement string interning for Libabigail This patch implements string interning optimization. One can read about the principles of this optimization at https://en.wikipedia.org/wiki/String_interning. The patch introduces an abigail::interned_string type, as well as an abigail::interned_string_pool type. Each environment type owns a string pool and strings are interned in that pool for all types and decls of that environments. The interned_string has methods to interact seemingly with std::string including a hashing function. Of course hashing and comparing interned_string is faster than for std::string. To enable ABI artifacts to intern strings, each constructor of ABI artifacts now takes the environment it's constructed in as parameter. From the environment, it can thus use the interned string pool. The patch then changes declaration names to be of type interned_string, and performs the necessary adjustments. The hash maps that hash strings coming from those declaration names are adjusted to hash interned_string. * include/Makefile.am: Add the new abg-interned-str.h file to source distribution. * include/abg-corpus.h (corpus::corpus): Re-arrange the order of * src/abg-corpus.cc (corpus::exported_decls_builder::priv::get_id): Return interned_string rather than std::string. (corpus::corpus): Re-arrange the order of parameters: take an environment as first parameter. parameters: take an environment as first parameter. * include/abg-dwarf-reader.h (lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Likewise. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab) (lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab) (lookup_symbol_from_elf, lookup_public_function_symbol_from_elf) (lookup_public_variable_symbol_from_elf, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Take an environment as first parameter and adjust. (build_translation_unit_and_add_to_ir) (build_namespace_decl_and_add_to_ir, build_type_decl) (build_enum_type, finish_member_function_reading) (build_class_type_and_add_to_ir, build_function_type) (read_debug_info_into_corpus, read_corpus_from_elf): Adjust. * include/abg-fwd.h: Include abg-interned-str.h (get_type_name, get_function_type_name, get_method_type_name): Return a interned_string, rather than a std::string. * include/abg-interned-str.h: New declarations for interned strings and their pool. * include/abg-ir.h (environment::intern): Declare new method. (elf_symbol::{g,s}et_environment): Likewise. (type_or_decl_base::type_or_decl_base): Make the default constructor private. ({translation, type_or_decl_base}::set_environment) (set_environment_for_artifact): Take a const environment*. (elf_symbol::elf_symbol) (elf_symbol::create) (type_or_decl_base::type_or_decl_base) (translation::translation, decl_base::decl_base) (scope_decl::scope_decl, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator) (function_type::function_type, method_type::method_type) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl, class_decl::class_decl): Take an environment. (type_or_decl_base::operator=) (enum_type_decl::enumerator::get_environment): Declare new method. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_qualified_name, get_name, get_qualified_parent_name, get_linkage_name}, qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::{get_name, get_qualified_name}) ({var,function}_decl::get_id) (function_decl::parameter::{get_type_name, get_name_id}): Return an interned_string, rather than a std::string. (decl_base::{set_qualified_name, set_temporary_qualified_name, get_qualified_name, set_linkage_name}) (qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string, rather than a std::string. (class_decl::member_{class,function}_template::member_{class,function}_template): Adjust. * src/abg-ir.cc (environment_setter::env_): Make this be a pointer to const environment. (environment_setter::visit_begin): Adjust. (interned_string_pool::priv): Define new type. (interned_string_pool::*): Define the method declared in abg-interned-str. h. (operator==, operator!=, operator+): Define operator for interned_string and std::string (operator<<): Define for interned_string. (translation_unit::priv::env_): Make this be a pointer to const environment. (translation_unit::priv::priv): Take a pointer to const environment. (elf_symbol::priv::env_): New data member. (elf_symbol::priv::priv): Adjust. Make an overoad take an environment. (translation_unit::{g,s}et_environment): Adjust. (interned_string_bool_map_type): New typedef. (environment::priv::classes_being_compared_): Make this hastable of string be a hashtable of interned_string. (environment::priv::string_pool_): New data member. (environment::{get_void_type_decl, get_variadic_parameter_type_decl}): Adjust. (type_or_decl_base::priv::env_): Make this be a pointer to const environment. (type_or_decl::base::priv::priv): Adjust. (type_or_decl_base::set_environment) (set_environment_for_artifact): Take a pointer to const environment. (elf_symbol::{g,s}et_environment, environment::intern) (type_or_decl_base::operator=): Define new methods. (decl_base::priv::{name_, qualified_parent_name_, temporary_qualified_name_, qualified_name_, linkage_name_}): Make these data member be of tpe interned_string. (decl_base::priv::priv): Make this take an environment. Adjust. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_linkage_name, get_qualified_parent_name, get_name, get_qualified_name}, get_type_name, get_function_type_name) (get_method_type_name, get_node_name) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::get_qualified_name) (var_decl::get_id, function_decl::get_id) (function_decl::parameter::get_{name_id, type_name}): Return an interned_string. (decl_base::{set_qualified_name, set_temporary_qualified_name}) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string. (decl_base::{set_name, set_linkage_name}): Intern the std::string passed in parameter. (equals): In the overload for decl_base, adjust for a little speed optimization that is justified by profiling. (pointer_type_def::priv::{internal_qualified_name_, temp_internal_qualified_name_}): Make these data member be interned_string. (enum_type_decl::enumerator::priv::env_): New data member. (enum_type_decl::enumerator::priv::{name_, qualified_name}): Make these data member be of type interned_string. (enum_type_decl::enumerator::get_environment): New method. (enum_type_decl::enumerator::priv::priv) Adjust. (typedef_decl::operator==): Implement a little speed optimization. (var_decl::priv::nake_type_): New data member. (var_decl::priv::id_): Make this data member be of type interned_string. (equals): In the overload for var_decl, function_type, function_decl, adjust for the use of interned_string. (function_decl::priv::id_): Make this be of type interned_string. (scope_decl::{add_member_decl, insert_member_decl}) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit, lookup_node_in_scope) (lookup_type_in_scope, scope_decl::scope_decl) (qualified_type_def::qualified_type_def) (qualified_type_def::get_qualified_name) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def) (array_type_def::array_type_def, array_type_def::append_subrange) (array_type_def::get_qualified_name) (enum_type_decl::enum_type_decl) (enum_type_decl::enumerator::get_qualified_name) (enum_type_decl::enumerator::set_name) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter) (class_decl::priv::comparison_started) (class_decl::add_base_specifier) (class_decl::base_spec::base_spec) (class_decl::method_decl::method_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, class_tdecl::class_tdecl) (qualified_name_setter::do_update): Adjust. (translation_unit::translation_unit, elf_symbol::elf_symbol) (elf_symbol::create, type_or_decl_base::type_or_decl_base) (decl_base::decl_base, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator, class_decl::class_decl) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Take an environment. * src/abg-comparison.cc (function_suppression::suppresses_function): Adjust. * src/abg-reader.cc (read_translation_unit) (read_corpus_from_input, build_namespace_decl, build_elf_symbol) (build_function_parameter, build_function_decl, build_type_decl) (build_function_type, build_enum_type_decl, build_enum_type_decl) (build_class_decl, build_function_tdecl, build_class_tdecl) (read_corpus_from_native_xml): Likewise. * src/abg-writer.cc (id_manager::m_cur_id): Make this mutable. (id_manager::m_env): New data member. (id_manager::id_manager): Adjust. (id_manager::get_environment): New method. (id_manager::{get_id, get_id_with_prefix}): Return an interned_string. (type_ptr_map): Make this be a hash map of type_base* -> interned_string, rather a type_base* -> string. (write_context::m_env): New data member. (write_context::m_type_id_map): Make this data member be mutable. (write_context::m_emitted_type_id_map): Make this be a hash map of interned_string -> bool, rather than string -> bool. (write_context::write_context): Take an environment and adjust. (write_context::get_environment): New method. (write_context::get_id_manager): New const overload. (write_context::get_id_for_type): Return an interned_string; adjust. (write_context::{record_type_id_as_emitted, record_type_as_referenced}): Adjust. (write_context::type_id_is_emitted): Take an interned_string. (write_context::{type_is_emitted, record_decl_only_type_as_emitted}): Adjust. (write_translation_unit, write_corpus_to_native_xml, dump): Adjust. * tools/abisym.cc (main): Adjust. * tests/data/test-read-write/test22.xml: Adjust. * tests/data/test-read-write/test23.xml: Adjust. * tests/data/test-read-write/test26.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-24 06:44:29 +00:00
interned_string
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
get_type_name(const type_base&,
bool qualified = true,
bool internal = false);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
Initial support to lookup types per location This patch adds support to associate a type to its source location. The location being a string of the form "filepath:line:column". The association is done by a per-translation unit map which associates a location to a type. For the moment this only associates one type to a given location. For the general case, though, we need to associate a vector or types to a given location. We'll add that support later. The patch provides lookup functions, each of which looking up a particular kind of type by its location. * include/abg-fwd.h (get_name_of_qualified_type) (get_name_of_reference_to_type, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_union_type_per_location) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, lookup_pointer_type) (lookup_reference_type, lookup_type_per_location) (lookup_type_through_translation_units) (lookup_type_from_translation_unit, odr_is_relevant): Declare new functions or new function overloads. * include/abg-ir.h (location::expand): Declare new member function. (type_maps::empty): Likewise. (operator|=): Declare an overload for qualified_type_def::CV. (get_string_representation_of_cv_quals) (get_name_of_qualified_type, lookup_qualified_type): Declare new functions. * src/abg-ir.cc (location::expand): Define new member function. (type_maps::empty): Likewise. (odr_is_relevant): Likewise. (get_string_representation_of_cv_quals) (get_name_of_reference_to_type, get_name_of_qualified_type) (lookup_union_type_per_location): Define new functions or overloads. (lookup_basic_type, lookup_enum_type, lookup_typedef_type) (lookup_qualified_type, lookup_pointer_type) (lookup_reference_type, lookup_type_from_translation_unit) (lookup_basic_type_per_location, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_class_type_per_location) (lookup_enum_type_per_location, lookup_enum_type_per_location) (lookup_typedef_type_per_location) (lookup_typedef_type_per_location, lookup_type_per_location): Define new overloads. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Add a new use_type_name_as_key parameter. If it's false, then associates the type to its location rather than to its name. (maybe_update_types_lookup_map): In the overloads for type_decl, class_decl, union_decl, enum_type, typedef_decl, array_type_def, record the type in the lookup map per location, in addition to the per-name recording. (qualified_type_def::build_name): Use the new get_name_of_qualified_type. (qualified_type_def::get_cv_quals_string_prefix): Use the new get_string_representation_of_cv_quals. (operator|=): Define a new overload for qualified_type_def::CV. (pointer_type_def::get_qualified_name): Use the new get_name_of_pointer_to_type. (reference_type_def::get_qualified_name): Use the new get_name_of_reference_to_type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-31 07:34:26 +00:00
interned_string
get_name_of_pointer_to_type(const type_base& pointed_to_type,
bool qualified = true,
bool internal = false);
interned_string
get_name_of_reference_to_type(const type_base& pointed_to_type,
bool lvalue_reference = false,
bool qualified = true,
bool internal = false);
Implement string interning for Libabigail This patch implements string interning optimization. One can read about the principles of this optimization at https://en.wikipedia.org/wiki/String_interning. The patch introduces an abigail::interned_string type, as well as an abigail::interned_string_pool type. Each environment type owns a string pool and strings are interned in that pool for all types and decls of that environments. The interned_string has methods to interact seemingly with std::string including a hashing function. Of course hashing and comparing interned_string is faster than for std::string. To enable ABI artifacts to intern strings, each constructor of ABI artifacts now takes the environment it's constructed in as parameter. From the environment, it can thus use the interned string pool. The patch then changes declaration names to be of type interned_string, and performs the necessary adjustments. The hash maps that hash strings coming from those declaration names are adjusted to hash interned_string. * include/Makefile.am: Add the new abg-interned-str.h file to source distribution. * include/abg-corpus.h (corpus::corpus): Re-arrange the order of * src/abg-corpus.cc (corpus::exported_decls_builder::priv::get_id): Return interned_string rather than std::string. (corpus::corpus): Re-arrange the order of parameters: take an environment as first parameter. parameters: take an environment as first parameter. * include/abg-dwarf-reader.h (lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Likewise. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab) (lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab) (lookup_symbol_from_elf, lookup_public_function_symbol_from_elf) (lookup_public_variable_symbol_from_elf, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Take an environment as first parameter and adjust. (build_translation_unit_and_add_to_ir) (build_namespace_decl_and_add_to_ir, build_type_decl) (build_enum_type, finish_member_function_reading) (build_class_type_and_add_to_ir, build_function_type) (read_debug_info_into_corpus, read_corpus_from_elf): Adjust. * include/abg-fwd.h: Include abg-interned-str.h (get_type_name, get_function_type_name, get_method_type_name): Return a interned_string, rather than a std::string. * include/abg-interned-str.h: New declarations for interned strings and their pool. * include/abg-ir.h (environment::intern): Declare new method. (elf_symbol::{g,s}et_environment): Likewise. (type_or_decl_base::type_or_decl_base): Make the default constructor private. ({translation, type_or_decl_base}::set_environment) (set_environment_for_artifact): Take a const environment*. (elf_symbol::elf_symbol) (elf_symbol::create) (type_or_decl_base::type_or_decl_base) (translation::translation, decl_base::decl_base) (scope_decl::scope_decl, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator) (function_type::function_type, method_type::method_type) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl, class_decl::class_decl): Take an environment. (type_or_decl_base::operator=) (enum_type_decl::enumerator::get_environment): Declare new method. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_qualified_name, get_name, get_qualified_parent_name, get_linkage_name}, qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::{get_name, get_qualified_name}) ({var,function}_decl::get_id) (function_decl::parameter::{get_type_name, get_name_id}): Return an interned_string, rather than a std::string. (decl_base::{set_qualified_name, set_temporary_qualified_name, get_qualified_name, set_linkage_name}) (qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string, rather than a std::string. (class_decl::member_{class,function}_template::member_{class,function}_template): Adjust. * src/abg-ir.cc (environment_setter::env_): Make this be a pointer to const environment. (environment_setter::visit_begin): Adjust. (interned_string_pool::priv): Define new type. (interned_string_pool::*): Define the method declared in abg-interned-str. h. (operator==, operator!=, operator+): Define operator for interned_string and std::string (operator<<): Define for interned_string. (translation_unit::priv::env_): Make this be a pointer to const environment. (translation_unit::priv::priv): Take a pointer to const environment. (elf_symbol::priv::env_): New data member. (elf_symbol::priv::priv): Adjust. Make an overoad take an environment. (translation_unit::{g,s}et_environment): Adjust. (interned_string_bool_map_type): New typedef. (environment::priv::classes_being_compared_): Make this hastable of string be a hashtable of interned_string. (environment::priv::string_pool_): New data member. (environment::{get_void_type_decl, get_variadic_parameter_type_decl}): Adjust. (type_or_decl_base::priv::env_): Make this be a pointer to const environment. (type_or_decl::base::priv::priv): Adjust. (type_or_decl_base::set_environment) (set_environment_for_artifact): Take a pointer to const environment. (elf_symbol::{g,s}et_environment, environment::intern) (type_or_decl_base::operator=): Define new methods. (decl_base::priv::{name_, qualified_parent_name_, temporary_qualified_name_, qualified_name_, linkage_name_}): Make these data member be of tpe interned_string. (decl_base::priv::priv): Make this take an environment. Adjust. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_linkage_name, get_qualified_parent_name, get_name, get_qualified_name}, get_type_name, get_function_type_name) (get_method_type_name, get_node_name) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::get_qualified_name) (var_decl::get_id, function_decl::get_id) (function_decl::parameter::get_{name_id, type_name}): Return an interned_string. (decl_base::{set_qualified_name, set_temporary_qualified_name}) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string. (decl_base::{set_name, set_linkage_name}): Intern the std::string passed in parameter. (equals): In the overload for decl_base, adjust for a little speed optimization that is justified by profiling. (pointer_type_def::priv::{internal_qualified_name_, temp_internal_qualified_name_}): Make these data member be interned_string. (enum_type_decl::enumerator::priv::env_): New data member. (enum_type_decl::enumerator::priv::{name_, qualified_name}): Make these data member be of type interned_string. (enum_type_decl::enumerator::get_environment): New method. (enum_type_decl::enumerator::priv::priv) Adjust. (typedef_decl::operator==): Implement a little speed optimization. (var_decl::priv::nake_type_): New data member. (var_decl::priv::id_): Make this data member be of type interned_string. (equals): In the overload for var_decl, function_type, function_decl, adjust for the use of interned_string. (function_decl::priv::id_): Make this be of type interned_string. (scope_decl::{add_member_decl, insert_member_decl}) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit, lookup_node_in_scope) (lookup_type_in_scope, scope_decl::scope_decl) (qualified_type_def::qualified_type_def) (qualified_type_def::get_qualified_name) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def) (array_type_def::array_type_def, array_type_def::append_subrange) (array_type_def::get_qualified_name) (enum_type_decl::enum_type_decl) (enum_type_decl::enumerator::get_qualified_name) (enum_type_decl::enumerator::set_name) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter) (class_decl::priv::comparison_started) (class_decl::add_base_specifier) (class_decl::base_spec::base_spec) (class_decl::method_decl::method_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, class_tdecl::class_tdecl) (qualified_name_setter::do_update): Adjust. (translation_unit::translation_unit, elf_symbol::elf_symbol) (elf_symbol::create, type_or_decl_base::type_or_decl_base) (decl_base::decl_base, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator, class_decl::class_decl) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Take an environment. * src/abg-comparison.cc (function_suppression::suppresses_function): Adjust. * src/abg-reader.cc (read_translation_unit) (read_corpus_from_input, build_namespace_decl, build_elf_symbol) (build_function_parameter, build_function_decl, build_type_decl) (build_function_type, build_enum_type_decl, build_enum_type_decl) (build_class_decl, build_function_tdecl, build_class_tdecl) (read_corpus_from_native_xml): Likewise. * src/abg-writer.cc (id_manager::m_cur_id): Make this mutable. (id_manager::m_env): New data member. (id_manager::id_manager): Adjust. (id_manager::get_environment): New method. (id_manager::{get_id, get_id_with_prefix}): Return an interned_string. (type_ptr_map): Make this be a hash map of type_base* -> interned_string, rather a type_base* -> string. (write_context::m_env): New data member. (write_context::m_type_id_map): Make this data member be mutable. (write_context::m_emitted_type_id_map): Make this be a hash map of interned_string -> bool, rather than string -> bool. (write_context::write_context): Take an environment and adjust. (write_context::get_environment): New method. (write_context::get_id_manager): New const overload. (write_context::get_id_for_type): Return an interned_string; adjust. (write_context::{record_type_id_as_emitted, record_type_as_referenced}): Adjust. (write_context::type_id_is_emitted): Take an interned_string. (write_context::{type_is_emitted, record_decl_only_type_as_emitted}): Adjust. (write_translation_unit, write_corpus_to_native_xml, dump): Adjust. * tools/abisym.cc (main): Adjust. * tests/data/test-read-write/test22.xml: Adjust. * tests/data/test-read-write/test23.xml: Adjust. * tests/data/test-read-write/test26.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-24 06:44:29 +00:00
interned_string
get_function_type_name(const function_type_sptr&,
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
bool internal = false);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
Implement string interning for Libabigail This patch implements string interning optimization. One can read about the principles of this optimization at https://en.wikipedia.org/wiki/String_interning. The patch introduces an abigail::interned_string type, as well as an abigail::interned_string_pool type. Each environment type owns a string pool and strings are interned in that pool for all types and decls of that environments. The interned_string has methods to interact seemingly with std::string including a hashing function. Of course hashing and comparing interned_string is faster than for std::string. To enable ABI artifacts to intern strings, each constructor of ABI artifacts now takes the environment it's constructed in as parameter. From the environment, it can thus use the interned string pool. The patch then changes declaration names to be of type interned_string, and performs the necessary adjustments. The hash maps that hash strings coming from those declaration names are adjusted to hash interned_string. * include/Makefile.am: Add the new abg-interned-str.h file to source distribution. * include/abg-corpus.h (corpus::corpus): Re-arrange the order of * src/abg-corpus.cc (corpus::exported_decls_builder::priv::get_id): Return interned_string rather than std::string. (corpus::corpus): Re-arrange the order of parameters: take an environment as first parameter. parameters: take an environment as first parameter. * include/abg-dwarf-reader.h (lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Likewise. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab) (lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab) (lookup_symbol_from_elf, lookup_public_function_symbol_from_elf) (lookup_public_variable_symbol_from_elf, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Take an environment as first parameter and adjust. (build_translation_unit_and_add_to_ir) (build_namespace_decl_and_add_to_ir, build_type_decl) (build_enum_type, finish_member_function_reading) (build_class_type_and_add_to_ir, build_function_type) (read_debug_info_into_corpus, read_corpus_from_elf): Adjust. * include/abg-fwd.h: Include abg-interned-str.h (get_type_name, get_function_type_name, get_method_type_name): Return a interned_string, rather than a std::string. * include/abg-interned-str.h: New declarations for interned strings and their pool. * include/abg-ir.h (environment::intern): Declare new method. (elf_symbol::{g,s}et_environment): Likewise. (type_or_decl_base::type_or_decl_base): Make the default constructor private. ({translation, type_or_decl_base}::set_environment) (set_environment_for_artifact): Take a const environment*. (elf_symbol::elf_symbol) (elf_symbol::create) (type_or_decl_base::type_or_decl_base) (translation::translation, decl_base::decl_base) (scope_decl::scope_decl, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator) (function_type::function_type, method_type::method_type) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl, class_decl::class_decl): Take an environment. (type_or_decl_base::operator=) (enum_type_decl::enumerator::get_environment): Declare new method. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_qualified_name, get_name, get_qualified_parent_name, get_linkage_name}, qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::{get_name, get_qualified_name}) ({var,function}_decl::get_id) (function_decl::parameter::{get_type_name, get_name_id}): Return an interned_string, rather than a std::string. (decl_base::{set_qualified_name, set_temporary_qualified_name, get_qualified_name, set_linkage_name}) (qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string, rather than a std::string. (class_decl::member_{class,function}_template::member_{class,function}_template): Adjust. * src/abg-ir.cc (environment_setter::env_): Make this be a pointer to const environment. (environment_setter::visit_begin): Adjust. (interned_string_pool::priv): Define new type. (interned_string_pool::*): Define the method declared in abg-interned-str. h. (operator==, operator!=, operator+): Define operator for interned_string and std::string (operator<<): Define for interned_string. (translation_unit::priv::env_): Make this be a pointer to const environment. (translation_unit::priv::priv): Take a pointer to const environment. (elf_symbol::priv::env_): New data member. (elf_symbol::priv::priv): Adjust. Make an overoad take an environment. (translation_unit::{g,s}et_environment): Adjust. (interned_string_bool_map_type): New typedef. (environment::priv::classes_being_compared_): Make this hastable of string be a hashtable of interned_string. (environment::priv::string_pool_): New data member. (environment::{get_void_type_decl, get_variadic_parameter_type_decl}): Adjust. (type_or_decl_base::priv::env_): Make this be a pointer to const environment. (type_or_decl::base::priv::priv): Adjust. (type_or_decl_base::set_environment) (set_environment_for_artifact): Take a pointer to const environment. (elf_symbol::{g,s}et_environment, environment::intern) (type_or_decl_base::operator=): Define new methods. (decl_base::priv::{name_, qualified_parent_name_, temporary_qualified_name_, qualified_name_, linkage_name_}): Make these data member be of tpe interned_string. (decl_base::priv::priv): Make this take an environment. Adjust. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_linkage_name, get_qualified_parent_name, get_name, get_qualified_name}, get_type_name, get_function_type_name) (get_method_type_name, get_node_name) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::get_qualified_name) (var_decl::get_id, function_decl::get_id) (function_decl::parameter::get_{name_id, type_name}): Return an interned_string. (decl_base::{set_qualified_name, set_temporary_qualified_name}) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string. (decl_base::{set_name, set_linkage_name}): Intern the std::string passed in parameter. (equals): In the overload for decl_base, adjust for a little speed optimization that is justified by profiling. (pointer_type_def::priv::{internal_qualified_name_, temp_internal_qualified_name_}): Make these data member be interned_string. (enum_type_decl::enumerator::priv::env_): New data member. (enum_type_decl::enumerator::priv::{name_, qualified_name}): Make these data member be of type interned_string. (enum_type_decl::enumerator::get_environment): New method. (enum_type_decl::enumerator::priv::priv) Adjust. (typedef_decl::operator==): Implement a little speed optimization. (var_decl::priv::nake_type_): New data member. (var_decl::priv::id_): Make this data member be of type interned_string. (equals): In the overload for var_decl, function_type, function_decl, adjust for the use of interned_string. (function_decl::priv::id_): Make this be of type interned_string. (scope_decl::{add_member_decl, insert_member_decl}) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit, lookup_node_in_scope) (lookup_type_in_scope, scope_decl::scope_decl) (qualified_type_def::qualified_type_def) (qualified_type_def::get_qualified_name) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def) (array_type_def::array_type_def, array_type_def::append_subrange) (array_type_def::get_qualified_name) (enum_type_decl::enum_type_decl) (enum_type_decl::enumerator::get_qualified_name) (enum_type_decl::enumerator::set_name) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter) (class_decl::priv::comparison_started) (class_decl::add_base_specifier) (class_decl::base_spec::base_spec) (class_decl::method_decl::method_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, class_tdecl::class_tdecl) (qualified_name_setter::do_update): Adjust. (translation_unit::translation_unit, elf_symbol::elf_symbol) (elf_symbol::create, type_or_decl_base::type_or_decl_base) (decl_base::decl_base, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator, class_decl::class_decl) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Take an environment. * src/abg-comparison.cc (function_suppression::suppresses_function): Adjust. * src/abg-reader.cc (read_translation_unit) (read_corpus_from_input, build_namespace_decl, build_elf_symbol) (build_function_parameter, build_function_decl, build_type_decl) (build_function_type, build_enum_type_decl, build_enum_type_decl) (build_class_decl, build_function_tdecl, build_class_tdecl) (read_corpus_from_native_xml): Likewise. * src/abg-writer.cc (id_manager::m_cur_id): Make this mutable. (id_manager::m_env): New data member. (id_manager::id_manager): Adjust. (id_manager::get_environment): New method. (id_manager::{get_id, get_id_with_prefix}): Return an interned_string. (type_ptr_map): Make this be a hash map of type_base* -> interned_string, rather a type_base* -> string. (write_context::m_env): New data member. (write_context::m_type_id_map): Make this data member be mutable. (write_context::m_emitted_type_id_map): Make this be a hash map of interned_string -> bool, rather than string -> bool. (write_context::write_context): Take an environment and adjust. (write_context::get_environment): New method. (write_context::get_id_manager): New const overload. (write_context::get_id_for_type): Return an interned_string; adjust. (write_context::{record_type_id_as_emitted, record_type_as_referenced}): Adjust. (write_context::type_id_is_emitted): Take an interned_string. (write_context::{type_is_emitted, record_decl_only_type_as_emitted}): Adjust. (write_translation_unit, write_corpus_to_native_xml, dump): Adjust. * tools/abisym.cc (main): Adjust. * tests/data/test-read-write/test22.xml: Adjust. * tests/data/test-read-write/test23.xml: Adjust. * tests/data/test-read-write/test26.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-24 06:44:29 +00:00
interned_string
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
get_function_type_name(const function_type*, bool internal = false);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
Implement string interning for Libabigail This patch implements string interning optimization. One can read about the principles of this optimization at https://en.wikipedia.org/wiki/String_interning. The patch introduces an abigail::interned_string type, as well as an abigail::interned_string_pool type. Each environment type owns a string pool and strings are interned in that pool for all types and decls of that environments. The interned_string has methods to interact seemingly with std::string including a hashing function. Of course hashing and comparing interned_string is faster than for std::string. To enable ABI artifacts to intern strings, each constructor of ABI artifacts now takes the environment it's constructed in as parameter. From the environment, it can thus use the interned string pool. The patch then changes declaration names to be of type interned_string, and performs the necessary adjustments. The hash maps that hash strings coming from those declaration names are adjusted to hash interned_string. * include/Makefile.am: Add the new abg-interned-str.h file to source distribution. * include/abg-corpus.h (corpus::corpus): Re-arrange the order of * src/abg-corpus.cc (corpus::exported_decls_builder::priv::get_id): Return interned_string rather than std::string. (corpus::corpus): Re-arrange the order of parameters: take an environment as first parameter. parameters: take an environment as first parameter. * include/abg-dwarf-reader.h (lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Likewise. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab) (lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab) (lookup_symbol_from_elf, lookup_public_function_symbol_from_elf) (lookup_public_variable_symbol_from_elf, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Take an environment as first parameter and adjust. (build_translation_unit_and_add_to_ir) (build_namespace_decl_and_add_to_ir, build_type_decl) (build_enum_type, finish_member_function_reading) (build_class_type_and_add_to_ir, build_function_type) (read_debug_info_into_corpus, read_corpus_from_elf): Adjust. * include/abg-fwd.h: Include abg-interned-str.h (get_type_name, get_function_type_name, get_method_type_name): Return a interned_string, rather than a std::string. * include/abg-interned-str.h: New declarations for interned strings and their pool. * include/abg-ir.h (environment::intern): Declare new method. (elf_symbol::{g,s}et_environment): Likewise. (type_or_decl_base::type_or_decl_base): Make the default constructor private. ({translation, type_or_decl_base}::set_environment) (set_environment_for_artifact): Take a const environment*. (elf_symbol::elf_symbol) (elf_symbol::create) (type_or_decl_base::type_or_decl_base) (translation::translation, decl_base::decl_base) (scope_decl::scope_decl, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator) (function_type::function_type, method_type::method_type) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl, class_decl::class_decl): Take an environment. (type_or_decl_base::operator=) (enum_type_decl::enumerator::get_environment): Declare new method. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_qualified_name, get_name, get_qualified_parent_name, get_linkage_name}, qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::{get_name, get_qualified_name}) ({var,function}_decl::get_id) (function_decl::parameter::{get_type_name, get_name_id}): Return an interned_string, rather than a std::string. (decl_base::{set_qualified_name, set_temporary_qualified_name, get_qualified_name, set_linkage_name}) (qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string, rather than a std::string. (class_decl::member_{class,function}_template::member_{class,function}_template): Adjust. * src/abg-ir.cc (environment_setter::env_): Make this be a pointer to const environment. (environment_setter::visit_begin): Adjust. (interned_string_pool::priv): Define new type. (interned_string_pool::*): Define the method declared in abg-interned-str. h. (operator==, operator!=, operator+): Define operator for interned_string and std::string (operator<<): Define for interned_string. (translation_unit::priv::env_): Make this be a pointer to const environment. (translation_unit::priv::priv): Take a pointer to const environment. (elf_symbol::priv::env_): New data member. (elf_symbol::priv::priv): Adjust. Make an overoad take an environment. (translation_unit::{g,s}et_environment): Adjust. (interned_string_bool_map_type): New typedef. (environment::priv::classes_being_compared_): Make this hastable of string be a hashtable of interned_string. (environment::priv::string_pool_): New data member. (environment::{get_void_type_decl, get_variadic_parameter_type_decl}): Adjust. (type_or_decl_base::priv::env_): Make this be a pointer to const environment. (type_or_decl::base::priv::priv): Adjust. (type_or_decl_base::set_environment) (set_environment_for_artifact): Take a pointer to const environment. (elf_symbol::{g,s}et_environment, environment::intern) (type_or_decl_base::operator=): Define new methods. (decl_base::priv::{name_, qualified_parent_name_, temporary_qualified_name_, qualified_name_, linkage_name_}): Make these data member be of tpe interned_string. (decl_base::priv::priv): Make this take an environment. Adjust. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_linkage_name, get_qualified_parent_name, get_name, get_qualified_name}, get_type_name, get_function_type_name) (get_method_type_name, get_node_name) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::get_qualified_name) (var_decl::get_id, function_decl::get_id) (function_decl::parameter::get_{name_id, type_name}): Return an interned_string. (decl_base::{set_qualified_name, set_temporary_qualified_name}) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string. (decl_base::{set_name, set_linkage_name}): Intern the std::string passed in parameter. (equals): In the overload for decl_base, adjust for a little speed optimization that is justified by profiling. (pointer_type_def::priv::{internal_qualified_name_, temp_internal_qualified_name_}): Make these data member be interned_string. (enum_type_decl::enumerator::priv::env_): New data member. (enum_type_decl::enumerator::priv::{name_, qualified_name}): Make these data member be of type interned_string. (enum_type_decl::enumerator::get_environment): New method. (enum_type_decl::enumerator::priv::priv) Adjust. (typedef_decl::operator==): Implement a little speed optimization. (var_decl::priv::nake_type_): New data member. (var_decl::priv::id_): Make this data member be of type interned_string. (equals): In the overload for var_decl, function_type, function_decl, adjust for the use of interned_string. (function_decl::priv::id_): Make this be of type interned_string. (scope_decl::{add_member_decl, insert_member_decl}) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit, lookup_node_in_scope) (lookup_type_in_scope, scope_decl::scope_decl) (qualified_type_def::qualified_type_def) (qualified_type_def::get_qualified_name) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def) (array_type_def::array_type_def, array_type_def::append_subrange) (array_type_def::get_qualified_name) (enum_type_decl::enum_type_decl) (enum_type_decl::enumerator::get_qualified_name) (enum_type_decl::enumerator::set_name) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter) (class_decl::priv::comparison_started) (class_decl::add_base_specifier) (class_decl::base_spec::base_spec) (class_decl::method_decl::method_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, class_tdecl::class_tdecl) (qualified_name_setter::do_update): Adjust. (translation_unit::translation_unit, elf_symbol::elf_symbol) (elf_symbol::create, type_or_decl_base::type_or_decl_base) (decl_base::decl_base, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator, class_decl::class_decl) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Take an environment. * src/abg-comparison.cc (function_suppression::suppresses_function): Adjust. * src/abg-reader.cc (read_translation_unit) (read_corpus_from_input, build_namespace_decl, build_elf_symbol) (build_function_parameter, build_function_decl, build_type_decl) (build_function_type, build_enum_type_decl, build_enum_type_decl) (build_class_decl, build_function_tdecl, build_class_tdecl) (read_corpus_from_native_xml): Likewise. * src/abg-writer.cc (id_manager::m_cur_id): Make this mutable. (id_manager::m_env): New data member. (id_manager::id_manager): Adjust. (id_manager::get_environment): New method. (id_manager::{get_id, get_id_with_prefix}): Return an interned_string. (type_ptr_map): Make this be a hash map of type_base* -> interned_string, rather a type_base* -> string. (write_context::m_env): New data member. (write_context::m_type_id_map): Make this data member be mutable. (write_context::m_emitted_type_id_map): Make this be a hash map of interned_string -> bool, rather than string -> bool. (write_context::write_context): Take an environment and adjust. (write_context::get_environment): New method. (write_context::get_id_manager): New const overload. (write_context::get_id_for_type): Return an interned_string; adjust. (write_context::{record_type_id_as_emitted, record_type_as_referenced}): Adjust. (write_context::type_id_is_emitted): Take an interned_string. (write_context::{type_is_emitted, record_decl_only_type_as_emitted}): Adjust. (write_translation_unit, write_corpus_to_native_xml, dump): Adjust. * tools/abisym.cc (main): Adjust. * tests/data/test-read-write/test22.xml: Adjust. * tests/data/test-read-write/test23.xml: Adjust. * tests/data/test-read-write/test26.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-24 06:44:29 +00:00
interned_string
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
get_function_type_name(const function_type&, bool internal = false);
Support diff/reporting for functions & better diff/report in general * include/abg-ir.h ({decl_base, class_decl, function_decl}::get_pretty_representation): New virtual member to get a pretty string name for decls & types. (class_decl::parameter): Add an index to the parameter type. (class_decl::parameter::parameter): Update the constructor for the change above. (class_decl::parameter::{get_index, set_index}): Accessors for the new index. (class_decl::parameter::operator==): Take in account the index. (function_type::append_parameter): Set the index of the parameter here. * include/abg-fwd.h (get_type_name): New declaration. * src/abg-ir.cc (get_type_name): New definition. ({decl_base, function_decl, class_decl}::get_pretty_representation): New implementations. (method_type::set_class_type): Update this to set function parameter's index by default. (function_decl::append_parameters): Use the append_parameter method from function_type. * include/abg-comparison.h (class function_decl_diff): New type declaration. * src/abg-comparison.cc (compute_diff_for_decls, compute_diff): New definitions. ({pointer_diff, class_diff, scope_diff}::report): Use the new get_pretty_representation. Output a prettier report. (function_decl_diff::priv): New type. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at, ensure_lookup_tables_populated, function_decl_diff, first_function_decl, second_function_decl, changed_parms, removed_parms, added_parms, length, report}): New member function definitions. * src/abg-hash.cc (function_decl::parameter::hash): Update this to take the index in account. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2013-10-19 14:33:40 +00:00
Implement string interning for Libabigail This patch implements string interning optimization. One can read about the principles of this optimization at https://en.wikipedia.org/wiki/String_interning. The patch introduces an abigail::interned_string type, as well as an abigail::interned_string_pool type. Each environment type owns a string pool and strings are interned in that pool for all types and decls of that environments. The interned_string has methods to interact seemingly with std::string including a hashing function. Of course hashing and comparing interned_string is faster than for std::string. To enable ABI artifacts to intern strings, each constructor of ABI artifacts now takes the environment it's constructed in as parameter. From the environment, it can thus use the interned string pool. The patch then changes declaration names to be of type interned_string, and performs the necessary adjustments. The hash maps that hash strings coming from those declaration names are adjusted to hash interned_string. * include/Makefile.am: Add the new abg-interned-str.h file to source distribution. * include/abg-corpus.h (corpus::corpus): Re-arrange the order of * src/abg-corpus.cc (corpus::exported_decls_builder::priv::get_id): Return interned_string rather than std::string. (corpus::corpus): Re-arrange the order of parameters: take an environment as first parameter. parameters: take an environment as first parameter. * include/abg-dwarf-reader.h (lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Likewise. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab) (lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab) (lookup_symbol_from_elf, lookup_public_function_symbol_from_elf) (lookup_public_variable_symbol_from_elf, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Take an environment as first parameter and adjust. (build_translation_unit_and_add_to_ir) (build_namespace_decl_and_add_to_ir, build_type_decl) (build_enum_type, finish_member_function_reading) (build_class_type_and_add_to_ir, build_function_type) (read_debug_info_into_corpus, read_corpus_from_elf): Adjust. * include/abg-fwd.h: Include abg-interned-str.h (get_type_name, get_function_type_name, get_method_type_name): Return a interned_string, rather than a std::string. * include/abg-interned-str.h: New declarations for interned strings and their pool. * include/abg-ir.h (environment::intern): Declare new method. (elf_symbol::{g,s}et_environment): Likewise. (type_or_decl_base::type_or_decl_base): Make the default constructor private. ({translation, type_or_decl_base}::set_environment) (set_environment_for_artifact): Take a const environment*. (elf_symbol::elf_symbol) (elf_symbol::create) (type_or_decl_base::type_or_decl_base) (translation::translation, decl_base::decl_base) (scope_decl::scope_decl, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator) (function_type::function_type, method_type::method_type) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl, class_decl::class_decl): Take an environment. (type_or_decl_base::operator=) (enum_type_decl::enumerator::get_environment): Declare new method. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_qualified_name, get_name, get_qualified_parent_name, get_linkage_name}, qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::{get_name, get_qualified_name}) ({var,function}_decl::get_id) (function_decl::parameter::{get_type_name, get_name_id}): Return an interned_string, rather than a std::string. (decl_base::{set_qualified_name, set_temporary_qualified_name, get_qualified_name, set_linkage_name}) (qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string, rather than a std::string. (class_decl::member_{class,function}_template::member_{class,function}_template): Adjust. * src/abg-ir.cc (environment_setter::env_): Make this be a pointer to const environment. (environment_setter::visit_begin): Adjust. (interned_string_pool::priv): Define new type. (interned_string_pool::*): Define the method declared in abg-interned-str. h. (operator==, operator!=, operator+): Define operator for interned_string and std::string (operator<<): Define for interned_string. (translation_unit::priv::env_): Make this be a pointer to const environment. (translation_unit::priv::priv): Take a pointer to const environment. (elf_symbol::priv::env_): New data member. (elf_symbol::priv::priv): Adjust. Make an overoad take an environment. (translation_unit::{g,s}et_environment): Adjust. (interned_string_bool_map_type): New typedef. (environment::priv::classes_being_compared_): Make this hastable of string be a hashtable of interned_string. (environment::priv::string_pool_): New data member. (environment::{get_void_type_decl, get_variadic_parameter_type_decl}): Adjust. (type_or_decl_base::priv::env_): Make this be a pointer to const environment. (type_or_decl::base::priv::priv): Adjust. (type_or_decl_base::set_environment) (set_environment_for_artifact): Take a pointer to const environment. (elf_symbol::{g,s}et_environment, environment::intern) (type_or_decl_base::operator=): Define new methods. (decl_base::priv::{name_, qualified_parent_name_, temporary_qualified_name_, qualified_name_, linkage_name_}): Make these data member be of tpe interned_string. (decl_base::priv::priv): Make this take an environment. Adjust. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_linkage_name, get_qualified_parent_name, get_name, get_qualified_name}, get_type_name, get_function_type_name) (get_method_type_name, get_node_name) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::get_qualified_name) (var_decl::get_id, function_decl::get_id) (function_decl::parameter::get_{name_id, type_name}): Return an interned_string. (decl_base::{set_qualified_name, set_temporary_qualified_name}) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string. (decl_base::{set_name, set_linkage_name}): Intern the std::string passed in parameter. (equals): In the overload for decl_base, adjust for a little speed optimization that is justified by profiling. (pointer_type_def::priv::{internal_qualified_name_, temp_internal_qualified_name_}): Make these data member be interned_string. (enum_type_decl::enumerator::priv::env_): New data member. (enum_type_decl::enumerator::priv::{name_, qualified_name}): Make these data member be of type interned_string. (enum_type_decl::enumerator::get_environment): New method. (enum_type_decl::enumerator::priv::priv) Adjust. (typedef_decl::operator==): Implement a little speed optimization. (var_decl::priv::nake_type_): New data member. (var_decl::priv::id_): Make this data member be of type interned_string. (equals): In the overload for var_decl, function_type, function_decl, adjust for the use of interned_string. (function_decl::priv::id_): Make this be of type interned_string. (scope_decl::{add_member_decl, insert_member_decl}) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit, lookup_node_in_scope) (lookup_type_in_scope, scope_decl::scope_decl) (qualified_type_def::qualified_type_def) (qualified_type_def::get_qualified_name) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def) (array_type_def::array_type_def, array_type_def::append_subrange) (array_type_def::get_qualified_name) (enum_type_decl::enum_type_decl) (enum_type_decl::enumerator::get_qualified_name) (enum_type_decl::enumerator::set_name) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter) (class_decl::priv::comparison_started) (class_decl::add_base_specifier) (class_decl::base_spec::base_spec) (class_decl::method_decl::method_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, class_tdecl::class_tdecl) (qualified_name_setter::do_update): Adjust. (translation_unit::translation_unit, elf_symbol::elf_symbol) (elf_symbol::create, type_or_decl_base::type_or_decl_base) (decl_base::decl_base, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator, class_decl::class_decl) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Take an environment. * src/abg-comparison.cc (function_suppression::suppresses_function): Adjust. * src/abg-reader.cc (read_translation_unit) (read_corpus_from_input, build_namespace_decl, build_elf_symbol) (build_function_parameter, build_function_decl, build_type_decl) (build_function_type, build_enum_type_decl, build_enum_type_decl) (build_class_decl, build_function_tdecl, build_class_tdecl) (read_corpus_from_native_xml): Likewise. * src/abg-writer.cc (id_manager::m_cur_id): Make this mutable. (id_manager::m_env): New data member. (id_manager::id_manager): Adjust. (id_manager::get_environment): New method. (id_manager::{get_id, get_id_with_prefix}): Return an interned_string. (type_ptr_map): Make this be a hash map of type_base* -> interned_string, rather a type_base* -> string. (write_context::m_env): New data member. (write_context::m_type_id_map): Make this data member be mutable. (write_context::m_emitted_type_id_map): Make this be a hash map of interned_string -> bool, rather than string -> bool. (write_context::write_context): Take an environment and adjust. (write_context::get_environment): New method. (write_context::get_id_manager): New const overload. (write_context::get_id_for_type): Return an interned_string; adjust. (write_context::{record_type_id_as_emitted, record_type_as_referenced}): Adjust. (write_context::type_id_is_emitted): Take an interned_string. (write_context::{type_is_emitted, record_decl_only_type_as_emitted}): Adjust. (write_translation_unit, write_corpus_to_native_xml, dump): Adjust. * tools/abisym.cc (main): Adjust. * tests/data/test-read-write/test22.xml: Adjust. * tests/data/test-read-write/test23.xml: Adjust. * tests/data/test-read-write/test26.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-24 06:44:29 +00:00
interned_string
get_method_type_name(const method_type_sptr&, bool internal = false);
Implement string interning for Libabigail This patch implements string interning optimization. One can read about the principles of this optimization at https://en.wikipedia.org/wiki/String_interning. The patch introduces an abigail::interned_string type, as well as an abigail::interned_string_pool type. Each environment type owns a string pool and strings are interned in that pool for all types and decls of that environments. The interned_string has methods to interact seemingly with std::string including a hashing function. Of course hashing and comparing interned_string is faster than for std::string. To enable ABI artifacts to intern strings, each constructor of ABI artifacts now takes the environment it's constructed in as parameter. From the environment, it can thus use the interned string pool. The patch then changes declaration names to be of type interned_string, and performs the necessary adjustments. The hash maps that hash strings coming from those declaration names are adjusted to hash interned_string. * include/Makefile.am: Add the new abg-interned-str.h file to source distribution. * include/abg-corpus.h (corpus::corpus): Re-arrange the order of * src/abg-corpus.cc (corpus::exported_decls_builder::priv::get_id): Return interned_string rather than std::string. (corpus::corpus): Re-arrange the order of parameters: take an environment as first parameter. parameters: take an environment as first parameter. * include/abg-dwarf-reader.h (lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Likewise. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab) (lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab) (lookup_symbol_from_elf, lookup_public_function_symbol_from_elf) (lookup_public_variable_symbol_from_elf, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Take an environment as first parameter and adjust. (build_translation_unit_and_add_to_ir) (build_namespace_decl_and_add_to_ir, build_type_decl) (build_enum_type, finish_member_function_reading) (build_class_type_and_add_to_ir, build_function_type) (read_debug_info_into_corpus, read_corpus_from_elf): Adjust. * include/abg-fwd.h: Include abg-interned-str.h (get_type_name, get_function_type_name, get_method_type_name): Return a interned_string, rather than a std::string. * include/abg-interned-str.h: New declarations for interned strings and their pool. * include/abg-ir.h (environment::intern): Declare new method. (elf_symbol::{g,s}et_environment): Likewise. (type_or_decl_base::type_or_decl_base): Make the default constructor private. ({translation, type_or_decl_base}::set_environment) (set_environment_for_artifact): Take a const environment*. (elf_symbol::elf_symbol) (elf_symbol::create) (type_or_decl_base::type_or_decl_base) (translation::translation, decl_base::decl_base) (scope_decl::scope_decl, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator) (function_type::function_type, method_type::method_type) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl, class_decl::class_decl): Take an environment. (type_or_decl_base::operator=) (enum_type_decl::enumerator::get_environment): Declare new method. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_qualified_name, get_name, get_qualified_parent_name, get_linkage_name}, qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::{get_name, get_qualified_name}) ({var,function}_decl::get_id) (function_decl::parameter::{get_type_name, get_name_id}): Return an interned_string, rather than a std::string. (decl_base::{set_qualified_name, set_temporary_qualified_name, get_qualified_name, set_linkage_name}) (qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string, rather than a std::string. (class_decl::member_{class,function}_template::member_{class,function}_template): Adjust. * src/abg-ir.cc (environment_setter::env_): Make this be a pointer to const environment. (environment_setter::visit_begin): Adjust. (interned_string_pool::priv): Define new type. (interned_string_pool::*): Define the method declared in abg-interned-str. h. (operator==, operator!=, operator+): Define operator for interned_string and std::string (operator<<): Define for interned_string. (translation_unit::priv::env_): Make this be a pointer to const environment. (translation_unit::priv::priv): Take a pointer to const environment. (elf_symbol::priv::env_): New data member. (elf_symbol::priv::priv): Adjust. Make an overoad take an environment. (translation_unit::{g,s}et_environment): Adjust. (interned_string_bool_map_type): New typedef. (environment::priv::classes_being_compared_): Make this hastable of string be a hashtable of interned_string. (environment::priv::string_pool_): New data member. (environment::{get_void_type_decl, get_variadic_parameter_type_decl}): Adjust. (type_or_decl_base::priv::env_): Make this be a pointer to const environment. (type_or_decl::base::priv::priv): Adjust. (type_or_decl_base::set_environment) (set_environment_for_artifact): Take a pointer to const environment. (elf_symbol::{g,s}et_environment, environment::intern) (type_or_decl_base::operator=): Define new methods. (decl_base::priv::{name_, qualified_parent_name_, temporary_qualified_name_, qualified_name_, linkage_name_}): Make these data member be of tpe interned_string. (decl_base::priv::priv): Make this take an environment. Adjust. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_linkage_name, get_qualified_parent_name, get_name, get_qualified_name}, get_type_name, get_function_type_name) (get_method_type_name, get_node_name) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::get_qualified_name) (var_decl::get_id, function_decl::get_id) (function_decl::parameter::get_{name_id, type_name}): Return an interned_string. (decl_base::{set_qualified_name, set_temporary_qualified_name}) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string. (decl_base::{set_name, set_linkage_name}): Intern the std::string passed in parameter. (equals): In the overload for decl_base, adjust for a little speed optimization that is justified by profiling. (pointer_type_def::priv::{internal_qualified_name_, temp_internal_qualified_name_}): Make these data member be interned_string. (enum_type_decl::enumerator::priv::env_): New data member. (enum_type_decl::enumerator::priv::{name_, qualified_name}): Make these data member be of type interned_string. (enum_type_decl::enumerator::get_environment): New method. (enum_type_decl::enumerator::priv::priv) Adjust. (typedef_decl::operator==): Implement a little speed optimization. (var_decl::priv::nake_type_): New data member. (var_decl::priv::id_): Make this data member be of type interned_string. (equals): In the overload for var_decl, function_type, function_decl, adjust for the use of interned_string. (function_decl::priv::id_): Make this be of type interned_string. (scope_decl::{add_member_decl, insert_member_decl}) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit, lookup_node_in_scope) (lookup_type_in_scope, scope_decl::scope_decl) (qualified_type_def::qualified_type_def) (qualified_type_def::get_qualified_name) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def) (array_type_def::array_type_def, array_type_def::append_subrange) (array_type_def::get_qualified_name) (enum_type_decl::enum_type_decl) (enum_type_decl::enumerator::get_qualified_name) (enum_type_decl::enumerator::set_name) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter) (class_decl::priv::comparison_started) (class_decl::add_base_specifier) (class_decl::base_spec::base_spec) (class_decl::method_decl::method_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, class_tdecl::class_tdecl) (qualified_name_setter::do_update): Adjust. (translation_unit::translation_unit, elf_symbol::elf_symbol) (elf_symbol::create, type_or_decl_base::type_or_decl_base) (decl_base::decl_base, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator, class_decl::class_decl) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Take an environment. * src/abg-comparison.cc (function_suppression::suppresses_function): Adjust. * src/abg-reader.cc (read_translation_unit) (read_corpus_from_input, build_namespace_decl, build_elf_symbol) (build_function_parameter, build_function_decl, build_type_decl) (build_function_type, build_enum_type_decl, build_enum_type_decl) (build_class_decl, build_function_tdecl, build_class_tdecl) (read_corpus_from_native_xml): Likewise. * src/abg-writer.cc (id_manager::m_cur_id): Make this mutable. (id_manager::m_env): New data member. (id_manager::id_manager): Adjust. (id_manager::get_environment): New method. (id_manager::{get_id, get_id_with_prefix}): Return an interned_string. (type_ptr_map): Make this be a hash map of type_base* -> interned_string, rather a type_base* -> string. (write_context::m_env): New data member. (write_context::m_type_id_map): Make this data member be mutable. (write_context::m_emitted_type_id_map): Make this be a hash map of interned_string -> bool, rather than string -> bool. (write_context::write_context): Take an environment and adjust. (write_context::get_environment): New method. (write_context::get_id_manager): New const overload. (write_context::get_id_for_type): Return an interned_string; adjust. (write_context::{record_type_id_as_emitted, record_type_as_referenced}): Adjust. (write_context::type_id_is_emitted): Take an interned_string. (write_context::{type_is_emitted, record_decl_only_type_as_emitted}): Adjust. (write_translation_unit, write_corpus_to_native_xml, dump): Adjust. * tools/abisym.cc (main): Adjust. * tests/data/test-read-write/test22.xml: Adjust. * tests/data/test-read-write/test23.xml: Adjust. * tests/data/test-read-write/test26.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-24 06:44:29 +00:00
interned_string
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
get_method_type_name(const method_type*, bool internal = false);
Implement string interning for Libabigail This patch implements string interning optimization. One can read about the principles of this optimization at https://en.wikipedia.org/wiki/String_interning. The patch introduces an abigail::interned_string type, as well as an abigail::interned_string_pool type. Each environment type owns a string pool and strings are interned in that pool for all types and decls of that environments. The interned_string has methods to interact seemingly with std::string including a hashing function. Of course hashing and comparing interned_string is faster than for std::string. To enable ABI artifacts to intern strings, each constructor of ABI artifacts now takes the environment it's constructed in as parameter. From the environment, it can thus use the interned string pool. The patch then changes declaration names to be of type interned_string, and performs the necessary adjustments. The hash maps that hash strings coming from those declaration names are adjusted to hash interned_string. * include/Makefile.am: Add the new abg-interned-str.h file to source distribution. * include/abg-corpus.h (corpus::corpus): Re-arrange the order of * src/abg-corpus.cc (corpus::exported_decls_builder::priv::get_id): Return interned_string rather than std::string. (corpus::corpus): Re-arrange the order of parameters: take an environment as first parameter. parameters: take an environment as first parameter. * include/abg-dwarf-reader.h (lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Likewise. * src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab) (lookup_symbol_from_gnu_hash_tab) (lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab) (lookup_symbol_from_elf, lookup_public_function_symbol_from_elf) (lookup_public_variable_symbol_from_elf, lookup_symbol_from_elf) (lookup_public_function_symbol_from_elf): Take an environment as first parameter and adjust. (build_translation_unit_and_add_to_ir) (build_namespace_decl_and_add_to_ir, build_type_decl) (build_enum_type, finish_member_function_reading) (build_class_type_and_add_to_ir, build_function_type) (read_debug_info_into_corpus, read_corpus_from_elf): Adjust. * include/abg-fwd.h: Include abg-interned-str.h (get_type_name, get_function_type_name, get_method_type_name): Return a interned_string, rather than a std::string. * include/abg-interned-str.h: New declarations for interned strings and their pool. * include/abg-ir.h (environment::intern): Declare new method. (elf_symbol::{g,s}et_environment): Likewise. (type_or_decl_base::type_or_decl_base): Make the default constructor private. ({translation, type_or_decl_base}::set_environment) (set_environment_for_artifact): Take a const environment*. (elf_symbol::elf_symbol) (elf_symbol::create) (type_or_decl_base::type_or_decl_base) (translation::translation, decl_base::decl_base) (scope_decl::scope_decl, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator) (function_type::function_type, method_type::method_type) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl, class_decl::class_decl): Take an environment. (type_or_decl_base::operator=) (enum_type_decl::enumerator::get_environment): Declare new method. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_qualified_name, get_name, get_qualified_parent_name, get_linkage_name}, qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::{get_name, get_qualified_name}) ({var,function}_decl::get_id) (function_decl::parameter::{get_type_name, get_name_id}): Return an interned_string, rather than a std::string. (decl_base::{set_qualified_name, set_temporary_qualified_name, get_qualified_name, set_linkage_name}) (qualified_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string, rather than a std::string. (class_decl::member_{class,function}_template::member_{class,function}_template): Adjust. * src/abg-ir.cc (environment_setter::env_): Make this be a pointer to const environment. (environment_setter::visit_begin): Adjust. (interned_string_pool::priv): Define new type. (interned_string_pool::*): Define the method declared in abg-interned-str. h. (operator==, operator!=, operator+): Define operator for interned_string and std::string (operator<<): Define for interned_string. (translation_unit::priv::env_): Make this be a pointer to const environment. (translation_unit::priv::priv): Take a pointer to const environment. (elf_symbol::priv::env_): New data member. (elf_symbol::priv::priv): Adjust. Make an overoad take an environment. (translation_unit::{g,s}et_environment): Adjust. (interned_string_bool_map_type): New typedef. (environment::priv::classes_being_compared_): Make this hastable of string be a hashtable of interned_string. (environment::priv::string_pool_): New data member. (environment::{get_void_type_decl, get_variadic_parameter_type_decl}): Adjust. (type_or_decl_base::priv::env_): Make this be a pointer to const environment. (type_or_decl::base::priv::priv): Adjust. (type_or_decl_base::set_environment) (set_environment_for_artifact): Take a pointer to const environment. (elf_symbol::{g,s}et_environment, environment::intern) (type_or_decl_base::operator=): Define new methods. (decl_base::priv::{name_, qualified_parent_name_, temporary_qualified_name_, qualified_name_, linkage_name_}): Make these data member be of tpe interned_string. (decl_base::priv::priv): Make this take an environment. Adjust. (decl_base::{peek_qualified_name, peek_temporary_qualified_name, get_linkage_name, get_qualified_parent_name, get_name, get_qualified_name}, get_type_name, get_function_type_name) (get_method_type_name, get_node_name) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (array_type_def::get_qualified_name) (enum_type_decl::enumerator::get_qualified_name) (var_decl::get_id, function_decl::get_id) (function_decl::parameter::get_{name_id, type_name}): Return an interned_string. (decl_base::{set_qualified_name, set_temporary_qualified_name}) (qualified_type_def::get_qualified_name) (pointer_type_def::get_qualified_name) (reference_type_def::get_qualified_name) (array_type_def::get_qualified_name) (function_decl::parameter::get_qualified_name): Take an interned_string. (decl_base::{set_name, set_linkage_name}): Intern the std::string passed in parameter. (equals): In the overload for decl_base, adjust for a little speed optimization that is justified by profiling. (pointer_type_def::priv::{internal_qualified_name_, temp_internal_qualified_name_}): Make these data member be interned_string. (enum_type_decl::enumerator::priv::env_): New data member. (enum_type_decl::enumerator::priv::{name_, qualified_name}): Make these data member be of type interned_string. (enum_type_decl::enumerator::get_environment): New method. (enum_type_decl::enumerator::priv::priv) Adjust. (typedef_decl::operator==): Implement a little speed optimization. (var_decl::priv::nake_type_): New data member. (var_decl::priv::id_): Make this data member be of type interned_string. (equals): In the overload for var_decl, function_type, function_decl, adjust for the use of interned_string. (function_decl::priv::id_): Make this be of type interned_string. (scope_decl::{add_member_decl, insert_member_decl}) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit, lookup_node_in_scope) (lookup_type_in_scope, scope_decl::scope_decl) (qualified_type_def::qualified_type_def) (qualified_type_def::get_qualified_name) (pointer_type_def::pointer_type_def) (reference_type_def::reference_type_def) (array_type_def::array_type_def, array_type_def::append_subrange) (array_type_def::get_qualified_name) (enum_type_decl::enum_type_decl) (enum_type_decl::enumerator::get_qualified_name) (enum_type_decl::enumerator::set_name) (typedef_decl::typedef_decl, var_decl::var_decl) (function_type::function_type, method_type::method_type) (function_decl::function_decl) (function_decl::parameter::parameter) (class_decl::priv::comparison_started) (class_decl::add_base_specifier) (class_decl::base_spec::base_spec) (class_decl::method_decl::method_decl) (type_tparameter::type_tparameter) (non_type_tparameter::non_type_tparameter) (template_tparameter::template_tparameter) (type_composition::type_composition) (function_tdecl::function_tdecl, class_tdecl::class_tdecl) (qualified_name_setter::do_update): Adjust. (translation_unit::translation_unit, elf_symbol::elf_symbol) (elf_symbol::create, type_or_decl_base::type_or_decl_base) (decl_base::decl_base, type_base::type_base) (type_decl::type_decl, scope_type_decl::scope_type_decl) (namespace_decl::namespace_decl) (enum_type_decl::enumerator::enumerator, class_decl::class_decl) (template_decl::template_decl, function_tdecl::function_tdecl) (class_tdecl::class_tdecl): Take an environment. * src/abg-comparison.cc (function_suppression::suppresses_function): Adjust. * src/abg-reader.cc (read_translation_unit) (read_corpus_from_input, build_namespace_decl, build_elf_symbol) (build_function_parameter, build_function_decl, build_type_decl) (build_function_type, build_enum_type_decl, build_enum_type_decl) (build_class_decl, build_function_tdecl, build_class_tdecl) (read_corpus_from_native_xml): Likewise. * src/abg-writer.cc (id_manager::m_cur_id): Make this mutable. (id_manager::m_env): New data member. (id_manager::id_manager): Adjust. (id_manager::get_environment): New method. (id_manager::{get_id, get_id_with_prefix}): Return an interned_string. (type_ptr_map): Make this be a hash map of type_base* -> interned_string, rather a type_base* -> string. (write_context::m_env): New data member. (write_context::m_type_id_map): Make this data member be mutable. (write_context::m_emitted_type_id_map): Make this be a hash map of interned_string -> bool, rather than string -> bool. (write_context::write_context): Take an environment and adjust. (write_context::get_environment): New method. (write_context::get_id_manager): New const overload. (write_context::get_id_for_type): Return an interned_string; adjust. (write_context::{record_type_id_as_emitted, record_type_as_referenced}): Adjust. (write_context::type_id_is_emitted): Take an interned_string. (write_context::{type_is_emitted, record_decl_only_type_as_emitted}): Adjust. (write_translation_unit, write_corpus_to_native_xml, dump): Adjust. * tools/abisym.cc (main): Adjust. * tests/data/test-read-write/test22.xml: Adjust. * tests/data/test-read-write/test23.xml: Adjust. * tests/data/test-read-write/test26.xml: Adjust. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-24 06:44:29 +00:00
interned_string
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
get_method_type_name(const method_type&, bool internal = false);
string
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
get_pretty_representation(const decl_base*, bool internal = false);
string
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
get_pretty_representation(const type_base*, bool internal = false);
string
get_pretty_representation(const type_or_decl_base*, bool internal = false);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
string
get_pretty_representation(const type_or_decl_base_sptr&,
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
bool internal = false);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
string
get_pretty_representation(const decl_base_sptr&, bool internal = false);
string
get_pretty_representation(const type_base_sptr&, bool internal = false);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
string
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
get_pretty_representation(const function_type&, bool internal = false);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
string
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
get_pretty_representation(const function_type*, bool internal = false);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
string
get_pretty_representation(const function_type_sptr&,
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
bool internal = false);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
string
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
get_pretty_representation(const method_type&, bool internal = false);
string
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
get_pretty_representation(const method_type*, bool internal = false);
string
get_pretty_representation(const method_type_sptr&,
Make canonicalization non sensitive to struct-ness of subtypes In a previous patch, we made canonicalization independant from struct-ness of class types. This was in this commit: 0e3416e Bug 19023 - Type canonicalization is sensitive to struct-ness But then, that didn't handle the case of composite types which have a subtype of class type T, where the same T was declared as "struct" and as "class" in the same binary. This patch handles that case by passing a flag to the functions that build the pretty representation of types. Note that the pretty representation is used as a key in the hash map that contains canonical types. That flag is passed all the way down to the function that builds the pretty representation for class types, which decides to use either "struct" or "class" as a previx for the representation. The type canonicalization code then passes that flag (properly set) to the pretty representation function. * include/abg-fwd.h (get_type_name, get_function_type_name) (get_method_type_name, get_pretty_representation): Add an "internal" flag to all overoads. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, scope_type_decl, qualified_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl}::get_pretty_representation): Add an 'internal' flag. ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Likewise. (qualified_type_def::build_name): Likewise. * src/abg-ir.cc ({decl_base, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, enum_type_decl::enumerator, function_decl::parameter}::get_qualified_name): Take an "internal" flag. (qualified_type_def::build_name): Likewise. ({decl_base, type_decl, namespace_decl, array_type_def, enum_type_decl, typedef_decl, var_decl, function_type, method_type, function_decl, class_decl}::get_pretty_representation): Likewise. (get_type_name, get_function_type_name, get_method_type_name) (get_pretty_representation): Likewise. (type_base::get_canonical_type_for): Call get_pretty_representation() with the "internal" flag set to "true", to get a pretty representation that is independant from the struct-ness of the subtypes of the type being canonicalized. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-14 20:40:18 +00:00
bool internal = false);
Initial support of anonymous data members An anonymous data member is a data member of a struct or a union which has no name. The type of such data member is either a struct or a union. For instance: struct foo { int a; struct { // <-- this is an anonymous data member char a; char b; }; int c; }; In DWARF (as emitted by GCC at least), an anonymous data member is represented as a data member with an empty name. Libabigail sees it just fine, but then when representing *changes* to that kind of data member, it needs special treatment, otherwise users cannot make sense of the reports. This patch adds initial support to represent changes to anonymous data members. * include/abg-comparison.h (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Declare new functions. * include/abg-fwd.h (is_class_type): Declare new overload for type_or_decl_base&. (is_data_member): Declare new overload for decl_base*. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Declare new functions. (is_at_class_scope): Return the class or union scope. * include/abg-ir.h (var_decl::get_qualified_name): New virtual data member which overloads decl_base::get_qualified_name. * src/abg-comparison.cc (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Define new functions (leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous class or union diff nodes as diff nodes. * src/abg-ir.cc (is_data_member): Define new overload for decl_base*. (is_class_type, is_union_type): Define new overload for type_or_decl_base&. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Define new function overloads. (var_decl::get_qualified_name): Define new virtual member function. (is_at_class_scope): Return the class or union scope. (var_decl::get_pretty_representation): Support anonymous data members. (equals): In the overload for class_or_union_diff, mark data member textual representation changes as local changes. * src/abg-reporter-priv.cc (represent): In the overload for var_diff, support changes to anonymous data members. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted -- by offset -- data member changes before the ones that are sorted by other things. * tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so: New binary test input * tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt: New reference test outputs. * tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c: Source code of the new binary test output above. * tests/data/Makefile.am: Add the new test files above to the source distribution. * tests/data/test-annotate/libtest23.so.abi: Adjust test reference output. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-09 06:51:50 +00:00
string
get_class_or_union_flat_representation(const class_or_union& cou,
const string& indent,
Make abidiff --harmless show harmless changes in unions Since the previous commit filters out harmless changes inside unions, this one allows those changes to be reported whenever the user runs abidiff with the --harmless option. The patch just displays the "before" and "after" of the union because some of the harmless changes are not tracked anymore. Because we want to display the before and after of the union we use the function get_class_or_union_flat_representation. The patch adds a "qualified_name" boolean parameter to that function so that we can choose to display union members names in a non-qualified fashion, which is the natural way of displaying those names in the context of a union (or class) representation. Because get_class_or_union_flat_representation uses type_or_decl_base::get_pretty_representation, the patch has also added a "qualified_name" boolean parameter to that function so that we can choose to display names in a non-qualified manner. * include/abg-fwd.h (get_class_or_union_flat_representation): Add a "qualified_name" boolean parameter. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, namespace_decl, array_type_def::subrange_type, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl, union_decl}::get_pretty_representation): Likewise. * src/abg-ir.cc ({type_or_decl_base, decl_base, type_decl, namespace_decl, array_type_def::subrange_type, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl, union_decl, }::get_pretty_representation): Adjust the code to emit qualified or non-qualified names depending on the new "qualified_name" boolean parameter. (get_class_or_union_flat_representation): Likewise. * src/abg-default-reporter.cc (default_reporter::report): Use get_class_or_union_flat_representation with the new "qualified_name" boolean set to false. * tests/data/test-diff-dwarf/test38-union-report-0.txt: Adjust. * tests/test-diff-filter.cc (in_out_specs): Run the test harness on test-PR24731-v{0,1}.o make abidiff use the --harmless option. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-26 09:37:28 +00:00
bool one_line,
bool qualified_name = true);
Initial support of anonymous data members An anonymous data member is a data member of a struct or a union which has no name. The type of such data member is either a struct or a union. For instance: struct foo { int a; struct { // <-- this is an anonymous data member char a; char b; }; int c; }; In DWARF (as emitted by GCC at least), an anonymous data member is represented as a data member with an empty name. Libabigail sees it just fine, but then when representing *changes* to that kind of data member, it needs special treatment, otherwise users cannot make sense of the reports. This patch adds initial support to represent changes to anonymous data members. * include/abg-comparison.h (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Declare new functions. * include/abg-fwd.h (is_class_type): Declare new overload for type_or_decl_base&. (is_data_member): Declare new overload for decl_base*. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Declare new functions. (is_at_class_scope): Return the class or union scope. * include/abg-ir.h (var_decl::get_qualified_name): New virtual data member which overloads decl_base::get_qualified_name. * src/abg-comparison.cc (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Define new functions (leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous class or union diff nodes as diff nodes. * src/abg-ir.cc (is_data_member): Define new overload for decl_base*. (is_class_type, is_union_type): Define new overload for type_or_decl_base&. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Define new function overloads. (var_decl::get_qualified_name): Define new virtual member function. (is_at_class_scope): Return the class or union scope. (var_decl::get_pretty_representation): Support anonymous data members. (equals): In the overload for class_or_union_diff, mark data member textual representation changes as local changes. * src/abg-reporter-priv.cc (represent): In the overload for var_diff, support changes to anonymous data members. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted -- by offset -- data member changes before the ones that are sorted by other things. * tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so: New binary test input * tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt: New reference test outputs. * tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c: Source code of the new binary test output above. * tests/data/Makefile.am: Add the new test files above to the source distribution. * tests/data/test-annotate/libtest23.so.abi: Adjust test reference output. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-09 06:51:50 +00:00
string
get_class_or_union_flat_representation(const class_or_union* cou,
const string& indent,
Make abidiff --harmless show harmless changes in unions Since the previous commit filters out harmless changes inside unions, this one allows those changes to be reported whenever the user runs abidiff with the --harmless option. The patch just displays the "before" and "after" of the union because some of the harmless changes are not tracked anymore. Because we want to display the before and after of the union we use the function get_class_or_union_flat_representation. The patch adds a "qualified_name" boolean parameter to that function so that we can choose to display union members names in a non-qualified fashion, which is the natural way of displaying those names in the context of a union (or class) representation. Because get_class_or_union_flat_representation uses type_or_decl_base::get_pretty_representation, the patch has also added a "qualified_name" boolean parameter to that function so that we can choose to display names in a non-qualified manner. * include/abg-fwd.h (get_class_or_union_flat_representation): Add a "qualified_name" boolean parameter. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, namespace_decl, array_type_def::subrange_type, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl, union_decl}::get_pretty_representation): Likewise. * src/abg-ir.cc ({type_or_decl_base, decl_base, type_decl, namespace_decl, array_type_def::subrange_type, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl, union_decl, }::get_pretty_representation): Adjust the code to emit qualified or non-qualified names depending on the new "qualified_name" boolean parameter. (get_class_or_union_flat_representation): Likewise. * src/abg-default-reporter.cc (default_reporter::report): Use get_class_or_union_flat_representation with the new "qualified_name" boolean set to false. * tests/data/test-diff-dwarf/test38-union-report-0.txt: Adjust. * tests/test-diff-filter.cc (in_out_specs): Run the test harness on test-PR24731-v{0,1}.o make abidiff use the --harmless option. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-26 09:37:28 +00:00
bool one_line,
bool qualified_name = true);
Initial support of anonymous data members An anonymous data member is a data member of a struct or a union which has no name. The type of such data member is either a struct or a union. For instance: struct foo { int a; struct { // <-- this is an anonymous data member char a; char b; }; int c; }; In DWARF (as emitted by GCC at least), an anonymous data member is represented as a data member with an empty name. Libabigail sees it just fine, but then when representing *changes* to that kind of data member, it needs special treatment, otherwise users cannot make sense of the reports. This patch adds initial support to represent changes to anonymous data members. * include/abg-comparison.h (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Declare new functions. * include/abg-fwd.h (is_class_type): Declare new overload for type_or_decl_base&. (is_data_member): Declare new overload for decl_base*. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Declare new functions. (is_at_class_scope): Return the class or union scope. * include/abg-ir.h (var_decl::get_qualified_name): New virtual data member which overloads decl_base::get_qualified_name. * src/abg-comparison.cc (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Define new functions (leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous class or union diff nodes as diff nodes. * src/abg-ir.cc (is_data_member): Define new overload for decl_base*. (is_class_type, is_union_type): Define new overload for type_or_decl_base&. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Define new function overloads. (var_decl::get_qualified_name): Define new virtual member function. (is_at_class_scope): Return the class or union scope. (var_decl::get_pretty_representation): Support anonymous data members. (equals): In the overload for class_or_union_diff, mark data member textual representation changes as local changes. * src/abg-reporter-priv.cc (represent): In the overload for var_diff, support changes to anonymous data members. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted -- by offset -- data member changes before the ones that are sorted by other things. * tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so: New binary test input * tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt: New reference test outputs. * tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c: Source code of the new binary test output above. * tests/data/Makefile.am: Add the new test files above to the source distribution. * tests/data/test-annotate/libtest23.so.abi: Adjust test reference output. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-09 06:51:50 +00:00
string
get_class_or_union_flat_representation(const class_or_union_sptr& cou,
const string& indent,
Make abidiff --harmless show harmless changes in unions Since the previous commit filters out harmless changes inside unions, this one allows those changes to be reported whenever the user runs abidiff with the --harmless option. The patch just displays the "before" and "after" of the union because some of the harmless changes are not tracked anymore. Because we want to display the before and after of the union we use the function get_class_or_union_flat_representation. The patch adds a "qualified_name" boolean parameter to that function so that we can choose to display union members names in a non-qualified fashion, which is the natural way of displaying those names in the context of a union (or class) representation. Because get_class_or_union_flat_representation uses type_or_decl_base::get_pretty_representation, the patch has also added a "qualified_name" boolean parameter to that function so that we can choose to display names in a non-qualified manner. * include/abg-fwd.h (get_class_or_union_flat_representation): Add a "qualified_name" boolean parameter. * include/abg-ir.h ({type_or_decl_base, decl_base, type_decl, namespace_decl, array_type_def::subrange_type, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl, union_decl}::get_pretty_representation): Likewise. * src/abg-ir.cc ({type_or_decl_base, decl_base, type_decl, namespace_decl, array_type_def::subrange_type, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, function_type, method_type, class_decl, union_decl, }::get_pretty_representation): Adjust the code to emit qualified or non-qualified names depending on the new "qualified_name" boolean parameter. (get_class_or_union_flat_representation): Likewise. * src/abg-default-reporter.cc (default_reporter::report): Use get_class_or_union_flat_representation with the new "qualified_name" boolean set to false. * tests/data/test-diff-dwarf/test38-union-report-0.txt: Adjust. * tests/test-diff-filter.cc (in_out_specs): Run the test harness on test-PR24731-v{0,1}.o make abidiff use the --harmless option. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-06-26 09:37:28 +00:00
bool one_line,
bool qualified_name = true);
Initial support of anonymous data members An anonymous data member is a data member of a struct or a union which has no name. The type of such data member is either a struct or a union. For instance: struct foo { int a; struct { // <-- this is an anonymous data member char a; char b; }; int c; }; In DWARF (as emitted by GCC at least), an anonymous data member is represented as a data member with an empty name. Libabigail sees it just fine, but then when representing *changes* to that kind of data member, it needs special treatment, otherwise users cannot make sense of the reports. This patch adds initial support to represent changes to anonymous data members. * include/abg-comparison.h (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Declare new functions. * include/abg-fwd.h (is_class_type): Declare new overload for type_or_decl_base&. (is_data_member): Declare new overload for decl_base*. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Declare new functions. (is_at_class_scope): Return the class or union scope. * include/abg-ir.h (var_decl::get_qualified_name): New virtual data member which overloads decl_base::get_qualified_name. * src/abg-comparison.cc (is_class_or_union_diff) (is_anonymous_class_or_union_diff): Define new functions (leaf_diff_node_marker_visitor::visit_begin): Don't mark anonymous class or union diff nodes as diff nodes. * src/abg-ir.cc (is_data_member): Define new overload for decl_base*. (is_class_type, is_union_type): Define new overload for type_or_decl_base&. (is_anonymous_data_member) (anonymous_data_member_to_class_or_union) (get_class_or_union_flat_representation) (data_member_has_anonymous_type): Define new function overloads. (var_decl::get_qualified_name): Define new virtual member function. (is_at_class_scope): Return the class or union scope. (var_decl::get_pretty_representation): Support anonymous data members. (equals): In the overload for class_or_union_diff, mark data member textual representation changes as local changes. * src/abg-reporter-priv.cc (represent): In the overload for var_diff, support changes to anonymous data members. * src/abg-leaf-reporter.cc (leaf_reporter::report): Report sorted -- by offset -- data member changes before the ones that are sorted by other things. * tests/data/test-diff-filter/libtest44-anonymous-data-member-v{0,1}.so: New binary test input * tests/data/test-diff-filter/test44-anonymous-data-member-report-{0,1}.txt: New reference test outputs. * tests/data/test-diff-filter/test44-anonymous-data-member-v{0,1}.c: Source code of the new binary test output above. * tests/data/Makefile.am: Add the new test files above to the source distribution. * tests/data/test-annotate/libtest23.so.abi: Adjust test reference output. * tests/data/test-annotate/libtest24-drop-fns-2.so.abi: Likewise. * tests/data/test-annotate/libtest24-drop-fns.so.abi: Likewise. * tests/data/test-annotate/test13-pr18894.so.abi: Likewise. * tests/data/test-annotate/test14-pr18893.so.abi: Likewise. * tests/data/test-annotate/test15-pr18892.so.abi: Likewise. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-dwarf/test43-PR22913-report-0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report2.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-0.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-filter/test35-pr18754-no-added-syms-report-0.txt: Likewise. * tests/data/test-diff-pkg/libcdio-0.94-1.fc26.x86_64--libcdio-0.94-2.fc26.x86_64-report.1.txt: Likewise. * tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-09 06:51:50 +00:00
Initial support to lookup types per location This patch adds support to associate a type to its source location. The location being a string of the form "filepath:line:column". The association is done by a per-translation unit map which associates a location to a type. For the moment this only associates one type to a given location. For the general case, though, we need to associate a vector or types to a given location. We'll add that support later. The patch provides lookup functions, each of which looking up a particular kind of type by its location. * include/abg-fwd.h (get_name_of_qualified_type) (get_name_of_reference_to_type, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_union_type_per_location) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, lookup_pointer_type) (lookup_reference_type, lookup_type_per_location) (lookup_type_through_translation_units) (lookup_type_from_translation_unit, odr_is_relevant): Declare new functions or new function overloads. * include/abg-ir.h (location::expand): Declare new member function. (type_maps::empty): Likewise. (operator|=): Declare an overload for qualified_type_def::CV. (get_string_representation_of_cv_quals) (get_name_of_qualified_type, lookup_qualified_type): Declare new functions. * src/abg-ir.cc (location::expand): Define new member function. (type_maps::empty): Likewise. (odr_is_relevant): Likewise. (get_string_representation_of_cv_quals) (get_name_of_reference_to_type, get_name_of_qualified_type) (lookup_union_type_per_location): Define new functions or overloads. (lookup_basic_type, lookup_enum_type, lookup_typedef_type) (lookup_qualified_type, lookup_pointer_type) (lookup_reference_type, lookup_type_from_translation_unit) (lookup_basic_type_per_location, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_class_type_per_location) (lookup_enum_type_per_location, lookup_enum_type_per_location) (lookup_typedef_type_per_location) (lookup_typedef_type_per_location, lookup_type_per_location): Define new overloads. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Add a new use_type_name_as_key parameter. If it's false, then associates the type to its location rather than to its name. (maybe_update_types_lookup_map): In the overloads for type_decl, class_decl, union_decl, enum_type, typedef_decl, array_type_def, record the type in the lookup map per location, in addition to the per-name recording. (qualified_type_def::build_name): Use the new get_name_of_qualified_type. (qualified_type_def::get_cv_quals_string_prefix): Use the new get_string_representation_of_cv_quals. (operator|=): Define a new overload for qualified_type_def::CV. (pointer_type_def::get_qualified_name): Use the new get_name_of_pointer_to_type. (reference_type_def::get_qualified_name): Use the new get_name_of_reference_to_type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-31 07:34:26 +00:00
bool
Allow selective resolution of class declaration 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>
2017-05-17 08:19:30 +00:00
odr_is_relevant(const type_or_decl_base&);
Initial support to lookup types per location This patch adds support to associate a type to its source location. The location being a string of the form "filepath:line:column". The association is done by a per-translation unit map which associates a location to a type. For the moment this only associates one type to a given location. For the general case, though, we need to associate a vector or types to a given location. We'll add that support later. The patch provides lookup functions, each of which looking up a particular kind of type by its location. * include/abg-fwd.h (get_name_of_qualified_type) (get_name_of_reference_to_type, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_union_type_per_location) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, lookup_pointer_type) (lookup_reference_type, lookup_type_per_location) (lookup_type_through_translation_units) (lookup_type_from_translation_unit, odr_is_relevant): Declare new functions or new function overloads. * include/abg-ir.h (location::expand): Declare new member function. (type_maps::empty): Likewise. (operator|=): Declare an overload for qualified_type_def::CV. (get_string_representation_of_cv_quals) (get_name_of_qualified_type, lookup_qualified_type): Declare new functions. * src/abg-ir.cc (location::expand): Define new member function. (type_maps::empty): Likewise. (odr_is_relevant): Likewise. (get_string_representation_of_cv_quals) (get_name_of_reference_to_type, get_name_of_qualified_type) (lookup_union_type_per_location): Define new functions or overloads. (lookup_basic_type, lookup_enum_type, lookup_typedef_type) (lookup_qualified_type, lookup_pointer_type) (lookup_reference_type, lookup_type_from_translation_unit) (lookup_basic_type_per_location, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_class_type_per_location) (lookup_enum_type_per_location, lookup_enum_type_per_location) (lookup_typedef_type_per_location) (lookup_typedef_type_per_location, lookup_type_per_location): Define new overloads. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Add a new use_type_name_as_key parameter. If it's false, then associates the type to its location rather than to its name. (maybe_update_types_lookup_map): In the overloads for type_decl, class_decl, union_decl, enum_type, typedef_decl, array_type_def, record the type in the lookup map per location, in addition to the per-name recording. (qualified_type_def::build_name): Use the new get_name_of_qualified_type. (qualified_type_def::get_cv_quals_string_prefix): Use the new get_string_representation_of_cv_quals. (operator|=): Define a new overload for qualified_type_def::CV. (pointer_type_def::get_qualified_name): Use the new get_name_of_pointer_to_type. (reference_type_def::get_qualified_name): Use the new get_name_of_reference_to_type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-31 07:34:26 +00:00
Fix class scope setting & member type de-serializing from dwarf * include/abg-fwd.h (add_decl_to_scope, insert_decl_into_scope): return the decl added to the scope. (as_non_member_type, get_type_declaration): Declare new entry points. * include/abg-ir.h (class decl_base::insert_decl_into_scope): Update this friend declaration. (class scope_decl, class_decl): Update the friend add_decl_to_scope declaration. (scope_decl::add_member_decl): Return the added decl. (class_decl_sptr): Move this typedef befoer the class_decl class declaration. (class_decl::definition_of_declaration_): New member. (class_decl::{set_definition_of_declaration, get_definition_of_declaration}): New accessors. (class_decl::add_member_decl): Return the added member. (class_decl::insert_member_type): New member. (class_decl::member_base::access_specifier): Make this protected. (class_decl::member_type): Make this inherit from type_vase. (class_decl::member_type::type_): Remove this member. (class_decl::member_type::as_type): Remove this accessor. (class_decl::member_type::operator==(const type_base&)): New. (class_decl::member_type::operator shared_ptr<type_base>() const): Remove. (class_decl::member_type::get_underlying_type): New. (class_decl::member_type::operator==(const member_type&) const): New. * src/abg-comparison.cc (class_diff::{ensure_lookup_tables_populated, report}): Adjust for the removal of class_decl::member_type::as_type. * src/abg-dwarf-reader.cc (scope_stack_type): Change this as a typedef to stack<scope_decl*>. (current_scope): Change return type from scope_decl_sptr to scope_decl*. (insert_decl_into_scope): New. (build_namespace_decl_and_add_to_ir): Use insert_decl_into_scope in lieu of add_decl_to_scope. (build_class_type_and_add_to_ir): likewise. Link a class definition to its declaration. Push the current scope on the scope stack. Use as_non_member_type. Fix setting member types. (get_scope_for_die): Look through declaration-only classe to get its definition. (build_qualified_type, build_pointer_type_def) (build_reference_type, build_typedef_type, build_var_decl) (build_function_decl): Use as_non_member_type. (build_ir_node_from_die): Fix member variable & function adding. * src/abg-ir.cc (scope_decl::{add_member_decl, insert_member_decl}): Return the added member. (add_decl_to_scope): Likewise. (insert_decl_into_scope): Likewise. (get_top_most_scope_under): Fix logic. (get_type_declaration): New overload that return a decl_base*. (as_non_member_type): New definition. (class_decl::{get_definition_of_declaration, set_definition_of_declaration, insert_member_decl}): Likewise. (class_decl::add_member_decl): Re-write in terms of class::insert_member_decl. (class_decl::insert_member_type): New definition. (class_decl::add_member_type): Re-write in terms of class_decl::insert_member_type. (class_decl::remove_member_type): Update for the class_decl::member_type::as_type removal. (class_decl::{add_data_member, add_member_function, add_member_function_template, add_member_class_template}): Call scope_decl::add_member_decl. (class_decl::member_type::member_type): Update as the type now virtually inherits from type_base. (class_decl::member_type::{set,get}_access_specifier): New definitions. (class_decl::member_type::get_underlying_type): Likewise. (class_decl::member_type::set_scope): Update wrt class_decl::member_type::as_type -> get_underlying_type rename. (class_decl::member_type::operator==(const decl_base& other)): There is no more class_decl::member_type::as_type. (class_decl::member_type::operator==(const type_base& other)): New. (class_decl::member_type::get_pretty_representation): Update wrt class_decl::member_type::as_type -> get_underlying_type rename. * src/abg-reader.cc (build_class_decl): New that add add_member_decl adds even member types, no need to add it explicitly anymore. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-01-13 11:27:47 +00:00
const decl_base*
get_type_declaration(const type_base*);
decl_base*
get_type_declaration(type_base*);
decl_base_sptr
get_type_declaration(const type_base_sptr);
Avoid missing member types while reading bi files * include/abg-fwd.h (get_type_declaration): Declare function. * include/abg-ir.h (class decl_base): Add class_decl as a friend. This to be able to call decl_base::set_scope from class_decl. (scope_decl::add_member_decl): Make this virtual protected, so that it can be called (virtually) from e.g, class_decl. (type_decl_sptr, typedef_decl_sptr): New convenience typedefs. (class_decl::add_member_decl): New virtual overload for scope_decl::add_member_decl. (class_decl::{add_member_type, add_data_member, add_member_function}): New overloads. * src/abg-ir.cc (add_decl_to_scope): Benign style cleanup. (get_type_declaration): Define new function. (class_decl::add_member_decl): New method. (class_decl::add_member_type): Avoid silently added a new member type when that member type has already been (perhaps inadvertently) added to a scope already. Rather, put a strict assert in place there. Also add a new overload that constructs the member type out of a classic type and adds it to the class. (class_decl::{add_data_member, add_member_function}): Likewise. (class_decl::{add_member_function_template, add_member_class_template}): Avoid silently added a new member template when that template has already been (perhaps inadvertently) added to a scope already. Rather, put a strict assert in place there. * src/abg-reader.cc (push_decl_to_current_scope): Take a an extra flag saying if the current decl should be added to the current scope as well (in addition to being pushed onto the stack of scopes maintained in the reader context). (push_and_key_type_decl): Likewise, take that extra flag and pass it to push_decl_to_current_scope. (build_function_decl, build_var_decl, build_type_decl) (build_qualified_type_decl, build_pointer_type_def) (build_reference_type_def, build_enum_type_decl, build_typedef_decl) (build_function_tdecl, build_class_tdecl): Likewise. (build_class_decl): Likewise. When building member data, types, and functions, make sure /not/ to add the data, type of function to the current scope before adding it to the class_decl. This was making the member not being added to the class because it already had a scope. (build_type_tparameter, build_type_composition) (build_non_type_tparameter, build_template_tparameter) (build_type): Adjust to add the template parm to the current scope explicitly, like previously. (handle_type_decl): Use build_type_decl function. Add the type_decl to the current scope, like previously. (handle_namespace_decl, handle_qualified_type_decl) (handle_pointer_type_def, handle_reference_type_def) (handle_enum_type_decl, handle_typedef_decl, handle_var_decl) (handle_function_decl, handle_class_decl, handle_function_tdecl) (handle_class_tdecl): Adjust to add the decl to the current scope, like previously. * tests/data/test-read-write/test21.xml: New test input with member type(def). Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2013-11-19 09:06:04 +00:00
Add a COMPATIBLE_TYPE_CHANGE_CATEGORY to bidiff --no-harmless * include/abg-comparison.h (diff_category::COMPATIBLE_TYPE_CHANGE_CATEGORY): New enumerator. (operator|=(diff_category&, diff_category)): New declaration. * include/abg-fwd.h (is_typedef, strip_typedef) (types_are_compatible): New declarations. * include/abg-ir.h (operator==(const decl_base_sptr, const decl_base_sptr)): Added the consts here. (operator==(const type_base_sptr, const type_base_sptr)): New declaration. * src/abg-comp-filter.cc (is_compatible_change): New static function. (harmless_filter::visit): Detect compatible changes and add the sub-tree into the new COMPATIBLE_TYPE_CHANGE_CATEGORY if applicable. Cleanup the logic. * src/abg-comparison.cc (operator|=(diff_category&, diff_category)): Define new function. (operator==(const decl_base_sptr l, const decl_base_sptr r)): Add consts. (operator==(const type_base_sptr l, const type_base_sptr r)): Define new operator. (is_typedef, strip_typedef, types_are_compatible): New function definitions. * tests/data/test-diff-filter/test3-report.txt: New test report reference. * tests/data/test-diff-filter/test3-v0.cc: Source code for new test input. * tests/data/test-diff-filter/test3-v0.o: New test input. * tests/data/test-diff-filter/test3-v1.cc: Source code for new test input. * tests/data/test-diff-filter/test3-v1.o: New test input. * tests/test-diff-filter.cc: Adjust to consume the new tests inputs above. * tools/bidiff.cc: Add the new COMPATIBLE_TYPE_CHANGE_CATEGORY into the --harmless group. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-04-02 15:23:56 +00:00
bool
types_are_compatible(const type_base_sptr,
const type_base_sptr);
Add a COMPATIBLE_TYPE_CHANGE_CATEGORY to bidiff --no-harmless * include/abg-comparison.h (diff_category::COMPATIBLE_TYPE_CHANGE_CATEGORY): New enumerator. (operator|=(diff_category&, diff_category)): New declaration. * include/abg-fwd.h (is_typedef, strip_typedef) (types_are_compatible): New declarations. * include/abg-ir.h (operator==(const decl_base_sptr, const decl_base_sptr)): Added the consts here. (operator==(const type_base_sptr, const type_base_sptr)): New declaration. * src/abg-comp-filter.cc (is_compatible_change): New static function. (harmless_filter::visit): Detect compatible changes and add the sub-tree into the new COMPATIBLE_TYPE_CHANGE_CATEGORY if applicable. Cleanup the logic. * src/abg-comparison.cc (operator|=(diff_category&, diff_category)): Define new function. (operator==(const decl_base_sptr l, const decl_base_sptr r)): Add consts. (operator==(const type_base_sptr l, const type_base_sptr r)): Define new operator. (is_typedef, strip_typedef, types_are_compatible): New function definitions. * tests/data/test-diff-filter/test3-report.txt: New test report reference. * tests/data/test-diff-filter/test3-v0.cc: Source code for new test input. * tests/data/test-diff-filter/test3-v0.o: New test input. * tests/data/test-diff-filter/test3-v1.cc: Source code for new test input. * tests/data/test-diff-filter/test3-v1.o: New test input. * tests/test-diff-filter.cc: Adjust to consume the new tests inputs above. * tools/bidiff.cc: Add the new COMPATIBLE_TYPE_CHANGE_CATEGORY into the --harmless group. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-04-02 15:23:56 +00:00
bool
types_are_compatible(const decl_base_sptr,
const decl_base_sptr);
Add a COMPATIBLE_TYPE_CHANGE_CATEGORY to bidiff --no-harmless * include/abg-comparison.h (diff_category::COMPATIBLE_TYPE_CHANGE_CATEGORY): New enumerator. (operator|=(diff_category&, diff_category)): New declaration. * include/abg-fwd.h (is_typedef, strip_typedef) (types_are_compatible): New declarations. * include/abg-ir.h (operator==(const decl_base_sptr, const decl_base_sptr)): Added the consts here. (operator==(const type_base_sptr, const type_base_sptr)): New declaration. * src/abg-comp-filter.cc (is_compatible_change): New static function. (harmless_filter::visit): Detect compatible changes and add the sub-tree into the new COMPATIBLE_TYPE_CHANGE_CATEGORY if applicable. Cleanup the logic. * src/abg-comparison.cc (operator|=(diff_category&, diff_category)): Define new function. (operator==(const decl_base_sptr l, const decl_base_sptr r)): Add consts. (operator==(const type_base_sptr l, const type_base_sptr r)): Define new operator. (is_typedef, strip_typedef, types_are_compatible): New function definitions. * tests/data/test-diff-filter/test3-report.txt: New test report reference. * tests/data/test-diff-filter/test3-v0.cc: Source code for new test input. * tests/data/test-diff-filter/test3-v0.o: New test input. * tests/data/test-diff-filter/test3-v1.cc: Source code for new test input. * tests/data/test-diff-filter/test3-v1.o: New test input. * tests/test-diff-filter.cc: Adjust to consume the new tests inputs above. * tools/bidiff.cc: Add the new COMPATIBLE_TYPE_CHANGE_CATEGORY into the --harmless group. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-04-02 15:23:56 +00:00
Support reading namespaces * include/abg-fwd.h (get_global_scope): Return a const global_scope. Add a new overload that takes a naked pointer as parm. (insert_decl_into_scope, get_top_most_scope_under): Declare new entry points. * include/abg-ir.h (class decl_base, class scope_decl): Add insert_decl_into_scope as a friend of these classes. (scope_decl::{insert_decl_into_scope, find_iterator_for_member}): Declare new member. (scope_decl::get_member_decls): New non-const overload. * src/abg-dwarf-reader.cc (build_translation_unit): Remove the "recurse" parameter. Adjust the call to build_ir_node_from_die to read just public decls that are at namespace scope. Anything else should be dropped unless it's needed to emitting the public namespace-level decls. (build_namespace_decl_and_add_to_ir) (canonicalize_and_insert_type_into_ir): Define new static functions. (build_corpus): Adjust ad build_translation_unit doesn't have the "recurse" parameter anymore. (canonicalize_and_add_type_to_ir): Make this static. Fix comments. (build_ir_node_from_die): Take a new "only_public_decl" parameter. For DW_TAG_base_type case, use the new canonicalize_and_insert_type_into_ir to insert the type at the right place in the global scope making sure it is seen before the current scope. For pointer, references and qualified types, use canonicalize_and_insert_type_into_ir to add the type at the same scope as its underlying type. Handle DW_TAG_{namespace,module} using the new build_namespace_decl_and_add_to_ir function. Add some vertical spaces and some assertions. * src/abg-ir.cc (scope_decl::add_member_decl): Use scope_decl_sptr typedef. (scope_decl::{insert_member_decl,find_iterator_for_member}): Define new methods. (insert_decl_into_scope, get_top_most_scope_under): Define new functions. (get_global_scope): Constify the return type. (get_translation_unit): Adjust as get_global_scope now returns a const. * src/abg-reader.cc (get_translation_unit): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2013-12-12 14:40:52 +00:00
const scope_decl*
get_top_most_scope_under(const decl_base*,
const scope_decl*);
const scope_decl*
get_top_most_scope_under(const decl_base_sptr,
Support reading namespaces * include/abg-fwd.h (get_global_scope): Return a const global_scope. Add a new overload that takes a naked pointer as parm. (insert_decl_into_scope, get_top_most_scope_under): Declare new entry points. * include/abg-ir.h (class decl_base, class scope_decl): Add insert_decl_into_scope as a friend of these classes. (scope_decl::{insert_decl_into_scope, find_iterator_for_member}): Declare new member. (scope_decl::get_member_decls): New non-const overload. * src/abg-dwarf-reader.cc (build_translation_unit): Remove the "recurse" parameter. Adjust the call to build_ir_node_from_die to read just public decls that are at namespace scope. Anything else should be dropped unless it's needed to emitting the public namespace-level decls. (build_namespace_decl_and_add_to_ir) (canonicalize_and_insert_type_into_ir): Define new static functions. (build_corpus): Adjust ad build_translation_unit doesn't have the "recurse" parameter anymore. (canonicalize_and_add_type_to_ir): Make this static. Fix comments. (build_ir_node_from_die): Take a new "only_public_decl" parameter. For DW_TAG_base_type case, use the new canonicalize_and_insert_type_into_ir to insert the type at the right place in the global scope making sure it is seen before the current scope. For pointer, references and qualified types, use canonicalize_and_insert_type_into_ir to add the type at the same scope as its underlying type. Handle DW_TAG_{namespace,module} using the new build_namespace_decl_and_add_to_ir function. Add some vertical spaces and some assertions. * src/abg-ir.cc (scope_decl::add_member_decl): Use scope_decl_sptr typedef. (scope_decl::{insert_member_decl,find_iterator_for_member}): Define new methods. (insert_decl_into_scope, get_top_most_scope_under): Define new functions. (get_global_scope): Constify the return type. (get_translation_unit): Adjust as get_global_scope now returns a const. * src/abg-reader.cc (get_translation_unit): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2013-12-12 14:40:52 +00:00
const scope_decl*);
const scope_decl*
get_top_most_scope_under(const decl_base_sptr,
const scope_decl_sptr);
Support reading namespaces * include/abg-fwd.h (get_global_scope): Return a const global_scope. Add a new overload that takes a naked pointer as parm. (insert_decl_into_scope, get_top_most_scope_under): Declare new entry points. * include/abg-ir.h (class decl_base, class scope_decl): Add insert_decl_into_scope as a friend of these classes. (scope_decl::{insert_decl_into_scope, find_iterator_for_member}): Declare new member. (scope_decl::get_member_decls): New non-const overload. * src/abg-dwarf-reader.cc (build_translation_unit): Remove the "recurse" parameter. Adjust the call to build_ir_node_from_die to read just public decls that are at namespace scope. Anything else should be dropped unless it's needed to emitting the public namespace-level decls. (build_namespace_decl_and_add_to_ir) (canonicalize_and_insert_type_into_ir): Define new static functions. (build_corpus): Adjust ad build_translation_unit doesn't have the "recurse" parameter anymore. (canonicalize_and_add_type_to_ir): Make this static. Fix comments. (build_ir_node_from_die): Take a new "only_public_decl" parameter. For DW_TAG_base_type case, use the new canonicalize_and_insert_type_into_ir to insert the type at the right place in the global scope making sure it is seen before the current scope. For pointer, references and qualified types, use canonicalize_and_insert_type_into_ir to add the type at the same scope as its underlying type. Handle DW_TAG_{namespace,module} using the new build_namespace_decl_and_add_to_ir function. Add some vertical spaces and some assertions. * src/abg-ir.cc (scope_decl::add_member_decl): Use scope_decl_sptr typedef. (scope_decl::{insert_member_decl,find_iterator_for_member}): Define new methods. (insert_decl_into_scope, get_top_most_scope_under): Define new functions. (get_global_scope): Constify the return type. (get_translation_unit): Adjust as get_global_scope now returns a const. * src/abg-reader.cc (get_translation_unit): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2013-12-12 14:40:52 +00:00
Better support of static member variables * include/abg-fwd.h (fqn_to_components) (lookup_type_in_translation_unit, demangle_cplus_mangled_name): Declare new public entry points * src/abg-comparison.cc (corpus_diff::report): Report stuff about global variables using their mangled name, and demangle them. If there is no mangled name for the variable, then use its pretty representation. (compute_diff): For the corpus overload, compare global variables using their mangled name, if its available; otherwise, fall back to using their pretty representation. * src/abg-corpus.cc (var_comp::operator()(const var_decl*, const_var_decl*)): Compare variables using their mangled name in priority. If it's not available then use their pretty representation. * src/abg-dwarf-reader.cc (read_context::var_decls_to_re_add_to_tree): New accessor. (build_translation_unit_and_add_to_ir): If there is what appears to be a definition of a static member variable variable -- this is in case this definition lacks the DW_AT_specification attribute that links it to the DW_TAG_member or DW_TAG_variable DIE that is a child of the right class/structure DIE -- that is not at the right place in the DIE tree, remove it from the its current place in the tree and try to hang it off of the right DIE. To do this, de-mangle its mangled name, look at what is supposed to be the parent class name, look it up in the translation unit IR, and if found, stick the variable IR node in there, as a static member variable. If not found, then bad luck. (build_class_type_and_add_to_ir): Do not try to see if a member variable is static here as the way I was doing it was unreliable. Build the data member node directly w/o going through building a variable node first. Register the data member in the die offset -> IR node map. (build_ir_node_from_die): When seeing DW_TAG_variable, look for a DW_AT_specification attribute. If there is one, then it points to a the DIE of a data member and means that data member is static. Flag the IR node of that data member as static thus. Update the die offset -> IR node map. If there is no DW_AT_specification attribute or if it doesn't point to a data member DIE, schedule this variable tag for a stage when after the whole IR is built for the translation unit, the variable's mangled named is inspected, its hypothetical parent struct/class is looked up and the variable IR node is put into the node of the right struct/class IR node. * src/abg-ir.cc (enum lookup_entity_kind): New. (fqn_to_components, iterator, lookup_type_in_translation_unit) (lookup_node_in_translation_unit, lookup_type_in_translation_unit) (demangle_cplus_mangled_name): New function definitions. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-02-19 16:48:15 +00:00
void
fqn_to_components(const std::string&,
std::list<string>&);
Implement fast type lookup in a corpus Profiling has shown that on libraries with a lot of class types declarations (more than 10K types), the phase of resolving those declarations to their definition was a hot spot. The lookup of the type definition inside the entire corpus was the bottleneck. This patch removes (or loosen) that bottleneck by doing away with the graph-walking-based type lookup algorithm that was used. Rather, maps of name -> types are maintained by each scope, in each translation unit. Those maps are updated each time a type is added to a scope. And looking up a type amounts to a lookup in a map. Way faster. * include/abg-fwd.h (components_to_type_name): Declare new function. * include/abg-ir.h (string_type_base_wptr_map_type): New typedef. (translation_unit::{get,set}_types): Declare new member functions. * src/abg-ir.cc (translation_unit::priv::types_): New data member. (translation_unit::{get,set}_types): Define these member functions. (maybe_update_types_lookup_map): Define new static function. (components_to_type_name): Define new function. (scope_decl::{add_member_decl, insert_member_decl}): Call the new maybe_update_types_lookup_map. (scope_decl::find_iterator_for_member): Fix logic. (class_decl::set_is_declaration_only): When a class declaration becomes a definition, update the name -> type map maintained in the scope of the class. (lookup_type_in_translation_unit): Use the hash map of qualified name -> types that is now maintained in the translation unit. This is way faster than the previous walking algorithm. * src/abg-dwarf-reader.cc (build_translation_unit_and_add_to_ir): When fixing up global variable declarations that need to be re-added to the translation unit, use the new fast type lookup function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-10-15 08:14:22 +00:00
string
components_to_type_name(const std::list<string>&);
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
type_decl_sptr
lookup_basic_type(const type_decl&, const translation_unit&);
type_decl_sptr
lookup_basic_type(const interned_string&, const translation_unit&);
type_decl_sptr
lookup_basic_type(const string&, const translation_unit&);
type_decl_sptr
lookup_basic_type(const type_decl&, const corpus&);;
type_decl_sptr
lookup_basic_type(const string&, const corpus&);
type_decl_sptr
lookup_basic_type(const interned_string&, const corpus&);
Initial support to lookup types per location This patch adds support to associate a type to its source location. The location being a string of the form "filepath:line:column". The association is done by a per-translation unit map which associates a location to a type. For the moment this only associates one type to a given location. For the general case, though, we need to associate a vector or types to a given location. We'll add that support later. The patch provides lookup functions, each of which looking up a particular kind of type by its location. * include/abg-fwd.h (get_name_of_qualified_type) (get_name_of_reference_to_type, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_union_type_per_location) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, lookup_pointer_type) (lookup_reference_type, lookup_type_per_location) (lookup_type_through_translation_units) (lookup_type_from_translation_unit, odr_is_relevant): Declare new functions or new function overloads. * include/abg-ir.h (location::expand): Declare new member function. (type_maps::empty): Likewise. (operator|=): Declare an overload for qualified_type_def::CV. (get_string_representation_of_cv_quals) (get_name_of_qualified_type, lookup_qualified_type): Declare new functions. * src/abg-ir.cc (location::expand): Define new member function. (type_maps::empty): Likewise. (odr_is_relevant): Likewise. (get_string_representation_of_cv_quals) (get_name_of_reference_to_type, get_name_of_qualified_type) (lookup_union_type_per_location): Define new functions or overloads. (lookup_basic_type, lookup_enum_type, lookup_typedef_type) (lookup_qualified_type, lookup_pointer_type) (lookup_reference_type, lookup_type_from_translation_unit) (lookup_basic_type_per_location, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_class_type_per_location) (lookup_enum_type_per_location, lookup_enum_type_per_location) (lookup_typedef_type_per_location) (lookup_typedef_type_per_location, lookup_type_per_location): Define new overloads. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Add a new use_type_name_as_key parameter. If it's false, then associates the type to its location rather than to its name. (maybe_update_types_lookup_map): In the overloads for type_decl, class_decl, union_decl, enum_type, typedef_decl, array_type_def, record the type in the lookup map per location, in addition to the per-name recording. (qualified_type_def::build_name): Use the new get_name_of_qualified_type. (qualified_type_def::get_cv_quals_string_prefix): Use the new get_string_representation_of_cv_quals. (operator|=): Define a new overload for qualified_type_def::CV. (pointer_type_def::get_qualified_name): Use the new get_name_of_pointer_to_type. (reference_type_def::get_qualified_name): Use the new get_name_of_reference_to_type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-31 07:34:26 +00:00
type_decl_sptr
lookup_basic_type_per_location(const interned_string&, const corpus&);
type_decl_sptr
lookup_basic_type_per_location(const string&, const corpus&);
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
class_decl_sptr
lookup_class_type(const class_decl&, const translation_unit&);
class_decl_sptr
lookup_class_type(const interned_string&, const translation_unit&);
class_decl_sptr
lookup_class_type(const string&, const translation_unit&);
class_decl_sptr
lookup_class_type(const class_decl&, const corpus&);
class_decl_sptr
lookup_class_type(const interned_string&, const corpus&);
Delay non-complete class type resolution up to end of corpus reading From the DWARF emitted by GCC 4.4.7 for libstdc++ we encountered an interesting construct. A non-complete version of std::runtime_error is declared in libstdc++-v3/src/functexcept.cc and is represented in DWARF as: [ 37344] class_type name (strp) "runtime_error" declaration (flag) Then a bit later, that *non-complete* class is used as a base class for a class, *without* being fully defined! This shouldn't happen but, well, it does: [ 3b3a1] class_type specification (ref4) [ 3733e] byte_size (data1) 16 decl_file (data1) 5 decl_line (data1) 141 containing_type (ref4) [ 3734a] sibling (ref4) [3b405] [ 3b3b1] inheritance type (ref4) [ 37344] <---- here. The thing is that, later, in another translation unit (libstdc++-v3/src/stdexcept.cc), that same class is defined fully: [ 7e9f9] class_type name (strp) "runtime_error" declaration (flag) [...] [ 80c95] class_type specification (ref4) [ 7e9f9] byte_size (data1) 16 decl_file (data1) 4 decl_line (data1) 108 containing_type (ref4) [ 7e9ff] sibling (ref4) [ 80d2b] [...] <---------- and the definition goes here. But then you see that the DIE offset of the "version" of the runtime_error class that is "defined" libstdc++-v3/src/stdexcept.cc in is different from the version that is only declared in libstdc++-v3/src/functexcept.cc. But virtue of the "One Definition Rule", we can assume that they designate the same type. But still, runtime_error should have been defined in libstdc++-v3/src/stdexcept.cc. Anyhow, libabigail needs to be able to handle this. That is, it needs to wait until the entire ABI corpus is loaded from DWARF, then lookup the definition of all the non-complete types we have encountered. And then only after that non-complete type resolution has taken place, we can proceed with type canonicalizing, rather than doing it after the loading of each translation unit like what we were doing previously. This is what this patch does. * include/abg-fwd.h (lookup_type_in_corpus): Declare new function. * src/abg-corpus.cc (lookup_type_in_corpus): Define new function here. * include/abg-ir.h (function_types_type): Declare new typedef. (translation_unit::get_canonical_function_type): Remove member function. (translation_unit::bind_function_type_life_time): Declare new member function. (classes_type): New typedef. * src/abg-ir.cc (translation_unit::priv::canonical_function_types_): Remove data member. (translation_unit::priv::function_types): New data member. (translation_unit::get_canonical_function_type): Remove this function definition. (translation_unit::bind_function_type_life_time): New function definition. (lookup_node_in_scope): Ensure that the type returned is complete. * src/abg-dwarf-reader.cc (string_classes_map): New typedef. (read_context::decl_only_classes_map_): New data member. (read_context::declaration_only_classes): New accessor. (read_context::{maybe_schedule_declaration_only_class_for_resolution, is_decl_only_class_scheduled_for_resolution, resolve_declaration_only_classes, current_elf_file_is_executable, current_elf_file_is_dso}): Define new member functions. (read_context::clear_per_translation_unit_data): Do not clear the data structures that associate DIEs to decls/types or that contain the types to canonicalize here. Rather, clear them ... (read_context::clear_per_corpus_data): ... here instead. (read_context::build_translation_unit_and_add_to_ir): Do not perform late type canonicalizing here. Rather, do it ... (read_debug_info_into_corpus): ... here instead. And before that, call read_context::clear_per_corpus_data() and the new read_context::resolve_declaration_only_classes() here. (build_class_type_and_add_to_ir): Schedule the non-complete types for resolution to complete types. Assert that base classes that are non-complete are scheduled to be completed. (build_function_decl): Do not try to canonicalize function types this early, systematically. Now, all the non-complete types needs to be completed before starting canonicalizing. So let function types go through the normal processes of deciding when to canonicalize them. But then, bind the life time of the function type to the life time of the current translation unit. (maybe_canonicalize_type): If a class type is non-complete, schedule it for late canonicalizing. * src/abg-hash.cc (class_decl::hash::operator()(const class_decl&) const): During hashing, a base class should be complete. * src/abg-reader.cc (read_context::clear_per_translation_unit_data): Do not clear id/xml node, and type maps here. Rather, clear it ... (read_context::clear_per_corpus_data): ... here instead. (read_translation_unit_from_input): Do not perform late canonicalizing here. Rather, do it ... (read_corpus_from_input): ... here. Also, call the new read_context::clear_per_corpus_data() here. (build_function_decl): Do not canonicalize function types here so early. Rather, bind the life time of the function type to the life time of the translation unit. * src/abg-writer.cc (write_translation_unit): Do not clear the type/ID map here. * tests/data/test-read-dwarf/test2.so.abi: Adjust test input. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-17 09:54:12 +00:00
Allow selective resolution of class declaration 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>
2017-05-17 08:19:30 +00:00
const type_base_wptrs_type*
lookup_class_types(const interned_string&, const corpus&);
const type_base_wptrs_type*
lookup_class_types(const string&, const corpus&);
Initial support to lookup types per location This patch adds support to associate a type to its source location. The location being a string of the form "filepath:line:column". The association is done by a per-translation unit map which associates a location to a type. For the moment this only associates one type to a given location. For the general case, though, we need to associate a vector or types to a given location. We'll add that support later. The patch provides lookup functions, each of which looking up a particular kind of type by its location. * include/abg-fwd.h (get_name_of_qualified_type) (get_name_of_reference_to_type, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_union_type_per_location) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, lookup_pointer_type) (lookup_reference_type, lookup_type_per_location) (lookup_type_through_translation_units) (lookup_type_from_translation_unit, odr_is_relevant): Declare new functions or new function overloads. * include/abg-ir.h (location::expand): Declare new member function. (type_maps::empty): Likewise. (operator|=): Declare an overload for qualified_type_def::CV. (get_string_representation_of_cv_quals) (get_name_of_qualified_type, lookup_qualified_type): Declare new functions. * src/abg-ir.cc (location::expand): Define new member function. (type_maps::empty): Likewise. (odr_is_relevant): Likewise. (get_string_representation_of_cv_quals) (get_name_of_reference_to_type, get_name_of_qualified_type) (lookup_union_type_per_location): Define new functions or overloads. (lookup_basic_type, lookup_enum_type, lookup_typedef_type) (lookup_qualified_type, lookup_pointer_type) (lookup_reference_type, lookup_type_from_translation_unit) (lookup_basic_type_per_location, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_class_type_per_location) (lookup_enum_type_per_location, lookup_enum_type_per_location) (lookup_typedef_type_per_location) (lookup_typedef_type_per_location, lookup_type_per_location): Define new overloads. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Add a new use_type_name_as_key parameter. If it's false, then associates the type to its location rather than to its name. (maybe_update_types_lookup_map): In the overloads for type_decl, class_decl, union_decl, enum_type, typedef_decl, array_type_def, record the type in the lookup map per location, in addition to the per-name recording. (qualified_type_def::build_name): Use the new get_name_of_qualified_type. (qualified_type_def::get_cv_quals_string_prefix): Use the new get_string_representation_of_cv_quals. (operator|=): Define a new overload for qualified_type_def::CV. (pointer_type_def::get_qualified_name): Use the new get_name_of_pointer_to_type. (reference_type_def::get_qualified_name): Use the new get_name_of_reference_to_type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-31 07:34:26 +00:00
class_decl_sptr
lookup_class_type_per_location(const interned_string&, const corpus&);
class_decl_sptr
lookup_class_type_per_location(const string&, const corpus&);
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
class_decl_sptr
lookup_class_type(const string&, const corpus&);
class_decl_sptr
lookup_class_type_through_scopes(const std::list<string>&,
const translation_unit&);
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
union_decl_sptr
lookup_union_type(const interned_string&, const translation_unit&);
union_decl_sptr
lookup_union_type(const interned_string&, const corpus&);
Initial support to lookup types per location This patch adds support to associate a type to its source location. The location being a string of the form "filepath:line:column". The association is done by a per-translation unit map which associates a location to a type. For the moment this only associates one type to a given location. For the general case, though, we need to associate a vector or types to a given location. We'll add that support later. The patch provides lookup functions, each of which looking up a particular kind of type by its location. * include/abg-fwd.h (get_name_of_qualified_type) (get_name_of_reference_to_type, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_union_type_per_location) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, lookup_pointer_type) (lookup_reference_type, lookup_type_per_location) (lookup_type_through_translation_units) (lookup_type_from_translation_unit, odr_is_relevant): Declare new functions or new function overloads. * include/abg-ir.h (location::expand): Declare new member function. (type_maps::empty): Likewise. (operator|=): Declare an overload for qualified_type_def::CV. (get_string_representation_of_cv_quals) (get_name_of_qualified_type, lookup_qualified_type): Declare new functions. * src/abg-ir.cc (location::expand): Define new member function. (type_maps::empty): Likewise. (odr_is_relevant): Likewise. (get_string_representation_of_cv_quals) (get_name_of_reference_to_type, get_name_of_qualified_type) (lookup_union_type_per_location): Define new functions or overloads. (lookup_basic_type, lookup_enum_type, lookup_typedef_type) (lookup_qualified_type, lookup_pointer_type) (lookup_reference_type, lookup_type_from_translation_unit) (lookup_basic_type_per_location, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_class_type_per_location) (lookup_enum_type_per_location, lookup_enum_type_per_location) (lookup_typedef_type_per_location) (lookup_typedef_type_per_location, lookup_type_per_location): Define new overloads. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Add a new use_type_name_as_key parameter. If it's false, then associates the type to its location rather than to its name. (maybe_update_types_lookup_map): In the overloads for type_decl, class_decl, union_decl, enum_type, typedef_decl, array_type_def, record the type in the lookup map per location, in addition to the per-name recording. (qualified_type_def::build_name): Use the new get_name_of_qualified_type. (qualified_type_def::get_cv_quals_string_prefix): Use the new get_string_representation_of_cv_quals. (operator|=): Define a new overload for qualified_type_def::CV. (pointer_type_def::get_qualified_name): Use the new get_name_of_pointer_to_type. (reference_type_def::get_qualified_name): Use the new get_name_of_reference_to_type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-31 07:34:26 +00:00
union_decl_sptr
lookup_union_type_per_location(const interned_string&, const corpus&);
union_decl_sptr
lookup_union_type_per_location(const string&, const corpus&);
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
union_decl_sptr
lookup_union_type(const string&, const corpus&);
enum_type_decl_sptr
lookup_enum_type(const enum_type_decl&, const translation_unit&);
enum_type_decl_sptr
lookup_enum_type(const string&, const translation_unit&);
enum_type_decl_sptr
lookup_enum_type(const enum_type_decl&, const corpus&);
enum_type_decl_sptr
lookup_enum_type(const string&, const corpus&);
enum_type_decl_sptr
lookup_enum_type(const interned_string&, const corpus&);
Initial support to lookup types per location This patch adds support to associate a type to its source location. The location being a string of the form "filepath:line:column". The association is done by a per-translation unit map which associates a location to a type. For the moment this only associates one type to a given location. For the general case, though, we need to associate a vector or types to a given location. We'll add that support later. The patch provides lookup functions, each of which looking up a particular kind of type by its location. * include/abg-fwd.h (get_name_of_qualified_type) (get_name_of_reference_to_type, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_union_type_per_location) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, lookup_pointer_type) (lookup_reference_type, lookup_type_per_location) (lookup_type_through_translation_units) (lookup_type_from_translation_unit, odr_is_relevant): Declare new functions or new function overloads. * include/abg-ir.h (location::expand): Declare new member function. (type_maps::empty): Likewise. (operator|=): Declare an overload for qualified_type_def::CV. (get_string_representation_of_cv_quals) (get_name_of_qualified_type, lookup_qualified_type): Declare new functions. * src/abg-ir.cc (location::expand): Define new member function. (type_maps::empty): Likewise. (odr_is_relevant): Likewise. (get_string_representation_of_cv_quals) (get_name_of_reference_to_type, get_name_of_qualified_type) (lookup_union_type_per_location): Define new functions or overloads. (lookup_basic_type, lookup_enum_type, lookup_typedef_type) (lookup_qualified_type, lookup_pointer_type) (lookup_reference_type, lookup_type_from_translation_unit) (lookup_basic_type_per_location, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_class_type_per_location) (lookup_enum_type_per_location, lookup_enum_type_per_location) (lookup_typedef_type_per_location) (lookup_typedef_type_per_location, lookup_type_per_location): Define new overloads. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Add a new use_type_name_as_key parameter. If it's false, then associates the type to its location rather than to its name. (maybe_update_types_lookup_map): In the overloads for type_decl, class_decl, union_decl, enum_type, typedef_decl, array_type_def, record the type in the lookup map per location, in addition to the per-name recording. (qualified_type_def::build_name): Use the new get_name_of_qualified_type. (qualified_type_def::get_cv_quals_string_prefix): Use the new get_string_representation_of_cv_quals. (operator|=): Define a new overload for qualified_type_def::CV. (pointer_type_def::get_qualified_name): Use the new get_name_of_pointer_to_type. (reference_type_def::get_qualified_name): Use the new get_name_of_reference_to_type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-31 07:34:26 +00:00
enum_type_decl_sptr
lookup_enum_type_per_location(const interned_string&, const corpus&);
enum_type_decl_sptr
lookup_enum_type_per_location(const string&, const corpus&);
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
typedef_decl_sptr
lookup_typedef_type(const typedef_decl&, const translation_unit&);
typedef_decl_sptr
lookup_typedef_type(const typedef_decl&, const corpus&);
Initial support to lookup types per location This patch adds support to associate a type to its source location. The location being a string of the form "filepath:line:column". The association is done by a per-translation unit map which associates a location to a type. For the moment this only associates one type to a given location. For the general case, though, we need to associate a vector or types to a given location. We'll add that support later. The patch provides lookup functions, each of which looking up a particular kind of type by its location. * include/abg-fwd.h (get_name_of_qualified_type) (get_name_of_reference_to_type, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_union_type_per_location) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, lookup_pointer_type) (lookup_reference_type, lookup_type_per_location) (lookup_type_through_translation_units) (lookup_type_from_translation_unit, odr_is_relevant): Declare new functions or new function overloads. * include/abg-ir.h (location::expand): Declare new member function. (type_maps::empty): Likewise. (operator|=): Declare an overload for qualified_type_def::CV. (get_string_representation_of_cv_quals) (get_name_of_qualified_type, lookup_qualified_type): Declare new functions. * src/abg-ir.cc (location::expand): Define new member function. (type_maps::empty): Likewise. (odr_is_relevant): Likewise. (get_string_representation_of_cv_quals) (get_name_of_reference_to_type, get_name_of_qualified_type) (lookup_union_type_per_location): Define new functions or overloads. (lookup_basic_type, lookup_enum_type, lookup_typedef_type) (lookup_qualified_type, lookup_pointer_type) (lookup_reference_type, lookup_type_from_translation_unit) (lookup_basic_type_per_location, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_class_type_per_location) (lookup_enum_type_per_location, lookup_enum_type_per_location) (lookup_typedef_type_per_location) (lookup_typedef_type_per_location, lookup_type_per_location): Define new overloads. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Add a new use_type_name_as_key parameter. If it's false, then associates the type to its location rather than to its name. (maybe_update_types_lookup_map): In the overloads for type_decl, class_decl, union_decl, enum_type, typedef_decl, array_type_def, record the type in the lookup map per location, in addition to the per-name recording. (qualified_type_def::build_name): Use the new get_name_of_qualified_type. (qualified_type_def::get_cv_quals_string_prefix): Use the new get_string_representation_of_cv_quals. (operator|=): Define a new overload for qualified_type_def::CV. (pointer_type_def::get_qualified_name): Use the new get_name_of_pointer_to_type. (reference_type_def::get_qualified_name): Use the new get_name_of_reference_to_type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-31 07:34:26 +00:00
typedef_decl_sptr
lookup_typedef_type(const interned_string& type_name,
const translation_unit& tu);
typedef_decl_sptr
lookup_typedef_type(const string& type_name, const translation_unit& tu);
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
typedef_decl_sptr
lookup_typedef_type(const interned_string&, const corpus&);
Initial support to lookup types per location This patch adds support to associate a type to its source location. The location being a string of the form "filepath:line:column". The association is done by a per-translation unit map which associates a location to a type. For the moment this only associates one type to a given location. For the general case, though, we need to associate a vector or types to a given location. We'll add that support later. The patch provides lookup functions, each of which looking up a particular kind of type by its location. * include/abg-fwd.h (get_name_of_qualified_type) (get_name_of_reference_to_type, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_union_type_per_location) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, lookup_pointer_type) (lookup_reference_type, lookup_type_per_location) (lookup_type_through_translation_units) (lookup_type_from_translation_unit, odr_is_relevant): Declare new functions or new function overloads. * include/abg-ir.h (location::expand): Declare new member function. (type_maps::empty): Likewise. (operator|=): Declare an overload for qualified_type_def::CV. (get_string_representation_of_cv_quals) (get_name_of_qualified_type, lookup_qualified_type): Declare new functions. * src/abg-ir.cc (location::expand): Define new member function. (type_maps::empty): Likewise. (odr_is_relevant): Likewise. (get_string_representation_of_cv_quals) (get_name_of_reference_to_type, get_name_of_qualified_type) (lookup_union_type_per_location): Define new functions or overloads. (lookup_basic_type, lookup_enum_type, lookup_typedef_type) (lookup_qualified_type, lookup_pointer_type) (lookup_reference_type, lookup_type_from_translation_unit) (lookup_basic_type_per_location, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_class_type_per_location) (lookup_enum_type_per_location, lookup_enum_type_per_location) (lookup_typedef_type_per_location) (lookup_typedef_type_per_location, lookup_type_per_location): Define new overloads. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Add a new use_type_name_as_key parameter. If it's false, then associates the type to its location rather than to its name. (maybe_update_types_lookup_map): In the overloads for type_decl, class_decl, union_decl, enum_type, typedef_decl, array_type_def, record the type in the lookup map per location, in addition to the per-name recording. (qualified_type_def::build_name): Use the new get_name_of_qualified_type. (qualified_type_def::get_cv_quals_string_prefix): Use the new get_string_representation_of_cv_quals. (operator|=): Define a new overload for qualified_type_def::CV. (pointer_type_def::get_qualified_name): Use the new get_name_of_pointer_to_type. (reference_type_def::get_qualified_name): Use the new get_name_of_reference_to_type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-31 07:34:26 +00:00
typedef_decl_sptr
lookup_typedef_type_per_location(const interned_string&, const corpus &);
typedef_decl_sptr
lookup_typedef_type_per_location(const string&, const corpus &);
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
typedef_decl_sptr
lookup_typedef_type(const string&, const corpus&);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
type_base_sptr
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
lookup_class_or_typedef_type(const string&, const translation_unit&);
Better support of static member variables * include/abg-fwd.h (fqn_to_components) (lookup_type_in_translation_unit, demangle_cplus_mangled_name): Declare new public entry points * src/abg-comparison.cc (corpus_diff::report): Report stuff about global variables using their mangled name, and demangle them. If there is no mangled name for the variable, then use its pretty representation. (compute_diff): For the corpus overload, compare global variables using their mangled name, if its available; otherwise, fall back to using their pretty representation. * src/abg-corpus.cc (var_comp::operator()(const var_decl*, const_var_decl*)): Compare variables using their mangled name in priority. If it's not available then use their pretty representation. * src/abg-dwarf-reader.cc (read_context::var_decls_to_re_add_to_tree): New accessor. (build_translation_unit_and_add_to_ir): If there is what appears to be a definition of a static member variable variable -- this is in case this definition lacks the DW_AT_specification attribute that links it to the DW_TAG_member or DW_TAG_variable DIE that is a child of the right class/structure DIE -- that is not at the right place in the DIE tree, remove it from the its current place in the tree and try to hang it off of the right DIE. To do this, de-mangle its mangled name, look at what is supposed to be the parent class name, look it up in the translation unit IR, and if found, stick the variable IR node in there, as a static member variable. If not found, then bad luck. (build_class_type_and_add_to_ir): Do not try to see if a member variable is static here as the way I was doing it was unreliable. Build the data member node directly w/o going through building a variable node first. Register the data member in the die offset -> IR node map. (build_ir_node_from_die): When seeing DW_TAG_variable, look for a DW_AT_specification attribute. If there is one, then it points to a the DIE of a data member and means that data member is static. Flag the IR node of that data member as static thus. Update the die offset -> IR node map. If there is no DW_AT_specification attribute or if it doesn't point to a data member DIE, schedule this variable tag for a stage when after the whole IR is built for the translation unit, the variable's mangled named is inspected, its hypothetical parent struct/class is looked up and the variable IR node is put into the node of the right struct/class IR node. * src/abg-ir.cc (enum lookup_entity_kind): New. (fqn_to_components, iterator, lookup_type_in_translation_unit) (lookup_node_in_translation_unit, lookup_type_in_translation_unit) (demangle_cplus_mangled_name): New function definitions. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-02-19 16:48:15 +00:00
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
type_base_sptr
lookup_class_typedef_or_enum_type(const string&, const translation_unit&);
Better support of static member variables * include/abg-fwd.h (fqn_to_components) (lookup_type_in_translation_unit, demangle_cplus_mangled_name): Declare new public entry points * src/abg-comparison.cc (corpus_diff::report): Report stuff about global variables using their mangled name, and demangle them. If there is no mangled name for the variable, then use its pretty representation. (compute_diff): For the corpus overload, compare global variables using their mangled name, if its available; otherwise, fall back to using their pretty representation. * src/abg-corpus.cc (var_comp::operator()(const var_decl*, const_var_decl*)): Compare variables using their mangled name in priority. If it's not available then use their pretty representation. * src/abg-dwarf-reader.cc (read_context::var_decls_to_re_add_to_tree): New accessor. (build_translation_unit_and_add_to_ir): If there is what appears to be a definition of a static member variable variable -- this is in case this definition lacks the DW_AT_specification attribute that links it to the DW_TAG_member or DW_TAG_variable DIE that is a child of the right class/structure DIE -- that is not at the right place in the DIE tree, remove it from the its current place in the tree and try to hang it off of the right DIE. To do this, de-mangle its mangled name, look at what is supposed to be the parent class name, look it up in the translation unit IR, and if found, stick the variable IR node in there, as a static member variable. If not found, then bad luck. (build_class_type_and_add_to_ir): Do not try to see if a member variable is static here as the way I was doing it was unreliable. Build the data member node directly w/o going through building a variable node first. Register the data member in the die offset -> IR node map. (build_ir_node_from_die): When seeing DW_TAG_variable, look for a DW_AT_specification attribute. If there is one, then it points to a the DIE of a data member and means that data member is static. Flag the IR node of that data member as static thus. Update the die offset -> IR node map. If there is no DW_AT_specification attribute or if it doesn't point to a data member DIE, schedule this variable tag for a stage when after the whole IR is built for the translation unit, the variable's mangled named is inspected, its hypothetical parent struct/class is looked up and the variable IR node is put into the node of the right struct/class IR node. * src/abg-ir.cc (enum lookup_entity_kind): New. (fqn_to_components, iterator, lookup_type_in_translation_unit) (lookup_node_in_translation_unit, lookup_type_in_translation_unit) (demangle_cplus_mangled_name): New function definitions. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-02-19 16:48:15 +00:00
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
type_base_sptr
lookup_class_or_typedef_type(const string&, const corpus&);
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
type_base_sptr
lookup_class_typedef_or_enum_type(const string&, const corpus&);
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
qualified_type_def_sptr
lookup_qualified_type(const qualified_type_def&, const translation_unit&);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
qualified_type_def_sptr
lookup_qualified_type(const string&, const translation_unit&);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
qualified_type_def_sptr
lookup_qualified_type(const qualified_type_def&, const corpus&);
Fix type synthesis to fix abicompat weak mode While looking further in the issue Sinny Kumari reported, I realized that the weak mode wasn't working in that example either. It turned out that synthesizing qualified types was not working because we were just looking them up in the binary, rather than looking up the un-qualified underlying type and then synthezing the resulting qualified type. This patch just does that. * include/abg-fwd.h (synthesize_type_from_translation_unit): Declare new function. (synthesize_function_type_from_translation_unit): Make the translation_unit parameter non-const because the function needs to bind the life time of the synthesized function to the life time of the translation unit. Make this function be a friend of abigail::ir::translation_unit. (synthesize_function_type_from_translation_unit): * src/abg-ir.cc (translation_unit::priv::synthesized_types_): New data member. (synthesize_type_from_translation_unit): Define new function. (synthesize_function_type_from_translation_unit): Make the translation_unit parameter non-const. If the return is void, then take that in account carefuly. Rather than just looking up the type of parameters and return value, synthesize them too, especially when they are qualified types. Bind the life time of the synthesized function type to the lifetime of the translation unit. * tests/data/test-abicompat/test7-fn-changed-report-1.txt: New test reference output. * tests/test-abicompat.cc (in_out_spec): Run the harness on the exisiting test7-fn-changed-app and libtest7-fn-changed-libapp-v1 but in weak mode this time. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-20 14:14:01 +00:00
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
qualified_type_def_sptr
lookup_qualified_type(const interned_string&, const corpus&);
pointer_type_def_sptr
lookup_pointer_type(const pointer_type_def&, const translation_unit&);
pointer_type_def_sptr
lookup_pointer_type(const string&, const translation_unit&);
Initial support to lookup types per location This patch adds support to associate a type to its source location. The location being a string of the form "filepath:line:column". The association is done by a per-translation unit map which associates a location to a type. For the moment this only associates one type to a given location. For the general case, though, we need to associate a vector or types to a given location. We'll add that support later. The patch provides lookup functions, each of which looking up a particular kind of type by its location. * include/abg-fwd.h (get_name_of_qualified_type) (get_name_of_reference_to_type, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_union_type_per_location) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, lookup_pointer_type) (lookup_reference_type, lookup_type_per_location) (lookup_type_through_translation_units) (lookup_type_from_translation_unit, odr_is_relevant): Declare new functions or new function overloads. * include/abg-ir.h (location::expand): Declare new member function. (type_maps::empty): Likewise. (operator|=): Declare an overload for qualified_type_def::CV. (get_string_representation_of_cv_quals) (get_name_of_qualified_type, lookup_qualified_type): Declare new functions. * src/abg-ir.cc (location::expand): Define new member function. (type_maps::empty): Likewise. (odr_is_relevant): Likewise. (get_string_representation_of_cv_quals) (get_name_of_reference_to_type, get_name_of_qualified_type) (lookup_union_type_per_location): Define new functions or overloads. (lookup_basic_type, lookup_enum_type, lookup_typedef_type) (lookup_qualified_type, lookup_pointer_type) (lookup_reference_type, lookup_type_from_translation_unit) (lookup_basic_type_per_location, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_class_type_per_location) (lookup_enum_type_per_location, lookup_enum_type_per_location) (lookup_typedef_type_per_location) (lookup_typedef_type_per_location, lookup_type_per_location): Define new overloads. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Add a new use_type_name_as_key parameter. If it's false, then associates the type to its location rather than to its name. (maybe_update_types_lookup_map): In the overloads for type_decl, class_decl, union_decl, enum_type, typedef_decl, array_type_def, record the type in the lookup map per location, in addition to the per-name recording. (qualified_type_def::build_name): Use the new get_name_of_qualified_type. (qualified_type_def::get_cv_quals_string_prefix): Use the new get_string_representation_of_cv_quals. (operator|=): Define a new overload for qualified_type_def::CV. (pointer_type_def::get_qualified_name): Use the new get_name_of_pointer_to_type. (reference_type_def::get_qualified_name): Use the new get_name_of_reference_to_type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-31 07:34:26 +00:00
pointer_type_def_sptr
lookup_pointer_type(const type_base_sptr& pointed_to_type,
const translation_unit& tu);
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
pointer_type_def_sptr
lookup_pointer_type(const pointer_type_def&, const corpus&);
pointer_type_def_sptr
lookup_pointer_type(const interned_string&, const corpus&);
const reference_type_def_sptr
lookup_reference_type(const reference_type_def&, const translation_unit&);
const reference_type_def_sptr
lookup_reference_type(const string&, const translation_unit&);
Initial support to lookup types per location This patch adds support to associate a type to its source location. The location being a string of the form "filepath:line:column". The association is done by a per-translation unit map which associates a location to a type. For the moment this only associates one type to a given location. For the general case, though, we need to associate a vector or types to a given location. We'll add that support later. The patch provides lookup functions, each of which looking up a particular kind of type by its location. * include/abg-fwd.h (get_name_of_qualified_type) (get_name_of_reference_to_type, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_union_type_per_location) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, lookup_pointer_type) (lookup_reference_type, lookup_type_per_location) (lookup_type_through_translation_units) (lookup_type_from_translation_unit, odr_is_relevant): Declare new functions or new function overloads. * include/abg-ir.h (location::expand): Declare new member function. (type_maps::empty): Likewise. (operator|=): Declare an overload for qualified_type_def::CV. (get_string_representation_of_cv_quals) (get_name_of_qualified_type, lookup_qualified_type): Declare new functions. * src/abg-ir.cc (location::expand): Define new member function. (type_maps::empty): Likewise. (odr_is_relevant): Likewise. (get_string_representation_of_cv_quals) (get_name_of_reference_to_type, get_name_of_qualified_type) (lookup_union_type_per_location): Define new functions or overloads. (lookup_basic_type, lookup_enum_type, lookup_typedef_type) (lookup_qualified_type, lookup_pointer_type) (lookup_reference_type, lookup_type_from_translation_unit) (lookup_basic_type_per_location, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_class_type_per_location) (lookup_enum_type_per_location, lookup_enum_type_per_location) (lookup_typedef_type_per_location) (lookup_typedef_type_per_location, lookup_type_per_location): Define new overloads. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Add a new use_type_name_as_key parameter. If it's false, then associates the type to its location rather than to its name. (maybe_update_types_lookup_map): In the overloads for type_decl, class_decl, union_decl, enum_type, typedef_decl, array_type_def, record the type in the lookup map per location, in addition to the per-name recording. (qualified_type_def::build_name): Use the new get_name_of_qualified_type. (qualified_type_def::get_cv_quals_string_prefix): Use the new get_string_representation_of_cv_quals. (operator|=): Define a new overload for qualified_type_def::CV. (pointer_type_def::get_qualified_name): Use the new get_name_of_pointer_to_type. (reference_type_def::get_qualified_name): Use the new get_name_of_reference_to_type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-31 07:34:26 +00:00
const reference_type_def_sptr
lookup_reference_type(const type_base_sptr& pointed_to_type,
bool lvalue_reference,
const translation_unit& tu);
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
reference_type_def_sptr
lookup_reference_type(const reference_type_def&, const corpus&);
reference_type_def_sptr
lookup_reference_type(const interned_string&, const corpus&);
array_type_def_sptr
lookup_array_type(const array_type_def&, const translation_unit&);
array_type_def_sptr
lookup_array_type(const string&, const translation_unit&);
array_type_def_sptr
lookup_array_type(const array_type_def&, const corpus&);
array_type_def_sptr
lookup_array_type(const interned_string&, const corpus&);
function_type_sptr
lookup_function_type(const string&,
const translation_unit&);
function_type_sptr
lookup_function_type(const interned_string&,
const translation_unit&);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
function_type_sptr
lookup_function_type(const function_type&,
const translation_unit&);
function_type_sptr
lookup_function_type(const function_type_sptr&,
const translation_unit&);
function_type_sptr
lookup_function_type(const function_type&, const corpus&);
function_type_sptr
lookup_function_type(const function_type_sptr&, const corpus&);
function_type_sptr
lookup_function_type(const function_type&, const corpus&);
function_type_sptr
lookup_function_type(const interned_string&, const corpus&);
type_base_sptr
lookup_type(const string&, const translation_unit&);
const type_base_sptr
lookup_type(const type_base_sptr, const translation_unit&);
type_base_sptr
lookup_type(const interned_string&, const corpus&);
Initial support to lookup types per location This patch adds support to associate a type to its source location. The location being a string of the form "filepath:line:column". The association is done by a per-translation unit map which associates a location to a type. For the moment this only associates one type to a given location. For the general case, though, we need to associate a vector or types to a given location. We'll add that support later. The patch provides lookup functions, each of which looking up a particular kind of type by its location. * include/abg-fwd.h (get_name_of_qualified_type) (get_name_of_reference_to_type, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_union_type_per_location) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, lookup_pointer_type) (lookup_reference_type, lookup_type_per_location) (lookup_type_through_translation_units) (lookup_type_from_translation_unit, odr_is_relevant): Declare new functions or new function overloads. * include/abg-ir.h (location::expand): Declare new member function. (type_maps::empty): Likewise. (operator|=): Declare an overload for qualified_type_def::CV. (get_string_representation_of_cv_quals) (get_name_of_qualified_type, lookup_qualified_type): Declare new functions. * src/abg-ir.cc (location::expand): Define new member function. (type_maps::empty): Likewise. (odr_is_relevant): Likewise. (get_string_representation_of_cv_quals) (get_name_of_reference_to_type, get_name_of_qualified_type) (lookup_union_type_per_location): Define new functions or overloads. (lookup_basic_type, lookup_enum_type, lookup_typedef_type) (lookup_qualified_type, lookup_pointer_type) (lookup_reference_type, lookup_type_from_translation_unit) (lookup_basic_type_per_location, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_class_type_per_location) (lookup_enum_type_per_location, lookup_enum_type_per_location) (lookup_typedef_type_per_location) (lookup_typedef_type_per_location, lookup_type_per_location): Define new overloads. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Add a new use_type_name_as_key parameter. If it's false, then associates the type to its location rather than to its name. (maybe_update_types_lookup_map): In the overloads for type_decl, class_decl, union_decl, enum_type, typedef_decl, array_type_def, record the type in the lookup map per location, in addition to the per-name recording. (qualified_type_def::build_name): Use the new get_name_of_qualified_type. (qualified_type_def::get_cv_quals_string_prefix): Use the new get_string_representation_of_cv_quals. (operator|=): Define a new overload for qualified_type_def::CV. (pointer_type_def::get_qualified_name): Use the new get_name_of_pointer_to_type. (reference_type_def::get_qualified_name): Use the new get_name_of_reference_to_type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-31 07:34:26 +00:00
type_base_sptr
lookup_type_per_location(const interned_string&, const corpus&);
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
type_base_sptr
lookup_type(const type_base&, const corpus&);
type_base_sptr
lookup_type(const type_base_sptr&, const corpus&);
type_base_sptr
lookup_type_through_scopes(const std::list<string>&,
const translation_unit&);
Initial support to lookup types per location This patch adds support to associate a type to its source location. The location being a string of the form "filepath:line:column". The association is done by a per-translation unit map which associates a location to a type. For the moment this only associates one type to a given location. For the general case, though, we need to associate a vector or types to a given location. We'll add that support later. The patch provides lookup functions, each of which looking up a particular kind of type by its location. * include/abg-fwd.h (get_name_of_qualified_type) (get_name_of_reference_to_type, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_union_type_per_location) (lookup_enum_type_per_location, lookup_typedef_type) (lookup_typedef_type_per_location, lookup_pointer_type) (lookup_reference_type, lookup_type_per_location) (lookup_type_through_translation_units) (lookup_type_from_translation_unit, odr_is_relevant): Declare new functions or new function overloads. * include/abg-ir.h (location::expand): Declare new member function. (type_maps::empty): Likewise. (operator|=): Declare an overload for qualified_type_def::CV. (get_string_representation_of_cv_quals) (get_name_of_qualified_type, lookup_qualified_type): Declare new functions. * src/abg-ir.cc (location::expand): Define new member function. (type_maps::empty): Likewise. (odr_is_relevant): Likewise. (get_string_representation_of_cv_quals) (get_name_of_reference_to_type, get_name_of_qualified_type) (lookup_union_type_per_location): Define new functions or overloads. (lookup_basic_type, lookup_enum_type, lookup_typedef_type) (lookup_qualified_type, lookup_pointer_type) (lookup_reference_type, lookup_type_from_translation_unit) (lookup_basic_type_per_location, lookup_basic_type_per_location) (lookup_class_type_per_location, lookup_class_type_per_location) (lookup_enum_type_per_location, lookup_enum_type_per_location) (lookup_typedef_type_per_location) (lookup_typedef_type_per_location, lookup_type_per_location): Define new overloads. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Add a new use_type_name_as_key parameter. If it's false, then associates the type to its location rather than to its name. (maybe_update_types_lookup_map): In the overloads for type_decl, class_decl, union_decl, enum_type, typedef_decl, array_type_def, record the type in the lookup map per location, in addition to the per-name recording. (qualified_type_def::build_name): Use the new get_name_of_qualified_type. (qualified_type_def::get_cv_quals_string_prefix): Use the new get_string_representation_of_cv_quals. (operator|=): Define a new overload for qualified_type_def::CV. (pointer_type_def::get_qualified_name): Use the new get_name_of_pointer_to_type. (reference_type_def::get_qualified_name): Use the new get_name_of_reference_to_type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-03-31 07:34:26 +00:00
type_base_sptr
lookup_type_through_translation_units(const string&, const corpus&);
type_base_sptr
lookup_type_from_translation_unit(const string& type_name,
const string& tu_path,
const corpus& corp);
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
function_type_sptr
lookup_or_synthesize_fn_type(const function_type_sptr&,
const corpus&);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
type_base_sptr
Handle per translation unit and per corpus types maps Today, whenever a type is added to its scope, a map that associates the qualified type name to the type is updated. There is only one such map in a given ABI corpus. So whenever a type is looked up from its name, it's that per-corpus type map that is used. This setup makes libabigail type lookup be tailored only for binaries that respect the One Definition Rule of C++[1] (aka ODR) which basically says that there should be only one type of a given name in an ABI corpus. It turns out that many binaries, especically C binaries, don't respect the ODR. So a type "struct foo" can be defined in a file a.c and another *different* type "struct foo" can also be defined in b.c. What a useful and safe feature! Not. For those binaries, just having one type map doesn't work. We need to have one type map per translation unit, and one map per-corpus map. This is the strategy implemented by this patch. With this patch, whenever a type is added to its scope, a per translation unit type map is updated. The per corpus map is updated as well. If there are more than one type of a given name, the entry in the per corpus type map for that type is left empty. Type lookup now potentially becomes a two phases lookup. Whenever a type is looked up from its name, the per corpus type map is looked at first. If the type is not in that per corpus type map, then the per translation unit type maps are lookup up, in sequence. The patch thus re-visits the type maps updating and lookup routines to adapt them to the new scheme. The patch also updates the clients of the type map updating and lookup code. Note that this patch is part of a series of patches which aims to move libabigails away from its ODR-centric organization to make it work well also on binary where the ODR is not relevant. As such, the patch doesn't assure that "make check" passes. To have "make check" pass, you need to have all the patches of the series applied. [1]: https://en.wikipedia.org/wiki/One_Definition_Rule * include/abg-fwd.h (lookup_type_in_corpus): Remove. This is to be replaced by the new lookup_type below. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): (lookup_class_type_through_scopes, lookup_type) (lookup_type_through_scopes, lookup_or_synthesize_fn_type) * src/abg-ir-priv.h (struct translation_unit::priv): Move this private type here, from abg-ir.h. (synthesize_type_from_translation_unit): Declare new functions. * include/abg-ir.h (class type_maps): Define new type. (translation_unit::get_function_types): Remove. (translation_unit::get_types): Now return a type_maps. (translation_unit::get_live_fn_types): Declare new type. (class decl_base): Make canonicalize be a friend of this class. * src/abg-ir.cc (struct translation_unit::priv): Move this to abg-ir-priv.h (struct type_maps::priv): Define new type. (type_maps::{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Define new accessors. (translation_unit::bind_function_type_life_time): Adjust. (translation_unit::get_function_types): Remove accessor. (translation_unit::get_types, get_live_fn_types): Define new accessors. (lookup_type_in_translation_unit) (lookup_class_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_class_type_in_translation_unit) Remove function definitions. (lookup_type_in_map): Define function template. (lookup_{basic, class, union, typedef, class_or_typedef, class_typedef_or_enum, qualified, pointer, reference, array, function}_type): Define functions. (lookup_function_type, lookup_type_through_scopes) (lookup_class_type_through_scopes) (lookup_basic_type_through_translation_units) (lookup_union_type_through_translation_units) (lookup_enum_type_through_translation_units) (lookup_class_type_through_translation_units) (lookup_typedef_type_through_translation_units) (lookup_qualified_type_through_translation_units) (lookup_pointer_type_through_translation_units) (lookup_reference_type_through_translation_units) (lookup_array_type_through_translation_units) (lookup_function_type_through_translation_units) (lookup_type_through_translation_units) (lookup_or_synthesize_fn_type, lookup_type): Likewise. (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Define function template, specilizations and functions. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Define functions. * include/abg-corpus.h (corpus::get_types): Declare new accessor. * src/abg-corpus.cc (corpus::priv::get_types): Define new accessor. (corpus::get_types): Likewise. (lookup_type_in_corpus, lookup_class_type_in_corpus) (lookup_type_in_corpus, lookup_function_type_in_corpus) (maybe_update_types_lookup_map) (maybe_update_types_lookup_map<class_decl>) (maybe_update_types_lookup_map<function_type>): Remove. (lookup_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function, class_or_typedef, class_typedef_or_enum}_type): Likewise. * src/abg-corpus-priv.h (corpus::priv::{basic, class, union, typedef, qualified, pointer, reference, array, function}_types): Remove these data members. (corpus::priv::get_scopes): Remove member function. (corpus::priv::get_{basic, class, union, enum, typedef, qualified, pointer, reference, array, function}_types): Remove member function declarations. (corpus::priv::types_): New data member. (corpus::priv::get_types): Declare new member function. (lookup_{basic, class, enum, typedef, class_or_typedef, qualified, pointer, reference, array, function}_type): Declare new functions. * src/abg-dwarf-reader.cc (read_context::resolve_declaration_only_classes) (build_translation_unit_and_add_to_ir): Adjust use of lookup_class_type. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Adjust to the use of lookup_function_type_in_translation_unit that got renamed into lookup_function_type. * src/abg-writer.cc (type_ptr_cmp::operator()): New operator implementation. (read_context::sort_type): Add new overloads. (write_translation_unit): Adjust to get the function types from the new translation_unit::get_live_fn_types and sort them. * tools/abicompat.cc (perform_compat_check_in_weak_mode): Adjust to use the new lookup_or_synthesize_fn_type, in lieu of lookup_function_type_in_corpus. Adjust to use lookup_type in lieu of lookup_type_in_corpus. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2017-01-02 21:40:39 +00:00
synthesize_type_from_translation_unit(const type_base_sptr&,
translation_unit&);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
function_type_sptr
synthesize_function_type_from_translation_unit(const function_type&,
translation_unit&);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
const type_base_sptr
lookup_type_in_scope(const string&,
const scope_decl_sptr&);
const type_base_sptr
lookup_type_in_scope(const std::list<string>&,
const scope_decl_sptr&);
const decl_base_sptr
lookup_var_decl_in_scope(const string&,
const scope_decl_sptr&);
const decl_base_sptr
lookup_var_decl_in_scope(const std::list<string>&,
const scope_decl_sptr&);
Better support of static member variables * include/abg-fwd.h (fqn_to_components) (lookup_type_in_translation_unit, demangle_cplus_mangled_name): Declare new public entry points * src/abg-comparison.cc (corpus_diff::report): Report stuff about global variables using their mangled name, and demangle them. If there is no mangled name for the variable, then use its pretty representation. (compute_diff): For the corpus overload, compare global variables using their mangled name, if its available; otherwise, fall back to using their pretty representation. * src/abg-corpus.cc (var_comp::operator()(const var_decl*, const_var_decl*)): Compare variables using their mangled name in priority. If it's not available then use their pretty representation. * src/abg-dwarf-reader.cc (read_context::var_decls_to_re_add_to_tree): New accessor. (build_translation_unit_and_add_to_ir): If there is what appears to be a definition of a static member variable variable -- this is in case this definition lacks the DW_AT_specification attribute that links it to the DW_TAG_member or DW_TAG_variable DIE that is a child of the right class/structure DIE -- that is not at the right place in the DIE tree, remove it from the its current place in the tree and try to hang it off of the right DIE. To do this, de-mangle its mangled name, look at what is supposed to be the parent class name, look it up in the translation unit IR, and if found, stick the variable IR node in there, as a static member variable. If not found, then bad luck. (build_class_type_and_add_to_ir): Do not try to see if a member variable is static here as the way I was doing it was unreliable. Build the data member node directly w/o going through building a variable node first. Register the data member in the die offset -> IR node map. (build_ir_node_from_die): When seeing DW_TAG_variable, look for a DW_AT_specification attribute. If there is one, then it points to a the DIE of a data member and means that data member is static. Flag the IR node of that data member as static thus. Update the die offset -> IR node map. If there is no DW_AT_specification attribute or if it doesn't point to a data member DIE, schedule this variable tag for a stage when after the whole IR is built for the translation unit, the variable's mangled named is inspected, its hypothetical parent struct/class is looked up and the variable IR node is put into the node of the right struct/class IR node. * src/abg-ir.cc (enum lookup_entity_kind): New. (fqn_to_components, iterator, lookup_type_in_translation_unit) (lookup_node_in_translation_unit, lookup_type_in_translation_unit) (demangle_cplus_mangled_name): New function definitions. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-02-19 16:48:15 +00:00
string
demangle_cplus_mangled_name(const string&);
type_base_sptr
type_or_void(const type_base_sptr, const environment*);
Canonicalize types either early or late after TU reading While trying to diff two identical files (abidiff foo.so foo.so) it appeared that canonicalizing types during e.g, the DWARF reading process was leading to subtle errors because it's extremely hard to know when a type is complete. That is, during the building of a class type C, a pointer to C can be built before C is complete. Worse, even after reading the DIE (from DWARF) of class C, there can be DIE seen later in the translation unit that modifies type C. In these late cases, one needs to wait -- not only until C is fully built, but also sometimes, after the translation unit is fully built -- to canonicalize C and then the pointer to C. This kind of things. So now there are two possible points in time when canonicalization of a type can happen. It can happen early, when the type is built. This is the case for basic types and composite types for which all sub-types are canonicalized already. It can happen late, right after we've finished reading the debug info for the current translation unit. So this patch fixes the IR traversal and uses that to walk the translation unit (or even types) after it's built. It does away with the first attempt to perform early canonicalizing only. The patch also handles type canonicalizing while reading xml-abi format. * include/abg-fwd.h (is_class_type) (type_has_non_canonicalized_subtype): Declare new functions. (is_member_type): Remove the overload that takes a decl_base_sptr. It's superfluous. We just need the one that takes a type_base_sptr. * include/abg-ir.h (translation_unit::{is_constructed, set_is_constructed}): Add new methods. (class_decl::has_virtual_member_functions): Likewise. (class decl_base): Makes it virtually inherit ir_traversable_base. (class type_base): Make this virtually inherit traversable_base too. (type_base::canonicalize): Renamed enable_canonical_equality into this. (type_base::traverse): Declare new virtual method. (canonicalize): Renamed enable_canonical_equality into this. (scope_type_decl::traverse): Declare new virtual method. (namespace_decl::get_pretty_representation): Declare new virtual method. (function_type::traverse): Likewise. (class_decl::base_spec::traverse): Likewise. (ir_node_visitor::visit): Remove the overloads and replace each of them with a pair of ... (ir_node_visitor::{visit_begin, visit_end}): ... of these. * include/abg-traverse.h (traversable_base::visiting): New method. (traversable_base::visiting_): New data member. (traversable_base::traversable_base): New constructor. * src/abg-ir.cc ({scope_decl, type_decl, namespace_decl, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, typedef_decl, var_decl, function_decl, function_decl::parameter, class_decl, class_decl::member_function_template, class_decl::member_class_template, function_tdecl, class_tdecl}::traverse): Fix this to properly set the traversable_base::visiting_ flag and to reflect the new signatures of the ir_node_visitor methods. ({type_base, scope_type_decl, function_type, class_decl::base_spec}::traverse): New method. (type_base::get_canonical_type_for): Handle the case of the type already having a canonical type. Properly hash the type using the dynamic type hasher. Look through declaration-only classes to consider the definition of the class instead. Fix logic to have a single pointer of return, to ease debugging. (canonicalize): Renamed enable_canonical_equality into this. (namespace_decl::get_pretty_representation): Define new method. (ir_node_visitor::visit): Replace each of these overloads with a pair of visit_begin/visit_end ones. (translation_unit::priv::is_constructed_): New data member. (translation_unit::priv::priv): Initialize it. (translation_unit::{is_constructed, set_is_constructed}): Define new methods. (is_member_type(const decl_base_sptr)): Remove. (is_class_type(decl_base *d)): Define new function. (class_decl::has_virtual_member_functions): Define new method. (equals(const class_decl&, const class_decl&, change_kind*)): If the containing translation unit is not constructed yet, do not take virtual member functions in account when comparing the classes. This is because when reading from DWARF, there can be DIEs that change the number of virtual member functions after the DIE of the class. So one needs to start taking virtual members into account only after the translation unit has been constructed. (class non_canonicalized_subtype_detector): Define new type. (type_has_non_canonicalized_subtype): Define new function. * src/abg-corpus.cc (symtab_build_visitor_type::visit): Renamed this into symtab_build_visitor_type::visit_end. * src/abg-dwarf-reader.cc (die_type_map_type): New typedef. (die_class_map_type): This is now a typedef on a map of Dwarf_Off/class_decl_sptr. (read_context::{die_type_map_, alternate_die_type_map_, types_to_canonicalize_, alt_types_to_canonicalize_}): New data members. (read_context::{associate_die_to_decl, associate_die_to_decl_primary}): Make these methods public. (read_context::{associate_die_to_type, lookup_type_from_die_offset, is_wip_class_die_offset, types_to_canonicalize, schedule_type_for_canonicalization}): Define new methods. (build_type_decl, build_enum_type) (build_class_type_and_add_to_ir, build_qualified_type) (build_pointer_type_def, build_reference_type, build_array_type) (build_typedef_type, build_function_decl): Do not canonicalize types here. (maybe_canonicalize_type): Define new function. (build_ir_node_from_die): Take a new flag that says if the ir node is a member type/function or not. Early-canonicalize base types. Canonicalize composite types that have only canonicalized sub-types. Schedule the other types for late canonicalizing. For class types, early canonicalize those that are non-member types, that are fully constructed and that have only canonicalized sub-types. Adjust to the new signature of build_ir_node_from_die. (get_scope_for_die, build_namespace_decl_and_add_to_ir) (build_qualified_type, build_pointer_type_def) (build_reference_type, build_array_type, build_typedef_type) (build_var_decl, build_function_decl): Adjust for the new signature of build_ir_node_from_die. (build_translation_unit_and_add_to_ir): Likewise. Perform the late canonicalizing of the types that have been scheduled for that. (build_class_type_and_add_to_ir): Return a class_decl_sptr, not a decl_base_sptr. Adjust for the new signature of build_ir_node_from_die. Early canonicalize member types that are created and added to a given class, or schedule them for late canonicalizing. * src/abg-reader.cc (class read_context::{m_wip_classes_map, m_types_to_canonicalize}): New data members. (read_context::{clear_types_to_canonicalize, clear_wip_classes_map, mark_class_as_wip, unmark_class_as_wip, is_wip_class, maybe_canonicalize_type, schedule_type_for_late_canonicalizing, perform_late_type_canonicalizing}): Add new method definitions. (read_context::clear_per_translation_unit_data): Call read_context::clear_types_to_canonicalize(). (read_translation_unit_from_input): Call read_context::perform_late_type_canonicalizing() at the end of the function. (build_function_decl): Fix the function type canonicalizing (per translation) that was already in place. Do the canonicalizing of these only when the type is fully built. Oops. This was really brokend. Also, when the function type is constructed, consider it for type canonicalizing. (build_type_decl): Early canonicalize basic types. (build_qualified_type_decl, build_pointer_type_def) (build_pointer_type_def, build_reference_type_def) (build_array_type_def, build_enum_type_decl, build_typedef_decl): Handle the canonicalizing for these composite types: either early or late. (build_class_decl): Likewise. Also, mark this class a 'being built' until it's fully built. This helps the canonicalizing code to know that it should leave a class alone until it's fully built. * tests/test-ir-walker.cc (struct name_printing_visitor): Adjust to the visitor methods naming change. * configure.ac: Generate the tests/runtestcanonicalizetypes.sh testing script from tests/runtestcanonicalizetypes.sh.in. * tests/runtestcanonicalizetypes.sh.in: Add the template for the new runtestcanonicalizetypes.sh script that test for type canonicalizing. * tests/Makefile.am: Add the new runtestcanonicalizetypes.sh regression testing script to the build system. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-13 19:20:57 +00:00
type_base_sptr
canonicalize(type_base_sptr);
Make strip_typedef() act on canonical types only strip_typedef(), when constructing new pointers, references and other composite types was building new types that weakly referred to their sub-types; for instance, a pointer type has a weak reference on its pointed-type. That means the referred-to type must be 'own' by something else. That means that strip_typedef() needs to create types which lifetime is "long enough". This patch ensures that strip_typedef() returns a canonical type; and we are sure that a canonical type is live during the entire life time of the libabigail library itself. So that means strip_typedef can only be used after types have been canonicalized. To that end, this patch changes is_class_type() to make it not strip typedefs. That way, is_class_type() can be used even when canonicalized types are not yet available. The patch then introduces a new is_compatible_with_class_type() function that strips typedef. The code of type_size_changed() that wanted to strip typedefs is then adjusted to use this new is_compatible_with_class_type() instead. * include/abg-fwd.h (is_compatible_with_class_type): Declare new function. (canonicalize): Move the declaration here, from ... * include/abg-ir.h (canonicalize): ... here. * src/abg-ir.cc (strip_typedef): Assert that the input type is canonicalized. Make sure that weak references are on canonicalized types. Make sure that the returned type is a canonical one. (canonicalize): Make this return the canonical type that it has computed. * src/abg-comp-filter.cc (type_size_changed): Use the new is_compatible_with_class_type() function, instead of is_class_type(). Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-02-19 10:30:43 +00:00
Bug 24430 - Fold away const for array types In C and C++ the qualifiers of a qualified array type apply to the element type of said array. In this particular problem report, GCC and Clang emit DWARF that represent the qualifiers either on the array type, or on the element type. Quoting the test of the bug: Given the following example: struct test { const char asdf[4]; }; void func(struct test arg) {} abidiff says: 1 function with some indirect sub-type change: [C]'function void func(test)' at test.c:5:1 has some indirect sub-type changes: parameter 1 of type 'struct test' has sub-type changes: type size hasn't changed 1 data member change: type of 'const char test::asdf[4]' changed: entity changed from 'const char[4]' to 'const char[4] const' This is because GCC represents the array as const array of const signed char, whereas clang represents it as an array of const signed char. In this patch, libabigail's DWARF reader detects qualified array types and appropriately qualifies the array element type, instead of qualifying the array type. The patch accordingly adjusts the various regression tests and adds a new test which comes from the problem report. * include/abg-fwd.h (is_array_of_qualified_element): Declare 2 overloads of this function. (re_canonicalize): Declare a new function. * include/abg-ir.h (class {decl_base, type_base}): Declare re_canonicalize as a friend of these classes. * src/abg-dwarf-reader.cc (maybe_strip_qualification): Detect qualified array types and appropriately qualifies the array element type, instead of qualifying the array type itself. Re-canonicalize the resulting type if necessary. * src/abg-ir.cc (is_array_of_qualified_element): Define 2 overloads of this function. (re_canonicalize): Define new function. * tests/data/Makefile.am: The two new test binary input files PR24430-fold-qualified-array-clang and PR24430-fold-qualified-array-gcc to source distribution, as well as the expected reference output. * tests/data/test-annotate/test15-pr18892.so.abi: Adjust. * tests/data/test-annotate/test17-pr19027.so.abi: Likewise. * tests/data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-annotate/test21-pr19092.so.abi: Likewise. * tests/data/test-diff-filter/PR24430-fold-qualified-array-clang: New binary test input coming from the bug report. * tests/data/test-diff-filter/PR24430-fold-qualified-array-gcc: Likewise. * tests/data/test-diff-filter/PR24430-fold-qualified-array-report-0.txt: Expected reference abi difference. * tests/data/test-diff-filter/test33-report-0.txt: Adjust. * tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt: Likewise. * tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise. * tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. * tests/test-diff-filter.cc: Add the new binary test input to this test harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-04-10 10:51:13 +00:00
type_base_sptr
re_canonicalize(type_base_sptr);
Make type_has_non_canonicalized_subtype() tighter type_has_non_canonicalized_subtype() gives up too quickly. For instance, suppose it's looking a type 'foo'. If foo has no canonicalized type yet and has a data member which type is foo* (for instance), then type_has_non_canonicalized_subtype() just sees that type 'foo*' has no canonicalized type, and so it returns, saying that he found a non-canonicalized subtype for foo. In that case though, what type_has_non_canonicalized_subtype() should do is detect that foo* is a pointer to foo itself, so it shouldn't count as a non-canonicalized sub-type. It should keep going and look for other meaningful non-canonicalized sub-types. And this what this patch does. It changes the sub-type walker that type_has_non_canonicalized_subtype() uses, so that - it doesn't flag sub-types that refer to the type we are looking at as non-canonicalized sub-types. This is for sub-types that are combinations of pointers, references and typedefs. - it doesn't consider sub-types of member functions of the type we are looking at, unless that member function is virtual. The result is that more types are canonicalized early during DWARF reading, and so there are less types to store on the side for late canonicalization. This can have a big impact on, e.g, C++ libraries with tens of thousands of types. * include/abg-fwd.h (is_typedef, is_pointer_type) (is_reference_type): Declare new overloads. (peel_typedef_type): Renamed get_typedef_underlying_type into this. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Declare new functions. * src/abg-ir.cc (peel_typedef_type): Renamed get_typedef_underlying_type into this. (is_typedef, is_pointer_type, is_reference_type): Define new overloads. (peel_pointer_type, peel_reference_type) (peel_typedef_pointer_or_reference_type): Define new functions. (non_canonicalized_subtype_detector::has_non_canonical_type_): Make the type of this data member be a type_base*, not a bool. This is so that we can return the first non-canonicalized subtype of the type we are looking at. (non_canonicalized_subtype_detector::non_canonicalized_subtype_detector): Adjust the data member initialization. (non_canonicalized_subtype_detector::visit_begin): Add an overload for function_decl*, to avoid looking into non-virtual member functions. In the overload for type_base*, peel typedefs, pointers and reference of each sub-type that has no canonical type, to see if refers to the type we are actually walking. If yes, then keep going. (type_has_non_canonicalized_subtype): Return the non-canonicalized sub-type found. * src/abg-comparison.cc (type_suppression::suppresses_diff): Adjust for the get_typedef_underlying_type -> peel_typedef_type renaming. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-19 14:15:28 +00:00
type_base*
type_has_non_canonicalized_subtype(type_base_sptr t);
Declaration-only classes shouldn't have canonical types I am seeing issues related to the fact that a declaration-only class A would compare different to the full version of class A. This is due to the fact that that the declaration-only A and the full A have different hashes, even though they structurally compare equal. So they have different canonical types, with the current code. This patch arranges for declaration-only classes to have no canonical type, forcing it to compare structurally to other types. Then the patch adjusts strip_typedef() that used to expect that all types it sees have canonical types. Then the patch changes the type hashing code to avoid making it cache their hash, because otherwise, in some cases when we hash a type (too) early, a temporary hash of it gets stored ad infinitum, even after the type has been later updated. Last but not least, the patch returns a zero hash for declaration-only classes. * include/abg-fwd.h (keep_type_alive): Declare new function. * src/abg-ir.cc (strip_typedef): Simplify logic. Support types that are not canonicalized. (type_base::get_canonical_type_for): For declaration-only classes, return an empty canonical class, forcing the class to be compared structurally. (keep_type_alive): Define new function. * src/abg-hash.cc ({decl_base, type_decl, scope_type_decl, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, typedef_decl, class_decl::member_class_template, class_decl, type_tparameter, template_tparameter, }::hash::operator()): Do not cache the computed hash. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-13 16:14:03 +00:00
bool
type_has_sub_type_changes(type_base_sptr t_v1,
type_base_sptr t_v2);
Declaration-only classes shouldn't have canonical types I am seeing issues related to the fact that a declaration-only class A would compare different to the full version of class A. This is due to the fact that that the declaration-only A and the full A have different hashes, even though they structurally compare equal. So they have different canonical types, with the current code. This patch arranges for declaration-only classes to have no canonical type, forcing it to compare structurally to other types. Then the patch adjusts strip_typedef() that used to expect that all types it sees have canonical types. Then the patch changes the type hashing code to avoid making it cache their hash, because otherwise, in some cases when we hash a type (too) early, a temporary hash of it gets stored ad infinitum, even after the type has been later updated. Last but not least, the patch returns a zero hash for declaration-only classes. * include/abg-fwd.h (keep_type_alive): Declare new function. * src/abg-ir.cc (strip_typedef): Simplify logic. Support types that are not canonicalized. (type_base::get_canonical_type_for): For declaration-only classes, return an empty canonical class, forcing the class to be compared structurally. (keep_type_alive): Define new function. * src/abg-hash.cc ({decl_base, type_decl, scope_type_decl, qualified_type_def, pointer_type_def, reference_type_def, array_type_def, enum_type_decl, typedef_decl, class_decl::member_class_template, class_decl, type_tparameter, template_tparameter, }::hash::operator()): Do not cache the computed hash. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-13 16:14:03 +00:00
void
keep_type_alive(type_base_sptr t);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
size_t
hash_type(const type_base *t);
Add support for abicompat weak mode This patch implements the weak mode of abicompat. In this mode, just the application and the new version of the library are provided. The types of functions and variables of the library that are consumed by the application are compared to the types of the functions and variables expected by the application. The goal is to check if the types of the declarations consumed by the application and provided by the library are compatible with what the application expects. The abicompat first gets the set of symbols undefined in the application and exported by the library. It then builds the set of declarations exported by the library that have those symbols. We call these the set of declarations of the library that are consumed by the application. Note that the debug information for the application does not contain the declarations of the functions/variables whose symbols are undefined. So we can not just read them to compare them to declarations exported by the library. But the *types* of the variables and the *sub-types* of the functions whose symbols are undefined in the application are present in the debug information of the application. So in the weak mode, abicompat compare the *types* of the declarations consumed by the application as expected by the application (described by the debug information of the application) with the types of the declarations exported by the library. To do this a number of changes were necessary. The patch builds a representation of all the types found in the application's debug info. Before that, only the types that are reachable from exported declarations were represented. The abidw tool got a new --load-all-types to test this new ability of loading all types. The patch also adds support for looking a type, not by name, but by its internal representation. In the comparison engine, function_type_diff is introduced to represent changes between two function types. For this, a new class type_or_decl_base has been introduced in the IR. It's now the base class for both decl_base and type_base. And abigail::comparison::diff now takes two pointers of type_or_decl, not decl_base anymore. So function_type_diff can take two function_type now; not that a function_type has no declaration so it doesn't inherit decl_base. A bunch of changes got made just to adjust to this modification. A number of fixes were made too, to make this work, like adding missing comparison operators, removing asserts that too strong, etc.. The patch also adjust the test suite as well as the documentation. * include/abg-fwd.h (class type_or_decl_base): Forward declare this. (is_decl, is_type, is_function_type, get_name, get_type_name) (get_function_type_name, get_pretty_representation) (lookup_function_type_in_corpus, lookup_type_in_translation_unit) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (hash_type_or_decl): New function declarations. * src/abg-corpus.cc (lookup_type_in_corpus) (lookup_function_type_in_corpus): Define new functions. * include/abg-ir.h (translation_unit::lookup_function_type_in_translation_unit): Declare new friend function. (class type_or_decl_base): Declare this. (operator==(const type_or_decl_base&, const type_or_decl_base&)): Declare new operator. (operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (class {decl_base, type_base}): Make these class inherit type_or_decl_base. (decl_base::get_member_scopes): New const overload. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr&)): New operator. (function_type::get_parameters): Remove the non-const overload. (function_type::get_pretty_representation): Declare new member function. (method_type::get_pretty_representation): Likewise. * src/abg-ir.cc (bool operator==(const type_or_decl_base&, const type_or_decl_base&)): Define new equality operator. (bool operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&)): Likewise. (strip_typedef): Do not expect canonicalized types anymore. Now the system accepts (and expects) canonicalized types in certain cases. For instance, non-complete types and aggregated types that contain non-complete sub-types. (get_name, get_function_type_name, get_type_name) (get_pretty_representation, is_decl, is_type, is_function_type) (lookup_function_type_in_translation_unit) (synthesize_function_type_from_translation_unit) (lookup_type_in_scope, lookup_type_in_translation_unit): Define new functions or new overloads. (bool operator==(const function_decl::parameter_sptr&, const function_decl::parameter_sptr& r)): Define new operator. (function_type::get_parameters): Remove non-const overload. (function_type::get_pretty_representation): Define new function. (function_type::traverse): Adjust. (method_type::get_pretty_representation): Likewise. (function_decl::get_pretty_representation): Avoid emitting the type of cdtors. (hash_type_or_decl): Define new function. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take a new 'read_all_types' flag. * src/abg-dwarf-reader.cc (read_context::load_all_types_): New flag. (read_context::read_context): Initialize it. (read_context::canonical_types_scheduled): If some types still have non-canonicalized sub-types, then do not canonicalize them. (read_context::load_all_types): New member functions. (build_function_decl): Do not represent void return type like empty type anymore, rather, represent it like a void type node. (build_ir_node_from_die): When asked, load all types including those that are not reachable from an exported declaration. (create_read_context, read_corpus_from_elf): Take a new 'load_all_types' flag and honour it. * src/abg-reader.cc (read_context::type_is_from_translation_unit): Support looking up function types in the current translation unit, now that we now how to lookup function types. * include/abg-comparison.h (diff_context::{has_diff_for, add_diff, set_canonical_diff_for, set_or_get_canonical_diff_for, get_canonical_diff_for}): Make these take instances of type_or_decl_base_sptr, instead of decl_base_sptr. (diff::diff): Likewise. (diff::{first_subject, second_subject}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (type_diff_base::type_diff_base): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::distinct_diff): Likewise. (distinct_diff::{first, second}): Make these return type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::entities_are_of_distinct_kinds): Make these take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class function_type_diff): Create this new type. It's a factorization of the function_decl_diff type. * src/abg-comparison.cc (): * src/abg-comp-filter.cc ({harmless, harmful}_filter::visit): Adjust as diff::{first,second}_subject() now returns a type_or_decl_base_sptr, no more a decl_base_sptr. (decls_type, decls_diff_map_type): Remove these typedefs and replace it with ... (types_or_decls_type, types_or_decls_diff_map_type): ... these. (struct {decls_hash, decls_equals): Remove these type sand replace them with ... (struct {types_or_decls_hash, types_or_decls_equals}): ... these. ({type_suppression, variable_suppression}::suppresses_diff): Adjust. (diff_context::priv::decls_diff_map): Replace this with ... (diff_context::priv::types_or_decls_diff_map): ... this. (diff_context::{has_diff_for, add_diff, get_canonical_diff_for, set_canonical_diff_for, set_or_get_canonical_diff_for}): Take type_or_decl_base_sptr instead of decl_base_sptr. (diff::priv::{first, second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (diff::priv::priv): Adjust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff_less_than_functor::operator()(const diff_sptr, const diff_sptr) const): Adjust. (diff::diff): djust for the subjects of the diff being of type type_or_decl_sptr now, no more decl_base_sptr. (diff::{first,second}_subject): Make the type of these be type_or_decl_base_sptr, no more decl_base_sptr. (report_size_and_alignment_changes): Likewise. (type_diff_base::type_diff_base): Make the type of this be type_or_decl_base_sptr instead of type_base_sptr. (distinct_diff::distinct_diff): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (distinct_diff::{first, second, entities_are_of_distinct_kinds}): Likewise. (distinct_diff::has_changes): Simplify logic. (distinct_diff::report): Adjust. (compute_diff_for_types): Add an additional case to support the new function_type. (report_size_and_alignment_changes): Make this take instances of type_or_decl_base_sptr instead of decl_base_sptr. (class_diff::priv::member_type_has_changed): Return an instance of type_or_decl_base_sptr rather than a decl_base_sptr. (class_diff::report): Adjust. (diff_comp::operator()(const diff&, diff&) const): Adjust. (enum function_decl_diff::priv::Flags): Remove. (function_decl_diff::priv::{first_fn_flags_, second_fn_flags_, fn_flags_changes_}): Remove. (function_decl_diff::priv::{fn_is_declared_inline_to_flag, fn_binding_to_flag}): Remove. (function_decl_diff::{deleted_parameter_at, inserted_parameter_at}): Remove. (function_decl_diff::ensure_lookup_tables_populated): Empty this. (function_decl_diff::chain_into_hierarchy): Adjust. (function_decl_diff::function_decl_diff): This now only takes the subjects. It's body is now empty. (function_decl_diff::{return_type_diff, subtype_changed_parms, removed_parms, added_parms, type_diff}): Remove these member functions. (function_decl_diff::type_diff): Define new member function. (function_decl_diff::report): Simplify logic by using the reporting of the child type diff node. (compute_diff): Likewise, in the overload for function_decl_sptr simplify logic by using the child type diff object. (function_type_diff::priv): Define new type. (function_type_diff::{function_type_diff, ensure_lookup_tables_populated, deleted_parameter_at, inserted_parameter_at, finish_diff_type, first_function_type, second_function_type, return_type_diff, subtype_changed_parms, removed_parms, added_parms, get_pretty_representation, has_changes, has_local_changes, report, chain_into_hierarchy}): Define new functions. (compute_diff): Define new overload for function_type_sptr. * tools/abicompat.cc (options::weak_mode): New data member. (options::options): Initialize it. (enum abicompat_status): New enum (abicompat_status operator|(abicompat_status, abicompat_status)) (abicompat_status& operator|=(abicompat_status &, abicompat_status)) (abicompat_status operator&(abicompat_status, abicompat_status)): New operators to manipulate the abicompat_status enum. (display_usage): Add help string for the new --weak-mode option. (parse_command_line): Add the new --weak-mode command line argument. If the tool is called with just the application and one library then assume that we are in the weak mode. (perform_compat_check_in_normal_mode): Define new function, factorized from what was in the main function. (perform_compat_check_in_weak_mode): Define new function. (struct {fn,var}_change): Define new types. (main): Use perform_compat_check_in_weak_mode() and perform_compat_check_in_normal_mode(). * tools/abidiff.cc (main): Adjust. * tools/abidw.cc: (options::load_all_types): Add new data member. (options::options): Initialize it. (display_usage): New help string for --load-all-types. (parse_command_line): Support the new --load-all-types option. (main): Adjust and honour the --load-all-types option. * tools/abilint.cc (main): Adjust. * doc/manuals/abicompat.rst: Update documentation for the new weak mode. Also provide stuff that was missing from the examples provided. * doc/manuals/abidw.rst: Update documentation for the new --load-all-types option. * tests/print-diff-tree.cc (main): Adjust. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/data/test-abicompat/test0-fn-changed-app: Recompile this. * tests/data/test-abicompat/libtest5-fn-changed-libapp-v{0,1}.so: New new test input binaries * tests/data/test-abicompat/test5-fn-changed-app: Likewise. * tests/data/test-abicompat/test6-var-changed-app: Likewise. * tests/data/test-abicompat/libtest6-var-changed-libapp-v{0,1}.so: Likewise. * tests/data/test-abicompat/test5-fn-changed-report-0.txt: Reference output for one test above. * tests/data/test-abicompat/test6-var-changed-report-0.txt: Likewise. * tests/data/test-abicompat/test5-fn-changed-app.cc: Source file for a binary above. * tests/data/test-abicompat/test5-fn-changed-libapp-v{0,1}.{h,cc}: Likewise. * tests/data/test-abicompat/test6-var-changed-libapp-v{0,1}.{cc,h}: Likewise. * tests/data/test-abicompat/test6-var-changed-app.cc: Likewise. * tests/data/Makefile.am: Add the test related files above to the source distribution. * tests/test-abicompat.cc (in_out_spec): Add the new test input above to the list of inputs to feed to this test harness. (main): Support taking just the app and one library. * tests/data/test-read-dwarf/test{0, 1, 2.so, 3.so, 5.o, 8-qualified-this-pointer.so,}.abi: Adjust for void type being really emitted now, as opposed to just being an empty type. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-04-01 10:13:38 +00:00
size_t
hash_type_or_decl(const type_or_decl_base *);
size_t
hash_type_or_decl(const type_or_decl_base_sptr &);
Initial implementation of a --leaf-changes-only option to abidiff 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>
2017-08-02 16:00:23 +00:00
bool
function_decl_is_less_than(const function_decl&f, const function_decl &s);
Improve detection of local *type* changes For variables and data member, we are quite gross in the way we detect a local type change. Basically, if a textual representation of the variable (and thus of its type) changes, then we consider that the variable has a local (possibly type) change. This leads us to (wrongly) report changes like this: 'struct S1 at test-44-anonymous-data-member-v0.c:1:1' changed: type size hasn't changed there are data member changes: anonymous data member at offset 32 (in bits) changed from: union {int b; float c;} to: union {int b; float c; char e;} Here, you see that the textual representation of the anonymous data member (of union type) changed from: union {int b; float c;} to: union {int b; float c; char e;} You see that although the textual representation of the type changed, the *structure* of the type hasn't really changed. I am using the "vague" term structure, on purpose. Here, in the case of a union, the structure hasn't change because the size of the union hasn't changed. This patch thus introduces the concept of "similarity of type structures". That is, even if two types are different, if "their structure is similar", then the type change is not a local type change. More precisely, here is what we mean by type similarity: Two indirect types (pointers, references) have similar structure if their underlying types are of the same kind and have the same name. In this indirect types case, the size of the underlying type does not matter. Two direct types (i.e, non indirect) have a similar structure if they have the same kind, name and size. Two class types have similar structure if they have the same name, size, and if their data members have similar types. This patch then uses that similarity concept to detect local type changes. * include/abg-fwd.h (is_type_decl): Declare new overload for type_base*. (types_have_similar_structure): Declare new function. * src/abg-comparison.cc (class_or_union_diff::priv::count_filtered_changed_dm): Even when looking at local changes only, do not forget to count nodes that were filtered out. * src/abg-ir.cc (types_have_similar_structure): Define new function. (is_type_decl): Define new overload for type_base*. (is_enum_type): (equals): In the overload for var_decl, use the new types_have_similar_structure function to detect local (type) changes. * src/abg-reporter-priv.cc (represent): In the overload for var_decl, use the diff::has_local_changes function to detect local changes, now that we can better detect local changes. * tests/data/test-diff-filter/test44-anonymous-data-member-report-1.txt: Adjust. * tests/data/test-diff-suppr/test36-leaf-report-0.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-18 08:18:45 +00:00
bool
types_have_similar_structure(const type_base_sptr& first,
abg-ir.cc: Improve types_have_similar_structure. This function is used to determine whether or not type differences are "local" and is primarily used in --leaf-changes-only mode. The logic has some issues which are addressed by this patch: - Any number of points-to (*) and refers-to (& and &&) components are peeled off the types being compared, rather than checking these match in number and kind. - This peeling is done with peel_typedef_pointer_or_reference_type which also peels any number of CV qualifiers (OK) and array-of ([N]) type components (not OK). - The function sets a state variable (was_indirect_type) to modify the behaviour of downstream comparisons, but this cannot be passed through recursive calls. The effect of the indirect_type flag is to switch to comparisons by name: identically named structs don't get introspected. Arguably, a more useful behaviour for --leaf-changes-only mode would be to treat any change to a named type as non-local, except in the context of the definition of that type itself. This would be a more significant change in behaviour. * include/abg-fwd.h (types_have_similar_structure): In both overloads, add an indirect_type argument, defaulting to false. * src/abg-ir.cc (reference_type_def constructor): Tabify. (types_have_similar_structure): In both overloads, add an indirect_type argument and update documentation text. In the type_base_sptr overload, pass indirect_type in the tail call. In the type_base* overload, replace was_indirect_type with indirect_type; peel CV qualifiers and typedefs without testing as the peel function does this; replace the indiscriminate peeling of qualifier/pointer/reference/array type components with code that checks the same pointer/reference/array type component is used on each side and makes recursive calls with indirect_type set to true; pass the indirect_type argument recursively when comparing other subtypes; move the typeid check earlier, document its purpose and remove unneccessary checks after later dynamic casts; remove an always-true conditional; add a TODO for comparing array types more accurately. * tests/data/Makefile.am: Add new test case files. * tests/data/test-abidiff-exit/test-leaf-peeling-v0.cc: New test case. * tests/data/test-abidiff-exit/test-leaf-peeling-v1.cc: Ditto. * tests/data/test-abidiff-exit/test-leaf-peeling-report.txt: Ditto. * tests/test-abidiff-exit.cc: Run new test case. Signed-off-by: Giuliano Procida <gprocida@google.com>
2020-03-25 14:18:59 +00:00
const type_base_sptr& second,
bool indirect_type = false);
Improve detection of local *type* changes For variables and data member, we are quite gross in the way we detect a local type change. Basically, if a textual representation of the variable (and thus of its type) changes, then we consider that the variable has a local (possibly type) change. This leads us to (wrongly) report changes like this: 'struct S1 at test-44-anonymous-data-member-v0.c:1:1' changed: type size hasn't changed there are data member changes: anonymous data member at offset 32 (in bits) changed from: union {int b; float c;} to: union {int b; float c; char e;} Here, you see that the textual representation of the anonymous data member (of union type) changed from: union {int b; float c;} to: union {int b; float c; char e;} You see that although the textual representation of the type changed, the *structure* of the type hasn't really changed. I am using the "vague" term structure, on purpose. Here, in the case of a union, the structure hasn't change because the size of the union hasn't changed. This patch thus introduces the concept of "similarity of type structures". That is, even if two types are different, if "their structure is similar", then the type change is not a local type change. More precisely, here is what we mean by type similarity: Two indirect types (pointers, references) have similar structure if their underlying types are of the same kind and have the same name. In this indirect types case, the size of the underlying type does not matter. Two direct types (i.e, non indirect) have a similar structure if they have the same kind, name and size. Two class types have similar structure if they have the same name, size, and if their data members have similar types. This patch then uses that similarity concept to detect local type changes. * include/abg-fwd.h (is_type_decl): Declare new overload for type_base*. (types_have_similar_structure): Declare new function. * src/abg-comparison.cc (class_or_union_diff::priv::count_filtered_changed_dm): Even when looking at local changes only, do not forget to count nodes that were filtered out. * src/abg-ir.cc (types_have_similar_structure): Define new function. (is_type_decl): Define new overload for type_base*. (is_enum_type): (equals): In the overload for var_decl, use the new types_have_similar_structure function to detect local (type) changes. * src/abg-reporter-priv.cc (represent): In the overload for var_decl, use the diff::has_local_changes function to detect local changes, now that we can better detect local changes. * tests/data/test-diff-filter/test44-anonymous-data-member-report-1.txt: Adjust. * tests/data/test-diff-suppr/test36-leaf-report-0.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-18 08:18:45 +00:00
bool
types_have_similar_structure(const type_base* first,
abg-ir.cc: Improve types_have_similar_structure. This function is used to determine whether or not type differences are "local" and is primarily used in --leaf-changes-only mode. The logic has some issues which are addressed by this patch: - Any number of points-to (*) and refers-to (& and &&) components are peeled off the types being compared, rather than checking these match in number and kind. - This peeling is done with peel_typedef_pointer_or_reference_type which also peels any number of CV qualifiers (OK) and array-of ([N]) type components (not OK). - The function sets a state variable (was_indirect_type) to modify the behaviour of downstream comparisons, but this cannot be passed through recursive calls. The effect of the indirect_type flag is to switch to comparisons by name: identically named structs don't get introspected. Arguably, a more useful behaviour for --leaf-changes-only mode would be to treat any change to a named type as non-local, except in the context of the definition of that type itself. This would be a more significant change in behaviour. * include/abg-fwd.h (types_have_similar_structure): In both overloads, add an indirect_type argument, defaulting to false. * src/abg-ir.cc (reference_type_def constructor): Tabify. (types_have_similar_structure): In both overloads, add an indirect_type argument and update documentation text. In the type_base_sptr overload, pass indirect_type in the tail call. In the type_base* overload, replace was_indirect_type with indirect_type; peel CV qualifiers and typedefs without testing as the peel function does this; replace the indiscriminate peeling of qualifier/pointer/reference/array type components with code that checks the same pointer/reference/array type component is used on each side and makes recursive calls with indirect_type set to true; pass the indirect_type argument recursively when comparing other subtypes; move the typeid check earlier, document its purpose and remove unneccessary checks after later dynamic casts; remove an always-true conditional; add a TODO for comparing array types more accurately. * tests/data/Makefile.am: Add new test case files. * tests/data/test-abidiff-exit/test-leaf-peeling-v0.cc: New test case. * tests/data/test-abidiff-exit/test-leaf-peeling-v1.cc: Ditto. * tests/data/test-abidiff-exit/test-leaf-peeling-report.txt: Ditto. * tests/test-abidiff-exit.cc: Run new test case. Signed-off-by: Giuliano Procida <gprocida@google.com>
2020-03-25 14:18:59 +00:00
const type_base* second,
bool indirect_type = false);
Improve detection of local *type* changes For variables and data member, we are quite gross in the way we detect a local type change. Basically, if a textual representation of the variable (and thus of its type) changes, then we consider that the variable has a local (possibly type) change. This leads us to (wrongly) report changes like this: 'struct S1 at test-44-anonymous-data-member-v0.c:1:1' changed: type size hasn't changed there are data member changes: anonymous data member at offset 32 (in bits) changed from: union {int b; float c;} to: union {int b; float c; char e;} Here, you see that the textual representation of the anonymous data member (of union type) changed from: union {int b; float c;} to: union {int b; float c; char e;} You see that although the textual representation of the type changed, the *structure* of the type hasn't really changed. I am using the "vague" term structure, on purpose. Here, in the case of a union, the structure hasn't change because the size of the union hasn't changed. This patch thus introduces the concept of "similarity of type structures". That is, even if two types are different, if "their structure is similar", then the type change is not a local type change. More precisely, here is what we mean by type similarity: Two indirect types (pointers, references) have similar structure if their underlying types are of the same kind and have the same name. In this indirect types case, the size of the underlying type does not matter. Two direct types (i.e, non indirect) have a similar structure if they have the same kind, name and size. Two class types have similar structure if they have the same name, size, and if their data members have similar types. This patch then uses that similarity concept to detect local type changes. * include/abg-fwd.h (is_type_decl): Declare new overload for type_base*. (types_have_similar_structure): Declare new function. * src/abg-comparison.cc (class_or_union_diff::priv::count_filtered_changed_dm): Even when looking at local changes only, do not forget to count nodes that were filtered out. * src/abg-ir.cc (types_have_similar_structure): Define new function. (is_type_decl): Define new overload for type_base*. (is_enum_type): (equals): In the overload for var_decl, use the new types_have_similar_structure function to detect local (type) changes. * src/abg-reporter-priv.cc (represent): In the overload for var_decl, use the diff::has_local_changes function to detect local changes, now that we can better detect local changes. * tests/data/test-diff-filter/test44-anonymous-data-member-report-1.txt: Adjust. * tests/data/test-diff-suppr/test36-leaf-report-0.txt: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2018-05-18 08:18:45 +00:00
} // end namespace ir
using namespace abigail::ir;
Split suppression engine off of abg-comparison.{cc,h} Until now, the suppression engine was part of the comparison engine. The code of both was in the abg-comparison.{cc,h} files. For the sake of greater modularity, this patch separates the suppression engine from the comparison engine. The suppression engine now lives in include/abg-suppression.h and src/abg-suppression.cc. The patch also updates logical consumers of the suppression engine to adapt them to the change. * include/Makefile.am: Add abg-suppression.h to source distribution. * include/abg-comparison.h: Remove abg-ini.h include directive. (suppression_sptr, suppressions_type): Move these typedefs to abg-fwd.h. (class suppression_base, type_suppression) (type_suppression::insertion_range) (type_suppression::insertion_range::boundary) (type_suppression::insertion_range::integer_boundary) (type_suppression::insertion_range::fn_call_expr_boundary) (function_suppression, function_suppression::parameter_spec) (variable_suppression): Move these type definitions to the new abg-suppression.h. (read_suppressions, is_type_suppression, is_integer_boundary) (is_fn_call_expr_boundary, is_function_suppression) (is_variable_suppression, operator&) (operator|): Move these function declarations to the new abg-suppression.h. (type_suppression, type_suppression_sptr, type_suppression_type) (function_suppression, function_suppression_sptr) (function_suppressions_type, variable_suppression) (variable_suppression_sptr, variable_suppressions_type): Move these forward declaration and typedefs to the new abg-suppression.h. (diff_context::suppressions): Adjust return type to suppr::suppressions_type&. (diff_context::add_suppression): Adjust parameter type to suppr::suppressions_sptr. (diff_context::add_suppressions): Adjust parameter type suppr::suppressions_type&. (is_type_diff, is_decl_diff, is_var_diff, is_function_decl_diff) (is_pointer_diff, is_reference_diff, is_fn_parm_diff) (is_base_diff, is_child_node_of_function_parm_diff) (is_child_node_of_base_diff): Declare these new functions. They were previously static, local to abg-comparison.cc only. Now they need to be exported because they are used by the suppression engine's code that now lives in its one files. * include/abg-fwd.h (suppr::{suppression_base, suppression_sptr, suppressions_type}): Forward declare these here. * include/abg-suppression.h (class suppression_base) (type_suppression, type_suppression::insertion_range) (type_suppression::insertion_range::boundary) (type_suppression::insertion_range::integer_boundary) (type_suppression::insertion_range::fn_call_expr_boundary) (function_suppression, function_suppression::parameter_spec) (variable_suppression): Move these type definitions here, in the namespace suppr. (read_suppressions, is_type_suppression, is_integer_boundary) (is_fn_call_expr_boundary, is_function_suppression) (is_variable_suppression, operator&) (operator|): Move these function decalration here, in the namespace suppr. (type_suppression_sptr, type_suppressions_type) (function_suppression_sptr, function_suppressions_type) (variable_suppression_sptr, variable_suppressions_type): Move these typedefs here, in the namespace suppr. * src/Makefile.am: add src/abg-suppression.cc to source distribution. * src/abg-comparison.cc (is_type_diff, is_decl_diff, is_var_diff) (is_function_decl_diff, is_pointer_diff, is_reference_diff) (is_reference_or_pointer_diff, is_fn_parm_diff, is_base_diff) (is_child_node_of_function_parm_diff, is_child_node_of_base_diff): Export these functions. (*suppression*): Move all the suppression-related definitions to the new abg-suppression.cc. * src/abg-suppression.cc: New file. Contains all the *suppression* definitions from src/abg-comparison.cc, that are put in the suppr namespace. * tools/abicompat.cc: Adjust. * tools/abidiff.cc: Likewise. * tools/abipkgdiff.cc: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-07 09:28:21 +00:00
namespace suppr
{
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;
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>
2019-11-13 10:04:18 +00:00
} // end namespace suppr
Split suppression engine off of abg-comparison.{cc,h} Until now, the suppression engine was part of the comparison engine. The code of both was in the abg-comparison.{cc,h} files. For the sake of greater modularity, this patch separates the suppression engine from the comparison engine. The suppression engine now lives in include/abg-suppression.h and src/abg-suppression.cc. The patch also updates logical consumers of the suppression engine to adapt them to the change. * include/Makefile.am: Add abg-suppression.h to source distribution. * include/abg-comparison.h: Remove abg-ini.h include directive. (suppression_sptr, suppressions_type): Move these typedefs to abg-fwd.h. (class suppression_base, type_suppression) (type_suppression::insertion_range) (type_suppression::insertion_range::boundary) (type_suppression::insertion_range::integer_boundary) (type_suppression::insertion_range::fn_call_expr_boundary) (function_suppression, function_suppression::parameter_spec) (variable_suppression): Move these type definitions to the new abg-suppression.h. (read_suppressions, is_type_suppression, is_integer_boundary) (is_fn_call_expr_boundary, is_function_suppression) (is_variable_suppression, operator&) (operator|): Move these function declarations to the new abg-suppression.h. (type_suppression, type_suppression_sptr, type_suppression_type) (function_suppression, function_suppression_sptr) (function_suppressions_type, variable_suppression) (variable_suppression_sptr, variable_suppressions_type): Move these forward declaration and typedefs to the new abg-suppression.h. (diff_context::suppressions): Adjust return type to suppr::suppressions_type&. (diff_context::add_suppression): Adjust parameter type to suppr::suppressions_sptr. (diff_context::add_suppressions): Adjust parameter type suppr::suppressions_type&. (is_type_diff, is_decl_diff, is_var_diff, is_function_decl_diff) (is_pointer_diff, is_reference_diff, is_fn_parm_diff) (is_base_diff, is_child_node_of_function_parm_diff) (is_child_node_of_base_diff): Declare these new functions. They were previously static, local to abg-comparison.cc only. Now they need to be exported because they are used by the suppression engine's code that now lives in its one files. * include/abg-fwd.h (suppr::{suppression_base, suppression_sptr, suppressions_type}): Forward declare these here. * include/abg-suppression.h (class suppression_base) (type_suppression, type_suppression::insertion_range) (type_suppression::insertion_range::boundary) (type_suppression::insertion_range::integer_boundary) (type_suppression::insertion_range::fn_call_expr_boundary) (function_suppression, function_suppression::parameter_spec) (variable_suppression): Move these type definitions here, in the namespace suppr. (read_suppressions, is_type_suppression, is_integer_boundary) (is_fn_call_expr_boundary, is_function_suppression) (is_variable_suppression, operator&) (operator|): Move these function decalration here, in the namespace suppr. (type_suppression_sptr, type_suppressions_type) (function_suppression_sptr, function_suppressions_type) (variable_suppression_sptr, variable_suppressions_type): Move these typedefs here, in the namespace suppr. * src/Makefile.am: add src/abg-suppression.cc to source distribution. * src/abg-comparison.cc (is_type_diff, is_decl_diff, is_var_diff) (is_function_decl_diff, is_pointer_diff, is_reference_diff) (is_reference_or_pointer_diff, is_fn_parm_diff, is_base_diff) (is_child_node_of_function_parm_diff, is_child_node_of_base_diff): Export these functions. (*suppression*): Move all the suppression-related definitions to the new abg-suppression.cc. * src/abg-suppression.cc: New file. Contains all the *suppression* definitions from src/abg-comparison.cc, that are put in the suppr namespace. * tools/abicompat.cc: Adjust. * tools/abidiff.cc: Likewise. * tools/abipkgdiff.cc: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-07 09:28:21 +00:00
void
dump(const decl_base_sptr, std::ostream&);
void
dump(const decl_base_sptr);
void
dump(const type_base_sptr, std::ostream&);
void
dump(const type_base_sptr);
void
dump(const var_decl_sptr, std::ostream&);
void
dump(const var_decl_sptr);
void
dump(const translation_unit&, std::ostream&);
void
dump(const translation_unit&);
void
dump(const translation_unit_sptr, std::ostream&);
void
dump(const translation_unit_sptr);
void
dump_decl_location(const decl_base&);
void
dump_decl_location(const decl_base*);
void
dump_decl_location(const decl_base_sptr&);
#ifndef ABG_ASSERT
/// This is a wrapper around the 'assert' glibc call. It allows for
/// its argument to have side effects, so that it keeps working when
/// the code of libabigail is compiled with the NDEBUG macro defined.
Add compatibility layer for C++11 mode Introduce a compatibility layer for C++11 code by adding include/abg-cxx-compat.h. abg-cxx-compat defines a new namespace abg_compat and defines abg_compat::hash abg_compat::shared_ptr abg_compat::weak_ptr abg_compat::dynamic_pointer_cast abg_compat::static_pointer_cast abg_compat::unordered_map abg_compat::unordered_set based on definitions from std::tr1 (std=gnu++98) or std:: (std=gnu++11). I decided for introducing abg_compat:: rather than polluting abigail:: to allow an easier transition to C++11 at a later time and to not subtly break existing code. As the shared_ptr in C++11 defines shared_ptr::operator bool() explicit, some locations where a shared_ptr is assigned to boolean, needed to be adjusted to explicitly cast to bool. * include/abg-cxx-compat.h: new file introducing the abg_compat namespace to provide C++11 functionality from either std::tr1 or std:: * include/Makefile.am: Add the new abg-cxx-compat.h to source distribution. * include/abg-comparison.h: replace std::tr1 usage by abg_compat and adjust includes accordingly: likewise * include/abg-diff-utils.h: likewise * include/abg-fwd.h: likewise * include/abg-ini.h: likewise * include/abg-interned-str.h: likewise * include/abg-ir.h: likewise * include/abg-libxml-utils.h: likewise * include/abg-libzip-utils.h: likewise * include/abg-reporter.h: likewise * include/abg-sptr-utils.h: likewise * include/abg-suppression.h: likewise * include/abg-tools-utils.h: likewise * include/abg-workers.h: likewise * src/abg-comp-filter.cc: likewise * src/abg-comparison-priv.h: likewise * src/abg-corpus.cc: likewise * src/abg-dwarf-reader.cc: likewise * src/abg-hash.cc: likewise * src/abg-ir.cc: likewise * src/abg-reader.cc: likewise * src/abg-suppression.cc: likewise * src/abg-tools-utils.cc: likewise * src/abg-writer.cc: likewise * tests/test-diff-filter.cc: likewise * tests/test-diff-pkg.cc: likewise * tests/test-read-dwarf.cc: likewise * tests/test-read-write.cc: likewise * tests/test-types-stability.cc: likewise * tests/test-write-read-archive.cc: likewise * tools/abicompat.cc: likewise * tools/abidiff.cc: likewise * tools/abidw.cc: likewise * tools/abilint.cc: likewise * tools/abipkgdiff.cc: likewise Signed-off-by: Matthias Maennich <maennich@google.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2019-07-05 11:00:23 +00:00
#define ABG_ASSERT(cond) do {({bool __abg_cond__ = bool(cond); assert(__abg_cond__); !!__abg_cond__;});} while (false)
#endif
} // end namespace abigail
#endif // __ABG_IRFWD_H__