2013-08-02 03:16:22 +00:00
|
|
|
// -*- Mode: C++ -*-
|
|
|
|
//
|
2015-01-07 12:53:58 +00:00
|
|
|
// Copyright (C) 2013-2015 Red Hat, Inc.
|
2013-08-02 03:16:22 +00:00
|
|
|
//
|
|
|
|
// 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 <cstddef>
|
|
|
|
#include <tr1/memory>
|
|
|
|
#include <list>
|
|
|
|
#include <vector>
|
|
|
|
#include <string>
|
|
|
|
#include <tr1/functional>
|
|
|
|
#include <typeinfo>
|
|
|
|
#include <utility> // for std::rel_ops, at least.
|
2013-12-07 07:07:54 +00:00
|
|
|
#include <ostream>
|
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"
|
2013-08-02 03:16:22 +00:00
|
|
|
#include "abg-hash.h"
|
|
|
|
|
|
|
|
/// Toplevel namespace for libabigail.
|
|
|
|
namespace abigail
|
|
|
|
{
|
2013-10-10 08:11:35 +00:00
|
|
|
/**
|
|
|
|
@mainpage libabigail
|
2013-08-02 23:30:56 +00:00
|
|
|
|
2014-11-01 12:02:12 +00:00
|
|
|
This is the API documentation of the Application Binary
|
|
|
|
Interface Generic Analysis and Instrumentation Library, aka,
|
|
|
|
<em>libabigail</em>.
|
2013-08-02 23:30:56 +00:00
|
|
|
|
2014-11-01 12:02:12 +00:00
|
|
|
Check out <a href="http://sourceware.org/libabigail"> the project
|
|
|
|
homepage</a>!
|
2013-10-10 08:11:35 +00:00
|
|
|
|
2014-11-01 12:02:12 +00:00
|
|
|
The current libabigail source code can be browsed at
|
|
|
|
http://sourceware.org/git/gitweb.cgi?p=libabigail.git
|
2013-10-10 08:11:35 +00:00
|
|
|
|
2014-11-01 12:02:12 +00:00
|
|
|
It can be checked out with:
|
|
|
|
<em>git clone git://sourceware.org/git/libabigail.git</em>
|
2013-10-10 08:11:35 +00:00
|
|
|
|
|
|
|
The mailing list to send messages and patches to is
|
2014-11-10 14:47:10 +00:00
|
|
|
libabigail@sourceware.org.
|
|
|
|
|
|
|
|
You can hang out with libabigail developers and users on irc at
|
2014-11-18 22:14:49 +00:00
|
|
|
irc://irc.oftc.net\#libabigail.
|
2013-10-10 08:11:35 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
// Inject some types.
|
|
|
|
using std::tr1::shared_ptr;
|
Fix memory leaks due to cycles in types ownership
* include/abg-fwd.h (std::tr1::weak_ptr): Inject this type in the
abigail namespace.
* include/abg-ir.h: Write a memory management guideline for the IR
artifacts.
(Type_base_wptr, function_type_wptr)
(class_decl_wptr): New typedefs.
(translation_unit::get_canonical_function_type): Declare new
member function.
(qualified_type_def::underlying_type_)
(reference_type_def::pointed_to_type_)
(typedef_decl::underlying_type_, function_decl::parameter::type_)
(function_type::return_type_, method_type::class_type_)
(non_type_tparameter::type_, type_composition::type_): Make this a
weak pointer.
(qualified_type_def::get_pointed_to_type)
(reference_type_def::get_pointed_to_type)
(array_type::get_element_type, typedef_decl::get_underlying_type)
(var_decl::get_type, function_decl::parameter::get_type)
(function_type::get_return_type, method_type::get_class_type)
(non_type_tparameter::get_type)
(type_composition::get_composed_type): Adjust to make this return
a shared pointer initialized with the content of the weak pointer.
(function_decl::function_decl, method_decl::method_decl): Remove
the overload that doesn't take a type. This is because now,
function types need to be registered to their containing
translation unit.
(struct function_type::hash): Declare here.
* src/abg-hash.cc (struct function_type::hash): Declare this in
abg-ir.h and just define the methods here.
* src/abg-ir.cc (fn_type_ptr_map): New typedef.
(translation_unit::priv::canonical_types_): Remove this unused
member.
(translation_unit::priv::canonical_function_types_): New member.
(translation_unit::get_canonical_function_type): Define this
function.
(array_type_def::priv::element_type_, var_decl::priv::type_)
(function_decl::priv::type_): Make this a weak pointer.
(qualified_type_def::get_underlying_type)
(pointer_type_def::get_pointed_to_type)
(reference_type_def::get_pointed_to_type)
(array_type_def::get_element_type)
(typedef_decl::get_underlying_type, var_decl::get_type)
(function_decl::get_type): Adjust to make this return a shared
pointer initialized with the content of the weak pointer.
(qualified_type_def::build_name)
(pointer_type_def::get_qualified_name)
(reference_type_def::get_qualified_name): Adjust.
(method_type::set_class_type): Cleanup the logic.
(function_decl::priv::priv): Remove the overload that takes a bare
pointer to a type. This should not be used now that we need the
function type to registered with the translation unit.
(function_decl::function_decl): Remove the overload that doesn't
take a type. This is because now, function types need to be
registered to their containing translation unit.
* src/abg-dwarf-reader.cc (build_function_decl): Register the
function type within its translation type and use its canonical
version. This complies with the new memory management rules.
* src/abg-reader.cc (build_function_decl): Likewise.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2014-09-10 15:09:47 +00:00
|
|
|
using std::tr1::weak_ptr;
|
2013-10-10 08:11:35 +00:00
|
|
|
using std::string;
|
2013-12-12 14:40:52 +00:00
|
|
|
using std::vector;
|
2013-10-10 08:11:35 +00:00
|
|
|
|
|
|
|
// Pull in relational operators.
|
|
|
|
using namespace std::rel_ops;
|
|
|
|
|
2014-10-11 09:27:59 +00:00
|
|
|
namespace ir
|
|
|
|
{
|
|
|
|
|
2013-10-10 08:11:35 +00:00
|
|
|
// Forward declarations for corpus.
|
|
|
|
|
|
|
|
class corpus;
|
|
|
|
|
|
|
|
// Forward declarations for ir.
|
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;
|
2013-10-10 08:11:35 +00:00
|
|
|
class location;
|
|
|
|
class location_manager;
|
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
|
|
|
class corpus;
|
2013-10-10 08:11:35 +00:00
|
|
|
class translation_unit;
|
|
|
|
class class_decl;
|
|
|
|
class class_tdecl;
|
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
|
|
|
class type_or_decl_base;
|
2013-10-10 08:11:35 +00:00
|
|
|
class decl_base;
|
|
|
|
class enum_type_decl;
|
|
|
|
class function_decl;
|
|
|
|
class function_tdecl;
|
|
|
|
class function_type;
|
|
|
|
class global_scope;
|
|
|
|
class node_visitor;
|
|
|
|
class location;
|
|
|
|
class location_manager;
|
|
|
|
class method_type;
|
|
|
|
class namespace_decl;
|
|
|
|
class pointer_type_def;
|
|
|
|
class qualified_type_def;
|
|
|
|
class reference_type_def;
|
|
|
|
class scope_decl;
|
|
|
|
class scope_type_decl;
|
|
|
|
class template_decl;
|
|
|
|
class template_parameter;
|
|
|
|
class non_type_tparameter;
|
|
|
|
class type_tparameter;
|
|
|
|
class template_tparameter;
|
|
|
|
|
|
|
|
class type_composition;
|
|
|
|
class type_base;
|
|
|
|
class type_decl;
|
|
|
|
class typedef_decl;
|
|
|
|
class var_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
|
|
|
class array_type_def;
|
|
|
|
class subrange_type;
|
2013-10-10 08:11:35 +00:00
|
|
|
|
|
|
|
struct type_shared_ptr_equal;
|
|
|
|
struct traversable_base;
|
|
|
|
|
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
|
|
|
shared_ptr<decl_base>
|
2013-10-10 08:11:35 +00:00
|
|
|
add_decl_to_scope(shared_ptr<decl_base>, scope_decl*);
|
|
|
|
|
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
|
|
|
shared_ptr<decl_base>
|
2013-10-10 08:11:35 +00:00
|
|
|
add_decl_to_scope (shared_ptr<decl_base>, shared_ptr<scope_decl>);
|
|
|
|
|
2014-04-16 15:09:49 +00:00
|
|
|
const global_scope*
|
|
|
|
get_global_scope(const decl_base&);
|
|
|
|
|
|
|
|
const global_scope*
|
|
|
|
get_global_scope(const decl_base*);
|
|
|
|
|
2013-12-12 14:40:52 +00:00
|
|
|
const global_scope*
|
2013-10-10 08:11:35 +00:00
|
|
|
get_global_scope(const shared_ptr<decl_base>);
|
|
|
|
|
|
|
|
translation_unit*
|
2014-04-16 15:09:49 +00:00
|
|
|
get_translation_unit(const decl_base&);
|
2013-10-10 08:11:35 +00:00
|
|
|
|
2013-12-11 19:28:18 +00:00
|
|
|
translation_unit*
|
2014-04-16 15:09:49 +00:00
|
|
|
get_translation_unit(const decl_base*);
|
|
|
|
|
|
|
|
translation_unit*
|
|
|
|
get_translation_unit(const shared_ptr<decl_base>);
|
2013-12-11 19:28:18 +00:00
|
|
|
|
2014-04-21 15:14:30 +00:00
|
|
|
bool
|
|
|
|
is_global_scope(const scope_decl&);
|
|
|
|
|
2015-03-17 11:00:52 +00:00
|
|
|
const global_scope*
|
2013-10-19 14:01:59 +00:00
|
|
|
is_global_scope(const scope_decl*);
|
2013-10-10 08:11:35 +00:00
|
|
|
|
|
|
|
bool
|
2013-10-19 14:01:59 +00:00
|
|
|
is_global_scope(const shared_ptr<scope_decl>);
|
2013-10-10 08:11:35 +00:00
|
|
|
|
2014-04-21 15:14:30 +00:00
|
|
|
bool
|
|
|
|
is_at_global_scope(const decl_base&);
|
|
|
|
|
2013-10-10 08:11:35 +00:00
|
|
|
bool
|
2013-10-19 14:01:59 +00:00
|
|
|
is_at_global_scope(const shared_ptr<decl_base>);
|
2013-10-10 08:11:35 +00:00
|
|
|
|
|
|
|
bool
|
2013-10-19 14:01:59 +00:00
|
|
|
is_at_class_scope(const shared_ptr<decl_base>);
|
2013-10-10 08:11:35 +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_at_class_scope(const decl_base*);
|
|
|
|
|
|
|
|
bool
|
|
|
|
is_at_class_scope(const decl_base&);
|
|
|
|
|
2013-10-10 08:11:35 +00:00
|
|
|
bool
|
2013-10-19 14:01:59 +00:00
|
|
|
is_at_template_scope(const shared_ptr<decl_base>);
|
2013-10-10 08:11:35 +00:00
|
|
|
|
|
|
|
bool
|
2013-10-19 14:01:59 +00:00
|
|
|
is_template_parameter(const shared_ptr<decl_base>);
|
2013-10-10 08:11:35 +00:00
|
|
|
|
2015-09-21 08:53:33 +00:00
|
|
|
function_decl*
|
2015-10-14 18:44:18 +00:00
|
|
|
is_function_decl(const decl_base*);
|
2015-09-21 08:53:33 +00:00
|
|
|
|
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
|
|
|
shared_ptr<function_decl>
|
|
|
|
is_function_decl(shared_ptr<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
|
|
|
bool
|
|
|
|
is_function_decl(const decl_base&);
|
|
|
|
|
2015-09-21 08:53:33 +00:00
|
|
|
decl_base*
|
|
|
|
is_decl(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
|
|
|
shared_ptr<decl_base>
|
|
|
|
is_decl(const shared_ptr<type_or_decl_base>&);
|
|
|
|
|
|
|
|
bool
|
|
|
|
is_type(const type_or_decl_base&);
|
|
|
|
|
|
|
|
type_base*
|
|
|
|
is_type(const type_or_decl_base*);
|
|
|
|
|
|
|
|
shared_ptr<type_base>
|
|
|
|
is_type(const shared_ptr<type_or_decl_base>& tod);
|
|
|
|
|
2013-12-14 09:03:09 +00:00
|
|
|
bool
|
|
|
|
is_type(const decl_base&);
|
|
|
|
|
2013-11-28 13:51:23 +00:00
|
|
|
shared_ptr<type_base>
|
2013-10-19 14:01:59 +00:00
|
|
|
is_type(const shared_ptr<decl_base>);
|
2013-10-10 08:11:35 +00:00
|
|
|
|
2015-03-13 16:43:57 +00:00
|
|
|
type_base*
|
|
|
|
is_type(decl_base*);
|
|
|
|
|
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 shared_ptr<type_base>&);
|
|
|
|
|
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
|
|
|
shared_ptr<type_decl>
|
2016-07-04 14:51:10 +00:00
|
|
|
is_type_decl(const shared_ptr<type_base>&);
|
|
|
|
|
|
|
|
shared_ptr<type_decl>
|
|
|
|
is_type_decl(const shared_ptr<decl_base>&);
|
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
|
|
|
|
2014-04-02 15:23:56 +00:00
|
|
|
shared_ptr<typedef_decl>
|
|
|
|
is_typedef(const shared_ptr<type_base>);
|
|
|
|
|
|
|
|
shared_ptr<typedef_decl>
|
|
|
|
is_typedef(const shared_ptr<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 typedef_decl*
|
|
|
|
is_typedef(const type_base*);
|
|
|
|
|
|
|
|
typedef_decl*
|
|
|
|
is_typedef(type_base*);
|
|
|
|
|
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
|
|
|
shared_ptr<enum_type_decl>
|
2014-11-05 09:08:33 +00:00
|
|
|
is_enum_type(const shared_ptr<type_base>&);
|
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
|
|
|
|
2014-08-22 15:19:27 +00:00
|
|
|
shared_ptr<enum_type_decl>
|
2014-11-05 09:08:33 +00:00
|
|
|
is_enum_type(const shared_ptr<decl_base>&);
|
2014-08-22 15:19:27 +00:00
|
|
|
|
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*
|
2016-07-25 15:39:11 +00:00
|
|
|
is_class_type(const type_or_decl_base*);
|
2014-04-07 07:54:52 +00:00
|
|
|
|
|
|
|
shared_ptr<class_decl>
|
2016-07-25 15:39:11 +00:00
|
|
|
is_class_type(const shared_ptr<type_or_decl_base>&);
|
2014-04-07 07:54:52 +00:00
|
|
|
|
2015-02-19 10:30:43 +00:00
|
|
|
shared_ptr<class_decl>
|
2016-07-25 15:39:11 +00:00
|
|
|
is_compatible_with_class_type(const shared_ptr<type_base>&);
|
2015-02-19 10:30:43 +00:00
|
|
|
|
2015-08-26 10:06:46 +00:00
|
|
|
shared_ptr<class_decl>
|
2016-07-25 15:39:11 +00:00
|
|
|
is_compatible_with_class_type(const shared_ptr<decl_base>&);
|
2015-08-26 10:06:46 +00:00
|
|
|
|
2015-02-20 13:23:15 +00:00
|
|
|
pointer_type_def*
|
|
|
|
is_pointer_type(type_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*
|
|
|
|
is_pointer_type(const type_base*);
|
|
|
|
|
2014-10-16 21:32:08 +00:00
|
|
|
shared_ptr<pointer_type_def>
|
2014-11-05 09:08:33 +00:00
|
|
|
is_pointer_type(const shared_ptr<type_base>);
|
2014-10-16 21:32:08 +00:00
|
|
|
|
2015-02-20 13:23:15 +00:00
|
|
|
reference_type_def*
|
|
|
|
is_reference_type(type_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*
|
|
|
|
is_reference_type(const type_base*);
|
|
|
|
|
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
|
|
|
shared_ptr<reference_type_def>
|
|
|
|
is_reference_type(const shared_ptr<type_base>);
|
|
|
|
|
2015-02-20 13:23:15 +00:00
|
|
|
qualified_type_def*
|
2015-12-06 16:12:43 +00:00
|
|
|
is_qualified_type(const type_base*);
|
2015-02-20 13:23:15 +00:00
|
|
|
|
2014-10-16 21:32:08 +00:00
|
|
|
shared_ptr<qualified_type_def>
|
|
|
|
is_qualified_type(const shared_ptr<type_base>);
|
|
|
|
|
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
|
|
|
shared_ptr<function_type>
|
|
|
|
is_function_type(const shared_ptr<type_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
|
|
|
function_type*
|
|
|
|
is_function_type(type_base*);
|
|
|
|
|
|
|
|
const function_type*
|
|
|
|
is_function_type(const type_base*);
|
|
|
|
|
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
|
|
|
shared_ptr<method_type>
|
|
|
|
is_method_type(const shared_ptr<type_base>);
|
|
|
|
|
2015-08-21 10:09:22 +00:00
|
|
|
const method_type*
|
|
|
|
is_method_type(const type_base*);
|
|
|
|
|
|
|
|
method_type*
|
|
|
|
is_method_type(type_base*);
|
|
|
|
|
2014-03-10 22:20:34 +00:00
|
|
|
shared_ptr<class_decl>
|
|
|
|
look_through_decl_only_class(shared_ptr<class_decl>);
|
|
|
|
|
2015-09-21 08:53:33 +00:00
|
|
|
var_decl*
|
|
|
|
is_var_decl(const type_or_decl_base*);
|
|
|
|
|
2014-08-22 15:19:27 +00:00
|
|
|
shared_ptr<var_decl>
|
2013-10-19 14:01:59 +00:00
|
|
|
is_var_decl(const shared_ptr<decl_base>);
|
2013-10-10 08:11:35 +00:00
|
|
|
|
2015-09-21 08:53:33 +00:00
|
|
|
shared_ptr<namespace_decl>
|
|
|
|
is_namespace(const shared_ptr<decl_base>&);
|
|
|
|
|
|
|
|
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*);
|
2015-09-21 08:53:33 +00:00
|
|
|
|
2013-10-10 08:11:35 +00:00
|
|
|
bool
|
2013-10-19 14:01:59 +00:00
|
|
|
is_template_parm_composition_type(const shared_ptr<decl_base>);
|
2013-10-10 08:11:35 +00:00
|
|
|
|
|
|
|
bool
|
2013-10-19 14:01:59 +00:00
|
|
|
is_template_decl(const shared_ptr<decl_base>);
|
2013-10-10 08:11:35 +00:00
|
|
|
|
|
|
|
bool
|
2013-10-19 14:01:59 +00:00
|
|
|
is_function_template_pattern(const shared_ptr<decl_base>);
|
2013-10-10 08:11:35 +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
|
|
|
shared_ptr<decl_base>
|
2013-10-19 14:01:59 +00:00
|
|
|
add_decl_to_scope(shared_ptr<decl_base>, scope_decl*);
|
2013-10-10 08:11:35 +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
|
|
|
shared_ptr<decl_base>
|
2013-10-19 14:01:59 +00:00
|
|
|
add_decl_to_scope(shared_ptr<decl_base>, shared_ptr<scope_decl>);
|
2013-10-10 08:11:35 +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
|
|
|
shared_ptr<decl_base>
|
2013-12-12 14:40:52 +00:00
|
|
|
insert_decl_into_scope(shared_ptr<decl_base>,
|
|
|
|
vector<shared_ptr<decl_base> >::iterator,
|
|
|
|
scope_decl*);
|
2013-12-11 19:28:18 +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
|
|
|
shared_ptr<decl_base>
|
2013-12-12 14:40:52 +00:00
|
|
|
insert_decl_into_scope(shared_ptr<decl_base>,
|
|
|
|
vector<shared_ptr<decl_base> >::iterator,
|
|
|
|
shared_ptr<scope_decl>);
|
|
|
|
|
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 shared_ptr<decl_base>);
|
|
|
|
|
|
|
|
bool
|
|
|
|
is_member_decl(const shared_ptr<decl_base>);
|
|
|
|
|
|
|
|
bool
|
|
|
|
is_member_decl(const decl_base*);
|
|
|
|
|
|
|
|
bool
|
|
|
|
is_member_decl(const decl_base&);
|
|
|
|
|
2015-09-21 08:53:33 +00:00
|
|
|
scope_decl*
|
|
|
|
is_scope_decl(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
|
|
|
|
is_member_type(const shared_ptr<type_base>);
|
|
|
|
|
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(shared_ptr<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&);
|
|
|
|
|
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
|
Pass a bunch of smart pointers by reference
Some smart pointers handling got high on performance profiles. I am
passing those by reference here.
* include/abg-fwd.h (get_member_is_static, is_member_function)
(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): Declare the smart pointer
parameter of these as being passed by reference.
* include/abg-ir.h (get_member_access_specifier)
(get_member_is_static, get_member_access_specifier)
(set_member_function_is_ctor, set_member_function_is_const)
(set_member_function_vtable_offset): Likewise, for these friend
declarations to the decl_base type.
* src/abg-ir.cc (get_member_access_specifier)
(get_member_is_static, is_member_function)
(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): In these definitions, the smart
pointer parameter is passed by reference.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-10 17:41:44 +00:00
|
|
|
get_member_is_static(const shared_ptr<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
|
|
|
|
|
|
|
void
|
2014-08-22 15:19:27 +00:00
|
|
|
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
|
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_is_static(const shared_ptr<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
|
|
|
|
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&);
|
|
|
|
|
|
|
|
bool
|
|
|
|
is_data_member(const var_decl*);
|
|
|
|
|
|
|
|
bool
|
|
|
|
is_data_member(const shared_ptr<var_decl>);
|
|
|
|
|
2014-09-03 06:46:58 +00:00
|
|
|
shared_ptr<var_decl>
|
2014-08-22 15:19:27 +00:00
|
|
|
is_data_member(const shared_ptr<decl_base>&);
|
|
|
|
|
2015-05-05 08:05:45 +00:00
|
|
|
array_type_def*
|
|
|
|
is_array_type(const type_base* 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
|
|
|
shared_ptr<array_type_def>
|
2014-12-12 13:30:31 +00:00
|
|
|
is_array_type(const shared_ptr<type_base> 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
|
|
|
|
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(shared_ptr<var_decl>, size_t);
|
|
|
|
|
|
|
|
size_t
|
|
|
|
get_data_member_offset(const var_decl&);
|
|
|
|
|
|
|
|
size_t
|
|
|
|
get_data_member_offset(const shared_ptr<var_decl>);
|
|
|
|
|
2014-04-11 14:52:00 +00:00
|
|
|
size_t
|
|
|
|
get_data_member_offset(const shared_ptr<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
|
|
|
void
|
|
|
|
set_data_member_is_laid_out(shared_ptr<var_decl>, bool);
|
|
|
|
|
|
|
|
bool
|
|
|
|
get_data_member_is_laid_out(const var_decl&);
|
|
|
|
|
|
|
|
bool
|
|
|
|
get_data_member_is_laid_out(const shared_ptr<var_decl>);
|
|
|
|
|
2014-03-20 10:56:56 +00:00
|
|
|
bool
|
|
|
|
is_member_function(const function_decl&);
|
|
|
|
|
|
|
|
bool
|
|
|
|
is_member_function(const function_decl*);
|
|
|
|
|
|
|
|
bool
|
Pass a bunch of smart pointers by reference
Some smart pointers handling got high on performance profiles. I am
passing those by reference here.
* include/abg-fwd.h (get_member_is_static, is_member_function)
(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): Declare the smart pointer
parameter of these as being passed by reference.
* include/abg-ir.h (get_member_access_specifier)
(get_member_is_static, get_member_access_specifier)
(set_member_function_is_ctor, set_member_function_is_const)
(set_member_function_vtable_offset): Likewise, for these friend
declarations to the decl_base type.
* src/abg-ir.cc (get_member_access_specifier)
(get_member_is_static, is_member_function)
(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): In these definitions, the smart
pointer parameter is passed by reference.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-10 17:41:44 +00:00
|
|
|
is_member_function(const shared_ptr<function_decl>&);
|
2014-03-20 10:56:56 +00:00
|
|
|
|
|
|
|
bool
|
|
|
|
get_member_function_is_ctor(const function_decl&);
|
|
|
|
|
|
|
|
bool
|
Pass a bunch of smart pointers by reference
Some smart pointers handling got high on performance profiles. I am
passing those by reference here.
* include/abg-fwd.h (get_member_is_static, is_member_function)
(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): Declare the smart pointer
parameter of these as being passed by reference.
* include/abg-ir.h (get_member_access_specifier)
(get_member_is_static, get_member_access_specifier)
(set_member_function_is_ctor, set_member_function_is_const)
(set_member_function_vtable_offset): Likewise, for these friend
declarations to the decl_base type.
* src/abg-ir.cc (get_member_access_specifier)
(get_member_is_static, is_member_function)
(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): In these definitions, the smart
pointer parameter is passed by reference.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-10 17:41:44 +00:00
|
|
|
get_member_function_is_ctor(const shared_ptr<function_decl>&);
|
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
|
Pass a bunch of smart pointers by reference
Some smart pointers handling got high on performance profiles. I am
passing those by reference here.
* include/abg-fwd.h (get_member_is_static, is_member_function)
(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): Declare the smart pointer
parameter of these as being passed by reference.
* include/abg-ir.h (get_member_access_specifier)
(get_member_is_static, get_member_access_specifier)
(set_member_function_is_ctor, set_member_function_is_const)
(set_member_function_vtable_offset): Likewise, for these friend
declarations to the decl_base type.
* src/abg-ir.cc (get_member_access_specifier)
(get_member_is_static, is_member_function)
(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): In these definitions, the smart
pointer parameter is passed by reference.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-10 17:41:44 +00:00
|
|
|
set_member_function_is_ctor(const shared_ptr<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
|
|
|
|
2014-03-20 10:56:56 +00:00
|
|
|
bool
|
|
|
|
get_member_function_is_dtor(const function_decl&);
|
|
|
|
|
|
|
|
bool
|
Pass a bunch of smart pointers by reference
Some smart pointers handling got high on performance profiles. I am
passing those by reference here.
* include/abg-fwd.h (get_member_is_static, is_member_function)
(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): Declare the smart pointer
parameter of these as being passed by reference.
* include/abg-ir.h (get_member_access_specifier)
(get_member_is_static, get_member_access_specifier)
(set_member_function_is_ctor, set_member_function_is_const)
(set_member_function_vtable_offset): Likewise, for these friend
declarations to the decl_base type.
* src/abg-ir.cc (get_member_access_specifier)
(get_member_is_static, is_member_function)
(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): In these definitions, the smart
pointer parameter is passed by reference.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-10 17:41:44 +00:00
|
|
|
get_member_function_is_dtor(const shared_ptr<function_decl>&);
|
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
|
Pass a bunch of smart pointers by reference
Some smart pointers handling got high on performance profiles. I am
passing those by reference here.
* include/abg-fwd.h (get_member_is_static, is_member_function)
(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): Declare the smart pointer
parameter of these as being passed by reference.
* include/abg-ir.h (get_member_access_specifier)
(get_member_is_static, get_member_access_specifier)
(set_member_function_is_ctor, set_member_function_is_const)
(set_member_function_vtable_offset): Likewise, for these friend
declarations to the decl_base type.
* src/abg-ir.cc (get_member_access_specifier)
(get_member_is_static, is_member_function)
(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): In these definitions, the smart
pointer parameter is passed by reference.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-10 17:41:44 +00:00
|
|
|
set_member_function_is_dtor(const shared_ptr<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
|
|
|
|
2014-03-20 10:56:56 +00:00
|
|
|
bool
|
|
|
|
get_member_function_is_const(const function_decl&);
|
|
|
|
|
|
|
|
bool
|
Pass a bunch of smart pointers by reference
Some smart pointers handling got high on performance profiles. I am
passing those by reference here.
* include/abg-fwd.h (get_member_is_static, is_member_function)
(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): Declare the smart pointer
parameter of these as being passed by reference.
* include/abg-ir.h (get_member_access_specifier)
(get_member_is_static, get_member_access_specifier)
(set_member_function_is_ctor, set_member_function_is_const)
(set_member_function_vtable_offset): Likewise, for these friend
declarations to the decl_base type.
* src/abg-ir.cc (get_member_access_specifier)
(get_member_is_static, is_member_function)
(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): In these definitions, the smart
pointer parameter is passed by reference.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-10 17:41:44 +00:00
|
|
|
get_member_function_is_const(const shared_ptr<function_decl>&);
|
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
|
Pass a bunch of smart pointers by reference
Some smart pointers handling got high on performance profiles. I am
passing those by reference here.
* include/abg-fwd.h (get_member_is_static, is_member_function)
(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): Declare the smart pointer
parameter of these as being passed by reference.
* include/abg-ir.h (get_member_access_specifier)
(get_member_is_static, get_member_access_specifier)
(set_member_function_is_ctor, set_member_function_is_const)
(set_member_function_vtable_offset): Likewise, for these friend
declarations to the decl_base type.
* src/abg-ir.cc (get_member_access_specifier)
(get_member_is_static, is_member_function)
(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): In these definitions, the smart
pointer parameter is passed by reference.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-10 17:41:44 +00:00
|
|
|
set_member_function_is_const(const shared_ptr<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
|
|
|
|
2014-03-20 10:56:56 +00:00
|
|
|
size_t
|
|
|
|
get_member_function_vtable_offset(const function_decl&);
|
|
|
|
|
|
|
|
size_t
|
Pass a bunch of smart pointers by reference
Some smart pointers handling got high on performance profiles. I am
passing those by reference here.
* include/abg-fwd.h (get_member_is_static, is_member_function)
(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): Declare the smart pointer
parameter of these as being passed by reference.
* include/abg-ir.h (get_member_access_specifier)
(get_member_is_static, get_member_access_specifier)
(set_member_function_is_ctor, set_member_function_is_const)
(set_member_function_vtable_offset): Likewise, for these friend
declarations to the decl_base type.
* src/abg-ir.cc (get_member_access_specifier)
(get_member_is_static, is_member_function)
(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): In these definitions, the smart
pointer parameter is passed by reference.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-10 17:41:44 +00:00
|
|
|
get_member_function_vtable_offset(const shared_ptr<function_decl>&);
|
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,
|
|
|
|
size_t s);
|
|
|
|
|
|
|
|
void
|
Pass a bunch of smart pointers by reference
Some smart pointers handling got high on performance profiles. I am
passing those by reference here.
* include/abg-fwd.h (get_member_is_static, is_member_function)
(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): Declare the smart pointer
parameter of these as being passed by reference.
* include/abg-ir.h (get_member_access_specifier)
(get_member_is_static, get_member_access_specifier)
(set_member_function_is_ctor, set_member_function_is_const)
(set_member_function_vtable_offset): Likewise, for these friend
declarations to the decl_base type.
* src/abg-ir.cc (get_member_access_specifier)
(get_member_is_static, is_member_function)
(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): In these definitions, the smart
pointer parameter is passed by reference.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-10 17:41:44 +00:00
|
|
|
set_member_function_vtable_offset(const shared_ptr<function_decl> &f,
|
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
|
|
|
size_t s);
|
|
|
|
|
2014-04-13 21:09:02 +00:00
|
|
|
bool
|
2014-09-30 16:16:03 +00:00
|
|
|
get_member_function_is_virtual(const function_decl&);
|
2014-04-13 21:09:02 +00:00
|
|
|
|
|
|
|
bool
|
Pass a bunch of smart pointers by reference
Some smart pointers handling got high on performance profiles. I am
passing those by reference here.
* include/abg-fwd.h (get_member_is_static, is_member_function)
(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): Declare the smart pointer
parameter of these as being passed by reference.
* include/abg-ir.h (get_member_access_specifier)
(get_member_is_static, get_member_access_specifier)
(set_member_function_is_ctor, set_member_function_is_const)
(set_member_function_vtable_offset): Likewise, for these friend
declarations to the decl_base type.
* src/abg-ir.cc (get_member_access_specifier)
(get_member_is_static, is_member_function)
(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): In these definitions, the smart
pointer parameter is passed by reference.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-03-10 17:41:44 +00:00
|
|
|
get_member_function_is_virtual(const shared_ptr<function_decl>&);
|
2014-04-13 21:09:02 +00:00
|
|
|
|
2014-10-02 10:30:54 +00:00
|
|
|
bool
|
|
|
|
get_member_function_is_virtual(const function_decl*);
|
|
|
|
|
2014-04-14 12:56:51 +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_virtual(function_decl&, bool);
|
2014-04-14 12:56:51 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
set_member_function_is_virtual(const shared_ptr<function_decl>&, bool);
|
|
|
|
|
2014-04-02 15:23:56 +00:00
|
|
|
shared_ptr<type_base>
|
|
|
|
strip_typedef(const shared_ptr<type_base>);
|
|
|
|
|
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
|
|
|
shared_ptr<type_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
|
|
|
peel_typedef_type(const shared_ptr<type_base>&);
|
|
|
|
|
|
|
|
const type_base*
|
|
|
|
peel_typedef_type(const type_base*);
|
|
|
|
|
|
|
|
shared_ptr<type_base>
|
|
|
|
peel_pointer_type(const shared_ptr<type_base>&);
|
|
|
|
|
|
|
|
const type_base*
|
|
|
|
peel_pointer_type(const type_base*);
|
|
|
|
|
|
|
|
shared_ptr<type_base>
|
|
|
|
peel_reference_type(const shared_ptr<type_base>&);
|
|
|
|
|
|
|
|
const type_base*
|
|
|
|
peel_reference_type(const type_base*);
|
|
|
|
|
2015-10-04 10:08:08 +00:00
|
|
|
const shared_ptr<type_base>
|
|
|
|
peel_array_type(const shared_ptr<type_base>&);
|
|
|
|
|
|
|
|
const type_base*
|
|
|
|
peel_array_type(const type_base*);
|
|
|
|
|
2015-12-06 16:29:50 +00:00
|
|
|
const type_base*
|
|
|
|
peel_qualified_type(const type_base*);
|
|
|
|
|
|
|
|
const shared_ptr<type_base>
|
|
|
|
peel_qualified_type(const shared_ptr<type_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
|
|
|
shared_ptr<type_base>
|
|
|
|
peel_typedef_pointer_or_reference_type(const shared_ptr<type_base>);
|
|
|
|
|
|
|
|
type_base*
|
|
|
|
peel_typedef_pointer_or_reference_type(const type_base*);
|
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
|
|
|
|
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
|
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
|
|
|
get_name(const shared_ptr<type_or_decl_base>&,
|
|
|
|
bool qualified = true);
|
|
|
|
|
2015-09-02 11:41:34 +00:00
|
|
|
scope_decl*
|
|
|
|
get_type_scope(type_base*);
|
|
|
|
|
|
|
|
scope_decl*
|
|
|
|
get_type_scope(const shared_ptr<type_base>&);
|
|
|
|
|
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
|
2016-05-20 15:19:27 +00:00
|
|
|
get_type_name(const shared_ptr<type_base>&,
|
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
|
|
|
|
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 shared_ptr<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);
|
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
|
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 shared_ptr<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);
|
2015-08-21 10:09:22 +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_method_type_name(const method_type&, bool internal = false);
|
2015-08-21 10:09:22 +00:00
|
|
|
|
2014-04-14 20:46:51 +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 decl_base*, bool internal = false);
|
2014-04-14 20:46:51 +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 type_base*, bool internal = false);
|
2014-04-14 20:46:51 +00:00
|
|
|
|
2015-05-06 07:49:00 +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 type_or_decl_base*,bool internal = false);
|
2015-05-06 07:49:00 +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
|
|
|
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 shared_ptr<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
|
|
|
|
2014-04-14 20:46:51 +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 shared_ptr<decl_base>&, bool internal = false);
|
2014-04-14 20:46:51 +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 shared_ptr<type_base>&, bool internal = false);
|
2014-04-14 20:46:51 +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
|
|
|
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
|
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 shared_ptr<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
|
|
|
|
2015-08-21 10:09:22 +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);
|
2015-08-21 10:09:22 +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);
|
2015-08-21 10:09:22 +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 shared_ptr<method_type>&,
|
|
|
|
bool internal = false);
|
2015-08-21 10:09:22 +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*);
|
|
|
|
|
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
|
|
|
shared_ptr<decl_base>
|
|
|
|
get_type_declaration(const shared_ptr<type_base>);
|
|
|
|
|
2014-04-02 15:23:56 +00:00
|
|
|
bool
|
|
|
|
types_are_compatible(const shared_ptr<type_base>,
|
|
|
|
const shared_ptr<type_base>);
|
|
|
|
|
|
|
|
bool
|
|
|
|
types_are_compatible(const shared_ptr<decl_base>,
|
|
|
|
const shared_ptr<decl_base>);
|
|
|
|
|
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 shared_ptr<decl_base>,
|
|
|
|
const scope_decl*);
|
|
|
|
|
|
|
|
const scope_decl*
|
|
|
|
get_top_most_scope_under(const shared_ptr<decl_base>,
|
|
|
|
const shared_ptr<scope_decl>);
|
|
|
|
|
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>&);
|
|
|
|
|
2015-10-15 08:14:22 +00:00
|
|
|
string
|
|
|
|
components_to_type_name(const std::list<string>&);
|
|
|
|
|
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
|
|
|
const shared_ptr<decl_base>
|
|
|
|
lookup_type_in_corpus(const string&, const corpus&);
|
|
|
|
|
2015-03-30 10:17:52 +00:00
|
|
|
const shared_ptr<class_decl>
|
|
|
|
lookup_class_type_in_corpus(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
|
|
|
const shared_ptr<function_type>
|
|
|
|
lookup_function_type_in_corpus(const function_type&, const corpus&);
|
|
|
|
|
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
|
|
|
const shared_ptr<decl_base>
|
|
|
|
lookup_type_in_translation_unit(const string&,
|
|
|
|
const translation_unit&);
|
|
|
|
|
|
|
|
const shared_ptr<decl_base>
|
|
|
|
lookup_type_in_translation_unit(const std::list<string>&,
|
|
|
|
const translation_unit&);
|
|
|
|
|
2015-03-30 10:17:52 +00:00
|
|
|
const shared_ptr<class_decl>
|
|
|
|
lookup_class_type_in_translation_unit(const std::list<string>& fqn,
|
|
|
|
const translation_unit& tu);
|
|
|
|
|
|
|
|
const shared_ptr<class_decl>
|
|
|
|
lookup_class_type_in_translation_unit(const string& fqn,
|
|
|
|
const translation_unit& tu);
|
|
|
|
|
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 shared_ptr<type_base>
|
|
|
|
lookup_type_in_translation_unit(const shared_ptr<type_base>,
|
|
|
|
const translation_unit&);
|
|
|
|
|
|
|
|
shared_ptr<function_type>
|
|
|
|
lookup_function_type_in_translation_unit(const function_type&,
|
|
|
|
const translation_unit&);
|
|
|
|
|
2015-07-20 14:14:01 +00:00
|
|
|
shared_ptr<type_base>
|
|
|
|
synthesize_type_from_translation_unit(const shared_ptr<type_base>& type,
|
|
|
|
translation_unit& tu);
|
|
|
|
|
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
|
|
|
shared_ptr<function_type>
|
|
|
|
synthesize_function_type_from_translation_unit(const function_type&,
|
2015-07-20 14:14:01 +00:00
|
|
|
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
|
|
|
|
|
|
|
shared_ptr<function_type>
|
|
|
|
lookup_function_type_in_translation_unit(const shared_ptr<function_type>&,
|
|
|
|
const translation_unit&);
|
|
|
|
|
|
|
|
shared_ptr<function_type>
|
|
|
|
lookup_function_type_in_corpus(const shared_ptr<function_type>&,
|
|
|
|
corpus&);
|
|
|
|
|
|
|
|
shared_ptr<type_base>
|
|
|
|
lookup_type_in_corpus(const shared_ptr<type_base>&, corpus&);
|
|
|
|
|
2014-03-12 13:59:45 +00:00
|
|
|
const shared_ptr<decl_base>
|
|
|
|
lookup_type_in_scope(const string&,
|
2015-12-11 08:57:36 +00:00
|
|
|
const shared_ptr<scope_decl>&);
|
2014-03-12 13:59:45 +00:00
|
|
|
|
|
|
|
const shared_ptr<decl_base>
|
|
|
|
lookup_type_in_scope(const std::list<string>&,
|
2015-12-11 08:57:36 +00:00
|
|
|
const shared_ptr<scope_decl>&);
|
2014-03-12 13:59:45 +00:00
|
|
|
|
|
|
|
const shared_ptr<decl_base>
|
|
|
|
lookup_var_decl_in_scope(const string&,
|
2015-12-11 08:57:36 +00:00
|
|
|
const shared_ptr<scope_decl>&);
|
2014-03-12 13:59:45 +00:00
|
|
|
|
|
|
|
const shared_ptr<decl_base>
|
|
|
|
lookup_var_decl_in_scope(const std::list<string>&,
|
2015-12-11 08:57:36 +00:00
|
|
|
const shared_ptr<scope_decl>&);
|
2014-03-12 13:59:45 +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
|
|
|
string
|
|
|
|
demangle_cplus_mangled_name(const string&);
|
|
|
|
|
2014-12-26 17:28:20 +00:00
|
|
|
shared_ptr<type_base>
|
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
|
|
|
type_or_void(const shared_ptr<type_base>, 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
|
|
|
|
2015-02-19 10:30:43 +00:00
|
|
|
shared_ptr<type_base>
|
|
|
|
canonicalize(shared_ptr<type_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
|
|
|
type_base*
|
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_has_non_canonicalized_subtype(shared_ptr<type_base> 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
|
|
|
|
2015-05-06 08:20:15 +00:00
|
|
|
bool
|
|
|
|
type_has_sub_type_changes(shared_ptr<type_base> t_v1,
|
|
|
|
shared_ptr<type_base> 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(shared_ptr<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 shared_ptr<type_or_decl_base>&);
|
2014-10-11 09:27:59 +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;
|
|
|
|
|
|
|
|
} // end namespace comparison
|
|
|
|
|
2013-12-07 07:07:54 +00:00
|
|
|
void
|
|
|
|
dump(const shared_ptr<decl_base>, std::ostream&);
|
|
|
|
|
2013-10-16 20:01:28 +00:00
|
|
|
void
|
|
|
|
dump(const shared_ptr<decl_base>);
|
|
|
|
|
2013-12-07 07:07:54 +00:00
|
|
|
void
|
|
|
|
dump(const shared_ptr<type_base>, std::ostream&);
|
|
|
|
|
2013-10-16 20:01:28 +00:00
|
|
|
void
|
|
|
|
dump(const shared_ptr<type_base>);
|
|
|
|
|
2013-12-07 07:07:54 +00:00
|
|
|
void
|
|
|
|
dump(const shared_ptr<var_decl>, std::ostream&);
|
|
|
|
|
2013-10-16 20:01:28 +00:00
|
|
|
void
|
2013-10-19 14:01:59 +00:00
|
|
|
dump(const shared_ptr<var_decl>);
|
2013-10-16 20:01:28 +00:00
|
|
|
|
2013-12-07 07:07:54 +00:00
|
|
|
void
|
|
|
|
dump(const translation_unit&, std::ostream&);
|
|
|
|
|
2013-10-16 20:01:28 +00:00
|
|
|
void
|
|
|
|
dump(const translation_unit&);
|
|
|
|
|
2013-12-07 07:07:54 +00:00
|
|
|
void
|
|
|
|
dump(const shared_ptr<translation_unit>, std::ostream&);
|
|
|
|
|
|
|
|
void
|
|
|
|
dump(const shared_ptr<translation_unit>);
|
|
|
|
|
2014-04-16 15:09:49 +00:00
|
|
|
void
|
|
|
|
dump_decl_location(const decl_base&);
|
|
|
|
|
|
|
|
void
|
|
|
|
dump_decl_location(const decl_base*);
|
|
|
|
|
|
|
|
void
|
|
|
|
dump_decl_location(const shared_ptr<decl_base>&);
|
|
|
|
|
2013-08-02 03:16:22 +00:00
|
|
|
} // end namespace abigail
|
|
|
|
#endif // __ABG_IRFWD_H__
|