mirror of
https://github.com/openharmony/third_party_libabigail.git
synced 2026-07-01 06:09:52 -04:00
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>
This commit is contained in:
+10
-1
@@ -78,7 +78,16 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
corpus(const string&);
|
||||
corpus(const string&, ir::environment*);
|
||||
|
||||
environment*
|
||||
get_environment();
|
||||
|
||||
const environment*
|
||||
get_environment() const;
|
||||
|
||||
void
|
||||
set_environment(environment*) const;
|
||||
|
||||
void
|
||||
add(const translation_unit_sptr);
|
||||
|
||||
@@ -87,9 +87,9 @@ typedef shared_ptr<read_context> read_context_sptr;
|
||||
read_context_sptr
|
||||
create_read_context(const std::string& elf_path,
|
||||
char** debug_info_root_path,
|
||||
ir::environment* environment,
|
||||
bool read_all_types = false);
|
||||
|
||||
|
||||
corpus_sptr
|
||||
read_corpus_from_elf(read_context& ctxt,
|
||||
status&);
|
||||
@@ -97,6 +97,7 @@ read_corpus_from_elf(read_context& ctxt,
|
||||
corpus_sptr
|
||||
read_corpus_from_elf(const std::string& elf_path,
|
||||
char** debug_info_root_path,
|
||||
ir::environment* environment,
|
||||
bool load_all_types,
|
||||
status&);
|
||||
|
||||
@@ -129,13 +130,30 @@ bool
|
||||
get_type_of_elf_file(const string& path, elf_type& type);
|
||||
|
||||
|
||||
void
|
||||
set_debug_info_root_path(read_context& ctxt,
|
||||
char** path);
|
||||
|
||||
char**
|
||||
get_debug_info_root_path(read_context& ctxt,
|
||||
char**& path);
|
||||
|
||||
bool
|
||||
get_show_stats(read_context_sptr& ctxt);
|
||||
|
||||
void
|
||||
set_show_stats(read_context_sptr& ctxt,
|
||||
bool f);
|
||||
bool f);
|
||||
|
||||
void
|
||||
set_environment(read_context& ctxt,
|
||||
ir::environment*);
|
||||
|
||||
const environment_sptr&
|
||||
get_environment(const read_context& ctxt);
|
||||
|
||||
environment_sptr&
|
||||
get_environment(read_context& ctxt);
|
||||
}// end namespace dwarf_reader
|
||||
|
||||
}// end namespace abigail
|
||||
|
||||
+2
-1
@@ -77,6 +77,7 @@ namespace ir
|
||||
class corpus;
|
||||
|
||||
// Forward declarations for ir.
|
||||
class environment;
|
||||
class location;
|
||||
class location_manager;
|
||||
class translation_unit;
|
||||
@@ -662,7 +663,7 @@ string
|
||||
demangle_cplus_mangled_name(const string&);
|
||||
|
||||
shared_ptr<type_base>
|
||||
type_or_void(const shared_ptr<type_base>);
|
||||
type_or_void(const shared_ptr<type_base>, const environment*);
|
||||
|
||||
shared_ptr<type_base>
|
||||
canonicalize(shared_ptr<type_base>);
|
||||
|
||||
+132
-37
@@ -57,13 +57,13 @@
|
||||
/// abigail::type_base_sptr is added to the scope using the function
|
||||
/// abigail::add_decl_to_scope().
|
||||
///
|
||||
/// There is a kind of type that is usually not syntactically owned by a
|
||||
/// scope: it's function type. In libabigail function types are
|
||||
/// represented by abigail::function_type and abigail::method_type. These
|
||||
/// types must be owned by the translation unit they originate from.
|
||||
/// Adding them to the translation unit must be done by a call to the
|
||||
/// method function abigail::translation::get_canonical_function_type().
|
||||
/// The type returned by that function is the one to use.
|
||||
/// There is a kind of type that is usually not syntactically owned by
|
||||
/// a scope: it's function type. In libabigail, function types are
|
||||
/// represented by abigail::function_type and abigail::method_type.
|
||||
/// These types must be owned by the translation unit they originate
|
||||
/// from. Adding them to the translation unit must be done by a call
|
||||
/// to the method function
|
||||
/// abigail::translation::bind_function_type_life_time().
|
||||
///
|
||||
/// <b> A declaration that has a type does NOT own the type </b>
|
||||
///
|
||||
@@ -82,6 +82,12 @@
|
||||
/// Likewise, data members, function and template parameters similarly
|
||||
/// have weak pointers on their type.
|
||||
///
|
||||
/// If, for a reason, you really need to keep a type alive for the
|
||||
/// entire lifetime of the type system, then you can bind the life
|
||||
/// time of that type to the life time of the @ref environment that is
|
||||
/// supposed to outlive the type system. You do that by passing the
|
||||
/// type to the function environment::keep_type_alive().
|
||||
///
|
||||
/// @}
|
||||
|
||||
namespace abigail
|
||||
@@ -95,6 +101,69 @@ namespace ir
|
||||
// Inject some std::tr1 types in here.
|
||||
using std::tr1::unordered_map;
|
||||
|
||||
/// Convenience typedef for a shared pointer on a @ref type_base
|
||||
typedef shared_ptr<type_base> type_base_sptr;
|
||||
|
||||
/// Convenience typedef for a shared pointer on a @ref type_decl.
|
||||
typedef shared_ptr<type_decl> type_decl_sptr;
|
||||
|
||||
/// Convenience typedef for a shared pointer to an @ref environment
|
||||
typedef shared_ptr<environment> environment_sptr;
|
||||
|
||||
/// This is an abstraction of the set of resources necessary to manage
|
||||
/// several aspects of the internal representations of the Abigail
|
||||
/// library.
|
||||
///
|
||||
/// An environment can be seen as the boundaries in which all related
|
||||
/// Abigail artifacts live. So before doing anything using this
|
||||
/// library, the first thing to create is, well, you know it now, an
|
||||
/// environment.
|
||||
///
|
||||
/// Note that the lifetime of environment objects must be longer than
|
||||
/// the lifetime of any other type in the Abigail system. So a given
|
||||
/// instance of @ref environment must stay around as long as you are
|
||||
/// using libabigail. It's only when you are done using the library
|
||||
/// that you can de-allocate the environment instance.
|
||||
class environment
|
||||
{
|
||||
public:
|
||||
|
||||
// A convenience typedef for a map of canonical types. The a map
|
||||
/// entry key is the hash value of a particular type and the value
|
||||
/// is the list of canonical types that have the same hash value.
|
||||
typedef std::tr1::unordered_map<size_t,
|
||||
std::list<type_base_sptr> > canonical_types_map_type;
|
||||
|
||||
private:
|
||||
struct priv;
|
||||
typedef shared_ptr<priv> priv_sptr;
|
||||
|
||||
priv_sptr priv_;
|
||||
public:
|
||||
|
||||
environment();
|
||||
virtual ~environment();
|
||||
|
||||
canonical_types_map_type&
|
||||
get_canonical_types_map();
|
||||
|
||||
const type_decl_sptr&
|
||||
get_void_type_decl() const;
|
||||
|
||||
const type_decl_sptr&
|
||||
get_variadic_parameter_type_decl() const;
|
||||
|
||||
bool
|
||||
canonicalization_is_done() const;
|
||||
|
||||
void
|
||||
canonicalization_is_done(bool);
|
||||
|
||||
friend class class_decl;
|
||||
|
||||
friend void keep_type_alive(type_base_sptr);
|
||||
}; // end class environment
|
||||
|
||||
/// @brief The source location of a token.
|
||||
///
|
||||
/// This represents the location of a token coming from a given
|
||||
@@ -164,9 +233,6 @@ typedef shared_ptr<translation_unit> translation_unit_sptr;
|
||||
/// Convenience typedef for a vector of @ref translation_unit_sptr.
|
||||
typedef std::vector<translation_unit_sptr> translation_units;
|
||||
|
||||
/// Convenience typedef for a shared pointer on a @ref type_base
|
||||
typedef shared_ptr<type_base> type_base_sptr;
|
||||
|
||||
/// Convenience typedef for a weak pointer on a @ref type_base
|
||||
typedef weak_ptr<type_base> type_base_wptr;
|
||||
|
||||
@@ -255,11 +321,21 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
translation_unit(const std::string& path,
|
||||
char address_size = 0);
|
||||
translation_unit(const std::string& path,
|
||||
ir::environment* env,
|
||||
char address_size = 0);
|
||||
|
||||
virtual ~translation_unit();
|
||||
|
||||
const environment*
|
||||
get_environment() const;
|
||||
|
||||
environment*
|
||||
get_environment();
|
||||
|
||||
void
|
||||
set_environment(environment*);
|
||||
|
||||
language
|
||||
get_language() const;
|
||||
|
||||
@@ -719,8 +795,40 @@ typedef shared_ptr<type_or_decl_base> type_or_decl_base_sptr;
|
||||
/// The base class of both types and declarations.
|
||||
class type_or_decl_base : public ir_traversable_base
|
||||
{
|
||||
struct priv;
|
||||
typedef shared_ptr<priv> priv_sptr;
|
||||
mutable priv_sptr priv_;
|
||||
|
||||
protected:
|
||||
|
||||
size_t get_cached_hash_value() const;
|
||||
|
||||
void set_cached_hash_value(size_t) const;
|
||||
|
||||
bool hashing_started() const;
|
||||
|
||||
void hashing_started(bool) const;
|
||||
|
||||
public:
|
||||
|
||||
type_or_decl_base();
|
||||
|
||||
type_or_decl_base(const type_or_decl_base&);
|
||||
|
||||
virtual ~type_or_decl_base();
|
||||
|
||||
const environment*
|
||||
get_environment() const;
|
||||
|
||||
environment*
|
||||
get_environment();
|
||||
|
||||
void
|
||||
set_environment(environment*);
|
||||
|
||||
virtual bool
|
||||
traverse(ir_node_visitor&);
|
||||
|
||||
virtual string
|
||||
get_pretty_representation() const = 0;
|
||||
}; // end class type_or_decl_base
|
||||
@@ -731,6 +839,14 @@ operator==(const type_or_decl_base&, const type_or_decl_base&);
|
||||
bool
|
||||
operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&);
|
||||
|
||||
void
|
||||
set_environment_for_artifact(type_or_decl_base* artifact,
|
||||
environment* env);
|
||||
|
||||
void
|
||||
set_environment_for_artifact(type_or_decl_base_sptr artifact,
|
||||
environment* env);
|
||||
|
||||
/// The base type of all declarations.
|
||||
class decl_base : public virtual type_or_decl_base
|
||||
{
|
||||
@@ -740,15 +856,6 @@ class decl_base : public virtual type_or_decl_base
|
||||
protected:
|
||||
mutable priv_sptr priv_;
|
||||
|
||||
bool
|
||||
hashing_started() const;
|
||||
|
||||
void
|
||||
hashing_started(bool b) const;
|
||||
|
||||
size_t
|
||||
peek_hash_value() const;
|
||||
|
||||
const string&
|
||||
peek_qualified_name() const;
|
||||
|
||||
@@ -823,9 +930,6 @@ public:
|
||||
virtual const string&
|
||||
get_qualified_name() const;
|
||||
|
||||
void
|
||||
set_hash(size_t) const;
|
||||
|
||||
bool
|
||||
get_is_in_public_symbol_table() const;
|
||||
|
||||
@@ -962,7 +1066,8 @@ public:
|
||||
|
||||
scope_decl(const std::string& name, location locus,
|
||||
visibility vis = VISIBILITY_DEFAULT)
|
||||
: decl_base(name, locus, /*mangled_name=*/name, vis)
|
||||
: type_or_decl_base(),
|
||||
decl_base(name, locus, /*mangled_name=*/name, vis)
|
||||
{}
|
||||
|
||||
scope_decl(location l) : decl_base("", l)
|
||||
@@ -1074,7 +1179,6 @@ private:
|
||||
// Forbid this.
|
||||
type_base();
|
||||
|
||||
|
||||
static type_base_sptr
|
||||
get_canonical_type_for(type_base_sptr);
|
||||
|
||||
@@ -1127,8 +1231,8 @@ public:
|
||||
/// Hash functor for instances of @ref type_base.
|
||||
struct type_base::hash
|
||||
{
|
||||
size_t
|
||||
operator()(const type_base& t) const;
|
||||
size_t
|
||||
operator()(const type_base& t) const;
|
||||
|
||||
size_t
|
||||
operator()(const type_base* t) const;
|
||||
@@ -1180,9 +1284,6 @@ struct type_shared_ptr_equal
|
||||
bool
|
||||
equals(const type_decl&, const type_decl&, change_kind*);
|
||||
|
||||
/// Convenience typedef for a shared pointer on a @ref type_decl.
|
||||
typedef shared_ptr<type_decl> type_decl_sptr;
|
||||
|
||||
/// A basic type declaration that introduces no scope.
|
||||
class type_decl : public virtual decl_base, public virtual type_base
|
||||
{
|
||||
@@ -1199,12 +1300,6 @@ public:
|
||||
location locus, const std::string& mangled_name = "",
|
||||
visibility vis = VISIBILITY_DEFAULT);
|
||||
|
||||
static type_decl_sptr&
|
||||
get_void_type_decl();
|
||||
|
||||
static type_decl_sptr&
|
||||
get_variadic_parameter_type_decl();
|
||||
|
||||
virtual bool
|
||||
operator==(const type_base&) const;
|
||||
|
||||
|
||||
+12
-6
@@ -41,28 +41,34 @@ namespace xml_reader
|
||||
using namespace abigail::ir;
|
||||
|
||||
translation_unit_sptr
|
||||
read_translation_unit_from_file(const std::string& file_path);
|
||||
read_translation_unit_from_file(const std::string& file_path,
|
||||
environment* env);
|
||||
|
||||
translation_unit_sptr
|
||||
read_translation_unit_from_buffer(const std::string& file_path);
|
||||
read_translation_unit_from_buffer(const std::string& file_path,
|
||||
environment* env);
|
||||
|
||||
translation_unit_sptr
|
||||
read_translation_unit_from_istream(std::istream* in);
|
||||
read_translation_unit_from_istream(std::istream* in,
|
||||
environment* env);
|
||||
|
||||
abigail::corpus_sptr
|
||||
read_corpus_from_file(const string& path);
|
||||
|
||||
int
|
||||
read_corpus_from_file(corpus_sptr& corp, const string& path);
|
||||
read_corpus_from_file(corpus_sptr& corp,
|
||||
const string& path);
|
||||
|
||||
int
|
||||
read_corpus_from_file(corpus_sptr& corp);
|
||||
|
||||
corpus_sptr
|
||||
read_corpus_from_native_xml(std::istream* in);
|
||||
read_corpus_from_native_xml(std::istream* in,
|
||||
environment* env);
|
||||
|
||||
corpus_sptr
|
||||
read_corpus_from_native_xml_file(const string& path);
|
||||
read_corpus_from_native_xml_file(const string& path,
|
||||
environment* env);
|
||||
|
||||
}//end xml_reader
|
||||
}//end namespace abigail
|
||||
|
||||
+123
-3
@@ -6018,6 +6018,9 @@ compute_diff_for_decls(const decl_base_sptr first,
|
||||
/// Compute the difference between two decls. The decls can represent
|
||||
/// either type declarations, or non-type declaration.
|
||||
///
|
||||
/// Note that the two decls must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first the first decl to consider.
|
||||
///
|
||||
/// @param second the second decl to consider.
|
||||
@@ -6034,6 +6037,8 @@ compute_diff(const decl_base_sptr first,
|
||||
if (!first || !second)
|
||||
return diff_sptr();
|
||||
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
diff_sptr d;
|
||||
if (is_type(first) && is_type(second))
|
||||
d = compute_diff_for_types(first, second, ctxt);
|
||||
@@ -6045,6 +6050,9 @@ compute_diff(const decl_base_sptr first,
|
||||
|
||||
/// Compute the difference between two types.
|
||||
///
|
||||
/// Note that the two types must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first the first type to consider.
|
||||
///
|
||||
/// @param second the second type to consider.
|
||||
@@ -6060,6 +6068,10 @@ compute_diff(const type_base_sptr first,
|
||||
{
|
||||
decl_base_sptr f = get_type_declaration(first),
|
||||
s = get_type_declaration(second);
|
||||
|
||||
if (first && second)
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
diff_sptr d = compute_diff_for_types(f,s, ctxt);
|
||||
assert(d);
|
||||
return d;
|
||||
@@ -6708,6 +6720,9 @@ var_diff::report(ostream& out, const string& indent) const
|
||||
|
||||
/// Compute the diff between two instances of @ref var_decl.
|
||||
///
|
||||
/// Note that the two decls must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first the first @ref var_decl to consider for the diff.
|
||||
///
|
||||
/// @param second the second @ref var_decl to consider for the diff.
|
||||
@@ -6720,6 +6735,9 @@ compute_diff(const var_decl_sptr first,
|
||||
const var_decl_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
{
|
||||
if (first && second)
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
var_diff_sptr d(new var_diff(first, second, diff_sptr(), ctxt));
|
||||
ctxt->initialize_canonical_diff(d);
|
||||
return d;
|
||||
@@ -6921,6 +6939,9 @@ pointer_diff::report(ostream& out, const string& indent) const
|
||||
|
||||
/// Compute the diff between between two pointers.
|
||||
///
|
||||
/// Note that the two types must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first the pointer to consider for the diff.
|
||||
///
|
||||
/// @param second the pointer to consider for the diff.
|
||||
@@ -6933,6 +6954,9 @@ compute_diff(pointer_type_def_sptr first,
|
||||
pointer_type_def_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
{
|
||||
if (first && second)
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
diff_sptr d = compute_diff_for_types(first->get_pointed_to_type(),
|
||||
second->get_pointed_to_type(),
|
||||
ctxt);
|
||||
@@ -7111,6 +7135,9 @@ array_diff::report(ostream& out, const string& indent) const
|
||||
|
||||
/// Compute the diff between two arrays.
|
||||
///
|
||||
/// Note that the two types must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first the first array to consider for the diff.
|
||||
///
|
||||
/// @param second the second array to consider for the diff.
|
||||
@@ -7121,6 +7148,9 @@ compute_diff(array_type_def_sptr first,
|
||||
array_type_def_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
{
|
||||
if (first && second)
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
diff_sptr d = compute_diff_for_types(first->get_element_type(),
|
||||
second->get_element_type(),
|
||||
ctxt);
|
||||
@@ -7288,6 +7318,9 @@ reference_diff::report(ostream& out, const string& indent) const
|
||||
|
||||
/// Compute the diff between two references.
|
||||
///
|
||||
/// Note that the two types must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first the first reference to consider for the diff.
|
||||
///
|
||||
/// @param second the second reference to consider for the diff.
|
||||
@@ -7298,6 +7331,9 @@ compute_diff(reference_type_def_sptr first,
|
||||
reference_type_def_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
{
|
||||
if (first && second)
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
diff_sptr d = compute_diff_for_types(first->get_pointed_to_type(),
|
||||
second->get_pointed_to_type(),
|
||||
ctxt);
|
||||
@@ -7514,6 +7550,9 @@ qualified_type_diff::report(ostream& out, const string& indent) const
|
||||
|
||||
/// Compute the diff between two qualified types.
|
||||
///
|
||||
/// Note that the two types must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first the first qualified type to consider for the diff.
|
||||
///
|
||||
/// @param second the second qualified type to consider for the diff.
|
||||
@@ -7524,6 +7563,9 @@ compute_diff(const qualified_type_def_sptr first,
|
||||
const qualified_type_def_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
{
|
||||
if (first && second)
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
|
||||
second->get_underlying_type(),
|
||||
ctxt);
|
||||
@@ -7883,6 +7925,9 @@ enum_diff::report(ostream& out, const string& indent) const
|
||||
/// Compute the set of changes between two instances of @ref
|
||||
/// enum_type_decl.
|
||||
///
|
||||
/// Note that the two types must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first a pointer to the first enum_type_decl to consider.
|
||||
///
|
||||
/// @param second a pointer to the second enum_type_decl to consider.
|
||||
@@ -7896,6 +7941,9 @@ compute_diff(const enum_type_decl_sptr first,
|
||||
const enum_type_decl_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
{
|
||||
if (first && second)
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
diff_sptr ud = compute_diff_for_types(first->get_underlying_type(),
|
||||
second->get_underlying_type(),
|
||||
ctxt);
|
||||
@@ -9658,6 +9706,9 @@ class_diff::report(ostream& out, const string& indent) const
|
||||
|
||||
/// Compute the set of changes between two instances of class_decl.
|
||||
///
|
||||
/// Note that the two types must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first the first class_decl to consider.
|
||||
///
|
||||
/// @param second the second class_decl to consider.
|
||||
@@ -9670,6 +9721,9 @@ compute_diff(const class_decl_sptr first,
|
||||
const class_decl_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
{
|
||||
if (first && second)
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
class_decl_sptr f = look_through_decl_only_class(first),
|
||||
s = look_through_decl_only_class(second);
|
||||
|
||||
@@ -9931,6 +9985,9 @@ base_diff::report(ostream& out, const string& indent) const
|
||||
/// Constructs the diff object representing a diff between two base
|
||||
/// class specifications.
|
||||
///
|
||||
/// Note that the two artifacts must have been created in the same
|
||||
/// @ref environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first the first base class specification.
|
||||
///
|
||||
/// @param second the second base class specification.
|
||||
@@ -9943,6 +10000,9 @@ compute_diff(const class_decl::base_spec_sptr first,
|
||||
const class_decl::base_spec_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
{
|
||||
if (first && second)
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
class_diff_sptr cl = compute_diff(first->get_base_class(),
|
||||
second->get_base_class(),
|
||||
ctxt);
|
||||
@@ -10571,6 +10631,9 @@ scope_diff::report(ostream& out, const string& indent) const
|
||||
|
||||
/// Compute the diff between two scopes.
|
||||
///
|
||||
/// Note that the two decls must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first the first scope to consider in computing the diff.
|
||||
///
|
||||
/// @param second the second scope to consider in the diff
|
||||
@@ -10591,6 +10654,9 @@ compute_diff(const scope_decl_sptr first,
|
||||
{
|
||||
assert(d->first_scope() == first && d->second_scope() == second);
|
||||
|
||||
if (first && second)
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
compute_diff(first->get_member_decls().begin(),
|
||||
first->get_member_decls().end(),
|
||||
second->get_member_decls().begin(),
|
||||
@@ -10605,6 +10671,9 @@ compute_diff(const scope_decl_sptr first,
|
||||
|
||||
/// Compute the diff between two scopes.
|
||||
///
|
||||
/// Note that the two decls must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first_scope the first scope to consider in computing the diff.
|
||||
///
|
||||
/// @param second_scope the second scope to consider in the diff
|
||||
@@ -10618,6 +10687,10 @@ compute_diff(const scope_decl_sptr first_scope,
|
||||
const scope_decl_sptr second_scope,
|
||||
diff_context_sptr ctxt)
|
||||
{
|
||||
if (first_scope && second_scope)
|
||||
assert(first_scope->get_environment()
|
||||
== second_scope->get_environment());
|
||||
|
||||
scope_diff_sptr d(new scope_diff(first_scope, second_scope, ctxt));
|
||||
d = compute_diff(first_scope, second_scope, d, ctxt);
|
||||
ctxt->initialize_canonical_diff(d);
|
||||
@@ -10779,6 +10852,9 @@ fn_parm_diff::chain_into_hierarchy()
|
||||
/// that is, between two function parameters. Return a resulting
|
||||
/// fn_parm_diff_sptr that represents the changes.
|
||||
///
|
||||
/// Note that the two decls must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first the first subject of the diff.
|
||||
///
|
||||
/// @param second the second subject of the diff.
|
||||
@@ -10794,6 +10870,8 @@ compute_diff(const function_decl::parameter_sptr first,
|
||||
if (!first || !second)
|
||||
return fn_parm_diff_sptr();
|
||||
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
fn_parm_diff_sptr result(new fn_parm_diff(first, second, ctxt));
|
||||
ctxt->initialize_canonical_diff(result);
|
||||
|
||||
@@ -11189,6 +11267,9 @@ function_type_diff::chain_into_hierarchy()
|
||||
|
||||
/// Compute the diff between two instances of @ref function_type.
|
||||
///
|
||||
/// Note that the two types must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first the first @ref function_type to consider for the diff.
|
||||
///
|
||||
/// @param second the second @ref function_type to consider for the diff.
|
||||
@@ -11207,6 +11288,8 @@ compute_diff(const function_type_sptr first,
|
||||
return function_type_diff_sptr();
|
||||
}
|
||||
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
function_type_diff_sptr result(new function_type_diff(first, second, ctxt));
|
||||
|
||||
diff_utils::compute_diff(first->get_first_non_implicit_parm(),
|
||||
@@ -11672,6 +11755,9 @@ function_decl_diff::report(ostream& out, const string& indent) const
|
||||
|
||||
/// Compute the diff between two function_decl.
|
||||
///
|
||||
/// Note that the two decls must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first the first function_decl to consider for the diff
|
||||
///
|
||||
/// @param second the second function_decl to consider for the diff
|
||||
@@ -11690,6 +11776,8 @@ compute_diff(const function_decl_sptr first,
|
||||
return function_decl_diff_sptr();
|
||||
}
|
||||
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
function_type_diff_sptr type_diff = compute_diff(first->get_type(),
|
||||
second->get_type(),
|
||||
ctxt);
|
||||
@@ -11819,6 +11907,9 @@ type_decl_diff::report(ostream& out, const string& indent) const
|
||||
|
||||
/// Compute a diff between two type_decl.
|
||||
///
|
||||
/// Note that the two types must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// This function doesn't actually compute a diff. As a type_decl is
|
||||
/// very simple (unlike compound constructs like function_decl or
|
||||
/// class_decl) it's easy to just compare the components of the
|
||||
@@ -11840,6 +11931,9 @@ compute_diff(const type_decl_sptr first,
|
||||
const type_decl_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
{
|
||||
if (first && second)
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
type_decl_diff_sptr result(new type_decl_diff(first, second, ctxt));
|
||||
|
||||
// We don't need to actually compute a diff here as a type_decl
|
||||
@@ -12013,6 +12107,9 @@ typedef_diff::report(ostream& out, const string& indent) const
|
||||
|
||||
/// Compute a diff between two typedef_decl.
|
||||
///
|
||||
/// Note that the two types must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first a pointer to the first typedef_decl to consider.
|
||||
///
|
||||
/// @param second a pointer to the second typedef_decl to consider.
|
||||
@@ -12025,6 +12122,9 @@ compute_diff(const typedef_decl_sptr first,
|
||||
const typedef_decl_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
{
|
||||
if (first && second)
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
|
||||
second->get_underlying_type(),
|
||||
ctxt);
|
||||
@@ -12128,6 +12228,9 @@ translation_unit_diff::report(ostream& out, const string& indent) const
|
||||
|
||||
/// Compute the diff between two translation_units.
|
||||
///
|
||||
/// Note that the two translation units must have been created in the
|
||||
/// same @ref environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param first the first translation_unit to consider.
|
||||
///
|
||||
/// @param second the second translation_unit to consider.
|
||||
@@ -12141,6 +12244,10 @@ compute_diff(const translation_unit_sptr first,
|
||||
const translation_unit_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
{
|
||||
assert(first && second);
|
||||
|
||||
assert(first->get_environment() == second->get_environment());
|
||||
|
||||
if (!ctxt)
|
||||
ctxt.reset(new diff_context);
|
||||
|
||||
@@ -14909,7 +15016,10 @@ corpus_diff::traverse(diff_node_visitor& v)
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Compute the diff between two instances fo the @ref corpus
|
||||
/// Compute the diff between two instances of @ref corpus.
|
||||
///
|
||||
/// Note that the two corpora must have been created in the same @ref
|
||||
/// environment, otherwise, this function aborts.
|
||||
///
|
||||
/// @param f the first @ref corpus to consider for the diff.
|
||||
///
|
||||
@@ -14928,6 +15038,12 @@ compute_diff(const corpus_sptr f,
|
||||
typedef elf_symbols::const_iterator symbols_it_type;
|
||||
typedef diff_utils::deep_ptr_eq_functor eq_type;
|
||||
|
||||
assert(f && s);
|
||||
|
||||
// We can only compare two corpora that were built out of the same
|
||||
// environment.
|
||||
assert(f->get_environment() == s->get_environment());
|
||||
|
||||
if (!ctxt)
|
||||
ctxt.reset(new diff_context);
|
||||
|
||||
@@ -15920,11 +16036,15 @@ is_diff_of_variadic_parameter_type(const diff* d)
|
||||
return false;
|
||||
|
||||
type_base_sptr t = is_type(d->first_subject());
|
||||
if (t && t.get() == type_decl::get_variadic_parameter_type_decl().get())
|
||||
if (t
|
||||
&& (t.get()
|
||||
== t->get_environment()->get_variadic_parameter_type_decl().get()))
|
||||
return true;
|
||||
|
||||
t = is_type(d->second_subject());
|
||||
if (t && t.get() == type_decl::get_variadic_parameter_type_decl().get())
|
||||
if (t
|
||||
&& (t.get()
|
||||
== t->get_environment()->get_variadic_parameter_type_decl().get()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
+69
-34
@@ -750,38 +750,41 @@ corpus::exported_decls_builder::maybe_add_var_to_exported_vars(var_decl* var)
|
||||
|
||||
struct corpus::priv
|
||||
{
|
||||
corpus::exported_decls_builder_sptr exported_decls_builder;
|
||||
origin origin_;
|
||||
vector<string> regex_patterns_fns_to_suppress;
|
||||
vector<string> regex_patterns_vars_to_suppress;
|
||||
vector<string> regex_patterns_fns_to_keep;
|
||||
vector<string> regex_patterns_vars_to_keep;
|
||||
vector<string> sym_id_fns_to_keep;
|
||||
vector<string> sym_id_vars_to_keep;
|
||||
string path;
|
||||
vector<string> needed;
|
||||
string soname;
|
||||
string architecture_name;
|
||||
translation_units members;
|
||||
vector<function_decl*> fns;
|
||||
vector<var_decl*> vars;
|
||||
string_elf_symbols_map_sptr var_symbol_map;
|
||||
string_elf_symbols_map_sptr undefined_var_symbol_map;
|
||||
elf_symbols sorted_var_symbols;
|
||||
elf_symbols sorted_undefined_var_symbols;
|
||||
string_elf_symbols_map_sptr fun_symbol_map;
|
||||
string_elf_symbols_map_sptr undefined_fun_symbol_map;
|
||||
elf_symbols sorted_fun_symbols;
|
||||
elf_symbols sorted_undefined_fun_symbols;
|
||||
elf_symbols unrefed_fun_symbols;
|
||||
elf_symbols unrefed_var_symbols;
|
||||
environment* env;
|
||||
corpus::exported_decls_builder_sptr exported_decls_builder;
|
||||
origin origin_;
|
||||
vector<string> regex_patterns_fns_to_suppress;
|
||||
vector<string> regex_patterns_vars_to_suppress;
|
||||
vector<string> regex_patterns_fns_to_keep;
|
||||
vector<string> regex_patterns_vars_to_keep;
|
||||
vector<string> sym_id_fns_to_keep;
|
||||
vector<string> sym_id_vars_to_keep;
|
||||
string path;
|
||||
vector<string> needed;
|
||||
string soname;
|
||||
string architecture_name;
|
||||
translation_units members;
|
||||
vector<function_decl*> fns;
|
||||
vector<var_decl*> vars;
|
||||
string_elf_symbols_map_sptr var_symbol_map;
|
||||
string_elf_symbols_map_sptr undefined_var_symbol_map;
|
||||
elf_symbols sorted_var_symbols;
|
||||
elf_symbols sorted_undefined_var_symbols;
|
||||
string_elf_symbols_map_sptr fun_symbol_map;
|
||||
string_elf_symbols_map_sptr undefined_fun_symbol_map;
|
||||
elf_symbols sorted_fun_symbols;
|
||||
elf_symbols sorted_undefined_fun_symbols;
|
||||
elf_symbols unrefed_fun_symbols;
|
||||
elf_symbols unrefed_var_symbols;
|
||||
|
||||
private:
|
||||
priv();
|
||||
|
||||
public:
|
||||
priv(const string &p)
|
||||
: origin_(ARTIFICIAL_ORIGIN),
|
||||
priv(const string & p,
|
||||
environment* e)
|
||||
: env(e),
|
||||
origin_(ARTIFICIAL_ORIGIN),
|
||||
path(p)
|
||||
{}
|
||||
|
||||
@@ -1027,19 +1030,51 @@ corpus::priv::build_unreferenced_symbols_tables()
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructor of the @ref corpus type.
|
||||
///
|
||||
/// @param path the path to the file containing the ABI corpus.
|
||||
corpus::corpus(const string& path)
|
||||
{priv_.reset(new priv(path));}
|
||||
///
|
||||
/// @param env the environment of the corpus.
|
||||
corpus::corpus(const string& path, ir::environment* env)
|
||||
{priv_.reset(new priv(path, env));}
|
||||
|
||||
/// Add a translation unit to the current ABI Corpus. Next time
|
||||
/// corpus::save is called, all the translation unit that got added
|
||||
/// to the corpus are going to be serialized on disk in the file
|
||||
/// Getter of the enviroment of the corpus.
|
||||
///
|
||||
/// @return the environment of this corpus.
|
||||
const environment*
|
||||
corpus::get_environment() const
|
||||
{return priv_->env;}
|
||||
|
||||
/// Getter of the enviroment of the corpus.
|
||||
///
|
||||
/// @return the environment of this corpus.
|
||||
environment*
|
||||
corpus::get_environment()
|
||||
{return priv_->env;}
|
||||
|
||||
/// Setter of the environment of this corpus.
|
||||
///
|
||||
/// @param e the new environment.
|
||||
void
|
||||
corpus::set_environment(environment* e) const
|
||||
{priv_->env = e;}
|
||||
|
||||
/// Add a translation unit to the current ABI Corpus. Next time
|
||||
/// corpus::save is called, all the translation unit that got added to
|
||||
/// the corpus are going to be serialized on disk in the file
|
||||
/// associated to the current corpus.
|
||||
///
|
||||
/// @param tu the new translation unit to add.
|
||||
void
|
||||
corpus::add(const translation_unit_sptr tu)
|
||||
{priv_->members.push_back(tu);}
|
||||
{
|
||||
if (!tu->get_environment())
|
||||
tu->set_environment(get_environment());
|
||||
|
||||
assert(tu->get_environment() == get_environment());
|
||||
|
||||
priv_->members.push_back(tu);
|
||||
}
|
||||
|
||||
/// Return the list of translation units of the current corpus.
|
||||
///
|
||||
@@ -1076,7 +1111,7 @@ corpus::set_origin(origin o)
|
||||
/// the abi file expected at this path; likewise, a call to
|
||||
/// corpus::write will serialize the translation units contained in
|
||||
/// the corpus object into the on-disk file at this path.
|
||||
|
||||
///
|
||||
/// @return the file path associated to the current corpus.
|
||||
string&
|
||||
corpus::get_path() const
|
||||
|
||||
+163
-104
@@ -1713,7 +1713,9 @@ lookup_public_variable_symbol_from_elf(Elf* elf,
|
||||
/// get some important data from it.
|
||||
class read_context
|
||||
{
|
||||
environment* env_;
|
||||
unsigned short dwarf_version_;
|
||||
Dwfl_Callbacks offline_callbacks_;
|
||||
dwfl_sptr handle_;
|
||||
Dwarf* dwarf_;
|
||||
// The alternate debug info. Alternate debug info sections are a
|
||||
@@ -1778,16 +1780,16 @@ class read_context
|
||||
read_context();
|
||||
|
||||
public:
|
||||
read_context(dwfl_sptr handle,
|
||||
const string& elf_path)
|
||||
: dwarf_version_(0),
|
||||
handle_(handle),
|
||||
dwarf_(0),
|
||||
alt_dwarf_(0),
|
||||
elf_module_(0),
|
||||
elf_handle_(0),
|
||||
read_context(const string& elf_path)
|
||||
: env_(),
|
||||
dwarf_version_(),
|
||||
handle_(),
|
||||
dwarf_(),
|
||||
alt_dwarf_(),
|
||||
elf_module_(),
|
||||
elf_handle_(),
|
||||
elf_path_(elf_path),
|
||||
cur_tu_die_(0),
|
||||
cur_tu_die_(),
|
||||
symtab_section_(),
|
||||
symbol_versionning_sections_loaded_(),
|
||||
symbol_versionning_sections_found_(),
|
||||
@@ -1797,7 +1799,9 @@ public:
|
||||
exported_decls_builder_(),
|
||||
load_all_types_(),
|
||||
show_stats_()
|
||||
{}
|
||||
{
|
||||
memset(&offline_callbacks_, 0, sizeof(offline_callbacks_));
|
||||
}
|
||||
|
||||
/// Clear the data that is relevant only for the current translation
|
||||
/// unit being read. The rest of the data is relevant for the
|
||||
@@ -1808,7 +1812,6 @@ public:
|
||||
while (!scope_stack().empty())
|
||||
scope_stack().pop();
|
||||
var_decls_to_re_add_to_tree().clear();
|
||||
type_decl::get_void_type_decl()->set_scope(0);
|
||||
}
|
||||
|
||||
/// Clear the data that is relevant for the current corpus being
|
||||
@@ -1824,6 +1827,67 @@ public:
|
||||
types_to_canonicalize(/*in_alt_di=*/false).clear();
|
||||
}
|
||||
|
||||
/// Getter for the current environment.
|
||||
///
|
||||
/// @return the current environment.
|
||||
const ir::environment*
|
||||
env() const
|
||||
{return env_;}
|
||||
|
||||
/// Getter for the current environment.
|
||||
///
|
||||
/// @return the current environment.
|
||||
ir::environment*
|
||||
env()
|
||||
{return env_;}
|
||||
|
||||
/// Setter for the current environment.
|
||||
///
|
||||
/// @param env the new current environment.
|
||||
void
|
||||
env(ir::environment* env)
|
||||
{env_ = env;}
|
||||
|
||||
/// Getter for the callbacks of the Dwarf Front End library of
|
||||
/// elfutils that is used by this reader to read dwarf.
|
||||
///
|
||||
/// @return the callbacks.
|
||||
const Dwfl_Callbacks*
|
||||
offline_callbacks() const
|
||||
{return &offline_callbacks_;}
|
||||
|
||||
/// Getter for the callbacks of the Dwarf Front End library of
|
||||
/// elfutils that is used by this reader to read dwarf.
|
||||
/// @returnthe callbacks
|
||||
Dwfl_Callbacks*
|
||||
offline_callbacks()
|
||||
{return &offline_callbacks_;}
|
||||
|
||||
/// Constructor for a default Dwfl handle that knows how to load debug
|
||||
/// info from a library or executable elf file.
|
||||
///
|
||||
/// @param debug_info_root_path a pointer to the root path under which
|
||||
/// to look for the debug info of the elf files that are later handled
|
||||
/// by the Dwfl. This for cases where the debug info is split into a
|
||||
/// different file from the binary we want to inspect. On Red Hat
|
||||
/// compatible systems, this root path is usually /usr/lib/debug by
|
||||
/// default. If this argument is set to NULL, then "./debug" and
|
||||
/// /usr/lib/debug will be searched for sub-directories containing the
|
||||
/// debug info file. Note that for now, elfutils wants this path to
|
||||
/// be absolute otherwise things just don't work and the debug info is
|
||||
/// not found.
|
||||
///
|
||||
/// @return the constructed Dwfl handle.
|
||||
void
|
||||
create_default_dwfl(char** debug_info_root_path)
|
||||
{
|
||||
offline_callbacks()->find_debuginfo = dwfl_standard_find_debuginfo;
|
||||
offline_callbacks()->section_address = dwfl_offline_section_address;
|
||||
offline_callbacks()->debuginfo_path = debug_info_root_path;
|
||||
handle_.reset(dwfl_begin(offline_callbacks()),
|
||||
dwfl_deleter());
|
||||
}
|
||||
|
||||
unsigned short
|
||||
dwarf_version() const
|
||||
{return dwarf_version_;}
|
||||
@@ -1832,10 +1896,22 @@ public:
|
||||
dwarf_version(unsigned short v)
|
||||
{dwarf_version_ = v;}
|
||||
|
||||
/// Getter for a smart pointer to a handle on the dwarf front end
|
||||
/// library that we use to read dwarf.
|
||||
///
|
||||
/// @return the dwfl handle.
|
||||
dwfl_sptr
|
||||
dwfl_handle() const
|
||||
{return handle_;}
|
||||
|
||||
/// Setter for a smart pointer to a handle on the dwarf front end
|
||||
/// library that we use to read dwarf.
|
||||
///
|
||||
/// @param h the new dwfl handle.
|
||||
void
|
||||
dwfl_handle(dwfl_sptr& h)
|
||||
{handle_ = h;}
|
||||
|
||||
Dwfl_Module*
|
||||
elf_module() const
|
||||
{return elf_module_;}
|
||||
@@ -3706,6 +3782,28 @@ finish_member_function_reading(Dwarf_Die* die,
|
||||
function_decl_sptr f,
|
||||
class_decl_sptr klass);
|
||||
|
||||
/// Setter of the debug info root path for a dwarf reader context.
|
||||
///
|
||||
/// @param ctxt the dwarf reader context to consider.
|
||||
///
|
||||
/// @param path the new debug info root path. This must be a pointer to a
|
||||
/// character string which life time should be greater than the life
|
||||
/// time of the read context.
|
||||
void
|
||||
set_debug_info_root_path(read_context& ctxt, char** path)
|
||||
{ctxt.offline_callbacks()->debuginfo_path = path;}
|
||||
|
||||
/// Setter of the debug info root path for a dwarf reader context.
|
||||
///
|
||||
/// @param ctxt the dwarf reader context to consider.
|
||||
///
|
||||
/// @return a pointer to the the debug info root path.
|
||||
///
|
||||
/// time of the read context.
|
||||
char**
|
||||
get_debug_info_root_path(read_context& ctxt)
|
||||
{return ctxt.offline_callbacks()->debuginfo_path;}
|
||||
|
||||
/// Getter of the "show_stats" flag.
|
||||
///
|
||||
/// This flag tells if we should emit statistics about various
|
||||
@@ -3715,12 +3813,8 @@ finish_member_function_reading(Dwarf_Die* die,
|
||||
///
|
||||
/// @return the value of the flag.
|
||||
bool
|
||||
get_show_stats(read_context_sptr& ctxt)
|
||||
{
|
||||
if(!ctxt)
|
||||
return false;
|
||||
return ctxt->show_stats();
|
||||
}
|
||||
get_show_stats(read_context& ctxt)
|
||||
{return ctxt.show_stats();}
|
||||
|
||||
/// Setter of the "show_stats" flag.
|
||||
///
|
||||
@@ -3731,68 +3825,8 @@ get_show_stats(read_context_sptr& ctxt)
|
||||
///
|
||||
/// @param f the value of the flag.
|
||||
void
|
||||
set_show_stats(read_context_sptr& ctxt,
|
||||
bool f)
|
||||
{
|
||||
if (ctxt)
|
||||
ctxt->show_stats(f);
|
||||
}
|
||||
|
||||
/// Constructor for a default Dwfl handle that knows how to load debug
|
||||
/// info from a library or executable elf file.
|
||||
///
|
||||
/// @param debug_info_root_path a pointer to the root path under which
|
||||
/// to look for the debug info of the elf files that are later handled
|
||||
/// by the Dwfl. This for cases where the debug info is split into a
|
||||
/// different file from the binary we want to inspect. On Red Hat
|
||||
/// compatible systems, this root path is usually /usr/lib/debug by
|
||||
/// default. If this argument is set to NULL, then "./debug" and
|
||||
/// /usr/lib/debug will be searched for sub-directories containing the
|
||||
/// debug info file. Note that for now, elfutils wants this path to
|
||||
/// be absolute otherwise things just don't work and the debug info is
|
||||
/// not found.
|
||||
///
|
||||
/// @return the constructed Dwfl handle.
|
||||
static Dwfl*
|
||||
create_default_dwfl(char** debug_info_root_path)
|
||||
{
|
||||
static Dwfl_Callbacks offline_callbacks;
|
||||
|
||||
memset(&offline_callbacks, 0, sizeof(offline_callbacks));
|
||||
offline_callbacks.find_debuginfo = dwfl_standard_find_debuginfo;
|
||||
offline_callbacks.section_address = dwfl_offline_section_address;
|
||||
offline_callbacks.debuginfo_path = debug_info_root_path;
|
||||
return dwfl_begin(&offline_callbacks);
|
||||
}
|
||||
|
||||
/// Create a shared pointer for a pointer to Dwfl.
|
||||
///
|
||||
/// @param dwfl the pointer to Dwfl to create the shared pointer for.
|
||||
///
|
||||
/// @return the newly created shared pointer.
|
||||
static dwfl_sptr
|
||||
create_dwfl_sptr(Dwfl* dwfl)
|
||||
{
|
||||
dwfl_sptr result(dwfl, dwfl_deleter());
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Create a shared pointer to a default Dwfl handle. This uses the
|
||||
/// create_default_dwfl() function.
|
||||
///
|
||||
/// @param di_path a pointer to the root path under which to look for
|
||||
/// the debug info of the elf files that are later handled by the
|
||||
/// Dwfl. This for cases where the debug info is split into a
|
||||
/// different file from the binary we want to inspect. On Red Hat
|
||||
/// compatible systems, this root path is usually /usr/lib/debug by
|
||||
/// default. If this argument is set to NULL, then "./debug" and
|
||||
/// /usr/lib/debug will be searched for sub-directories containing the
|
||||
/// debug info file.
|
||||
///
|
||||
/// @return the created shared pointer.
|
||||
static dwfl_sptr
|
||||
create_default_dwfl_sptr(char** di_path)
|
||||
{return create_dwfl_sptr(create_default_dwfl(di_path));}
|
||||
set_show_stats(read_context& ctxt, bool f)
|
||||
{ctxt.show_stats(f);}
|
||||
|
||||
/// Get the value of an attribute that is supposed to be a string, or
|
||||
/// an empty string if the attribute could not be found.
|
||||
@@ -6059,7 +6093,9 @@ build_translation_unit_and_add_to_ir(read_context& ctxt,
|
||||
ctxt.cur_tu_die(die);
|
||||
|
||||
string path = die_string_attribute(die, DW_AT_name);
|
||||
result.reset(new translation_unit(path, address_size));
|
||||
result.reset(new translation_unit(path,
|
||||
ctxt.env(),
|
||||
address_size));
|
||||
|
||||
size_t l = 0;
|
||||
die_unsigned_constant_attribute(die, DW_AT_language, l);
|
||||
@@ -6756,8 +6792,8 @@ build_qualified_type(read_context& ctxt,
|
||||
/// Strip qualification from a qualified type, when it makes sense.
|
||||
///
|
||||
/// DWARF constructs "const reference". This is redundant because a
|
||||
/// reference is always const. The issue is these redundant type then
|
||||
/// leaks into the IR and makes for bad diagnostics.
|
||||
/// reference is always const. The issue is these redundant types then
|
||||
/// leak into the IR and make for bad diagnostics.
|
||||
///
|
||||
/// This function thus strips the const qualifier from the type in
|
||||
/// that case. It might contain code to strip other cases like this
|
||||
@@ -7329,8 +7365,9 @@ build_function_decl(read_context& ctxt,
|
||||
{
|
||||
// This is a variadic function parameter.
|
||||
bool is_artificial = die_is_artificial(&child);
|
||||
type_decl_sptr parm_type =
|
||||
type_decl::get_variadic_parameter_type_decl();
|
||||
ir::environment* env = ctxt.env();
|
||||
assert(env);
|
||||
type_decl_sptr parm_type = env->get_variadic_parameter_type_decl();
|
||||
function_decl::parameter_sptr p
|
||||
(new function_decl::parameter(parm_type,
|
||||
/*name=*/"",
|
||||
@@ -7396,8 +7433,6 @@ build_function_decl(read_context& ctxt,
|
||||
is_in_alt_di,
|
||||
result->get_type());
|
||||
|
||||
maybe_canonicalize_type(dwarf_dieoffset(die), is_in_alt_di, ctxt);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -7416,8 +7451,10 @@ read_debug_info_into_corpus(read_context& ctxt)
|
||||
|
||||
if (!ctxt.current_corpus())
|
||||
{
|
||||
corpus_sptr corp (new corpus(ctxt.elf_path()));
|
||||
corpus_sptr corp (new corpus(ctxt.elf_path(), ctxt.env()));
|
||||
ctxt.current_corpus(corp);
|
||||
if (!ctxt.env())
|
||||
ctxt.env(corp->get_environment());
|
||||
}
|
||||
|
||||
if (!ctxt.dwarf())
|
||||
@@ -8046,7 +8083,9 @@ build_ir_node_from_die(read_context& ctxt,
|
||||
static decl_base_sptr
|
||||
build_ir_node_for_void_type(read_context& ctxt)
|
||||
{
|
||||
decl_base_sptr t = type_decl::get_void_type_decl();
|
||||
ir::environment* env = ctxt.env();
|
||||
assert(env);
|
||||
decl_base_sptr t = env->get_void_type_decl();
|
||||
if (!has_scope(t))
|
||||
add_decl_to_scope(t, ctxt.cur_tu()->get_global_scope());
|
||||
canonicalize(is_type(t));
|
||||
@@ -8134,6 +8173,17 @@ operator&=(status& l, status r)
|
||||
/// debug info is to be found for @p elf_path. Leave this to NULL if
|
||||
/// the debug info is not in a split file.
|
||||
///
|
||||
/// @param environment the environment used by the current context.
|
||||
/// This environment contains resources needed by the reader and by
|
||||
/// the types and declarations that are to be created later. Note
|
||||
/// that ABI artifacts that are to be compared all need to be created
|
||||
/// within the same environment.
|
||||
///
|
||||
/// Please also note that the life time of this environment object
|
||||
/// must be greater than the life time of the resulting @ref
|
||||
/// read_context the context uses resources that are allocated in the
|
||||
/// environment.
|
||||
///
|
||||
/// @param load_all_types if set to false only the types that are
|
||||
/// reachable from publicly exported declarations (of functions and
|
||||
/// variables) are read. If set to true then all types found in the
|
||||
@@ -8141,15 +8191,17 @@ operator&=(status& l, status r)
|
||||
///
|
||||
/// @return a smart pointer to the resulting dwarf_reader::read_context.
|
||||
read_context_sptr
|
||||
create_read_context(const std::string& elf_path,
|
||||
char** debug_info_root_path,
|
||||
bool load_all_types)
|
||||
create_read_context(const std::string& elf_path,
|
||||
char** debug_info_root_path,
|
||||
ir::environment* environment,
|
||||
bool load_all_types)
|
||||
{
|
||||
// Create a DWARF Front End Library handle to be used by functions
|
||||
// of that library.
|
||||
dwfl_sptr handle = create_default_dwfl_sptr(debug_info_root_path);
|
||||
read_context_sptr result(new read_context(handle, elf_path));
|
||||
read_context_sptr result(new read_context(elf_path));
|
||||
result->create_default_dwfl(debug_info_root_path);
|
||||
result->load_all_types(load_all_types);
|
||||
result->env(environment);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -8214,6 +8266,15 @@ read_corpus_from_elf(read_context& ctxt, status& status)
|
||||
/// /usr/lib/debug will be searched for sub-directories containing the
|
||||
/// debug info file.
|
||||
///
|
||||
/// @param environment the environment used by the current context.
|
||||
/// This environment contains resources needed by the reader and by
|
||||
/// the types and declarations that are to be created later. Note
|
||||
/// that ABI artifacts that are to be compared all need to be created
|
||||
/// within the same environment. Also, the lifetime of the
|
||||
/// environment must be greater than the lifetime of the resulting
|
||||
/// corpus because the corpus uses resources that are allocated in the
|
||||
/// environment.
|
||||
///
|
||||
/// @param load_all_types if set to false only the types that are
|
||||
/// reachable from publicly exported declarations (of functions and
|
||||
/// variables) are read. If set to true then all types found in the
|
||||
@@ -8224,18 +8285,16 @@ read_corpus_from_elf(read_context& ctxt, status& status)
|
||||
/// @return the resulting status.
|
||||
corpus_sptr
|
||||
read_corpus_from_elf(const std::string& elf_path,
|
||||
char** debug_info_root_path,
|
||||
bool load_all_types,
|
||||
status& status)
|
||||
char** debug_info_root_path,
|
||||
ir::environment* environment,
|
||||
bool load_all_types,
|
||||
status& status)
|
||||
{
|
||||
// Create a DWARF Front End Library handle to be used by functions
|
||||
// of that library.
|
||||
dwfl_sptr handle = create_default_dwfl_sptr(debug_info_root_path);
|
||||
|
||||
read_context_sptr c = create_read_context(elf_path, debug_info_root_path);
|
||||
c->load_all_types(load_all_types);
|
||||
read_context_sptr c = create_read_context(elf_path,
|
||||
debug_info_root_path,
|
||||
environment,
|
||||
load_all_types);
|
||||
read_context& ctxt = *c;
|
||||
|
||||
return read_corpus_from_elf(ctxt, status);
|
||||
}
|
||||
|
||||
@@ -8390,7 +8449,7 @@ has_alt_debug_info(const string& elf_path,
|
||||
bool& has_alt_di,
|
||||
string& alt_debug_info_path)
|
||||
{
|
||||
read_context_sptr c = create_read_context(elf_path, debug_info_root_path);
|
||||
read_context_sptr c = create_read_context(elf_path, debug_info_root_path, 0);
|
||||
read_context& ctxt = *c;
|
||||
|
||||
// Load debug info from the elf path.
|
||||
|
||||
+9
-18
@@ -145,18 +145,15 @@ struct type_decl::hash
|
||||
size_t
|
||||
scope_decl::hash::operator()(const scope_decl& d) const
|
||||
{
|
||||
if (d.peek_hash_value() == 0 || d.hashing_started())
|
||||
{
|
||||
std::tr1::hash<string> hash_string;
|
||||
size_t v = hash_string(typeid(d).name());
|
||||
for (scope_decl::declarations::const_iterator i =
|
||||
d.get_member_decls().begin();
|
||||
i != d.get_member_decls().end();
|
||||
++i)
|
||||
v = hashing::combine_hashes(v, (*i)->get_hash());
|
||||
d.set_hash(v);
|
||||
}
|
||||
return d.peek_hash_value();
|
||||
std::tr1::hash<string> hash_string;
|
||||
size_t v = hash_string(typeid(d).name());
|
||||
for (scope_decl::declarations::const_iterator i =
|
||||
d.get_member_decls().begin();
|
||||
i != d.get_member_decls().end();
|
||||
++i)
|
||||
v = hashing::combine_hashes(v, (*i)->get_hash());
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/// Hashing operator for the @ref scope_decl type.
|
||||
@@ -375,9 +372,6 @@ var_decl::hash::operator()(const var_decl* t) const
|
||||
size_t
|
||||
function_decl::hash::operator()(const function_decl& t) const
|
||||
{
|
||||
if (t.peek_hash_value() != 0)
|
||||
return t.peek_hash_value();
|
||||
|
||||
std::tr1::hash<int> hash_int;
|
||||
std::tr1::hash<size_t> hash_size_t;
|
||||
std::tr1::hash<bool> hash_bool;
|
||||
@@ -406,9 +400,6 @@ function_decl::hash::operator()(const function_decl& t) const
|
||||
v = hashing::combine_hashes(v, hash_size_t(voffset));
|
||||
}
|
||||
|
||||
if (t.get_type() && (t.get_type()->get_canonical_type() != 0))
|
||||
t.set_hash(v);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
+439
-263
File diff suppressed because it is too large
Load Diff
+60
-20
@@ -96,6 +96,7 @@ public:
|
||||
typedef unordered_map<xmlNodePtr, decl_base_sptr> xml_node_decl_base_sptr_map;
|
||||
|
||||
private:
|
||||
environment* m_env;
|
||||
unordered_map<string, vector<type_base_sptr> > m_types_map;
|
||||
unordered_map<string, shared_ptr<function_tdecl> > m_fn_tmpl_map;
|
||||
unordered_map<string, shared_ptr<class_tdecl> > m_class_tmpl_map;
|
||||
@@ -112,12 +113,35 @@ private:
|
||||
read_context();
|
||||
|
||||
public:
|
||||
read_context(xml::reader_sptr reader)
|
||||
: m_reader(reader),
|
||||
read_context(xml::reader_sptr reader,
|
||||
environment* env)
|
||||
: m_env(env),
|
||||
m_reader(reader),
|
||||
m_corp_node(),
|
||||
m_exported_decls_builder_()
|
||||
{}
|
||||
|
||||
/// Getter for the environment of this reader.
|
||||
///
|
||||
/// @return the environment of this reader.
|
||||
const environment*
|
||||
get_environment() const
|
||||
{return m_env;}
|
||||
|
||||
/// Getter for the environment of this reader.
|
||||
///
|
||||
/// @return the environment of this reader.
|
||||
environment*
|
||||
get_environment()
|
||||
{return m_env;}
|
||||
|
||||
/// Setter for the environment of this reader.
|
||||
///
|
||||
/// @param env the environment of this reader.
|
||||
void
|
||||
set_environment(environment* env)
|
||||
{m_env = env;}
|
||||
|
||||
xml::reader_sptr
|
||||
get_reader() const
|
||||
{return m_reader;}
|
||||
@@ -1085,7 +1109,7 @@ read_translation_unit(read_context& ctxt, xmlNodePtr node)
|
||||
|
||||
ctxt.set_corpus_node(node);
|
||||
|
||||
tu.reset(new translation_unit(""));
|
||||
tu.reset(new translation_unit("", ctxt.get_environment()));
|
||||
|
||||
xml::xml_char_sptr addrsize_str =
|
||||
XML_NODE_GET_ATTRIBUTE(node, "address-size");
|
||||
@@ -1422,7 +1446,7 @@ read_corpus_from_input(read_context& ctxt)
|
||||
|
||||
if (!ctxt.get_corpus())
|
||||
{
|
||||
corpus_sptr c(new corpus(""));
|
||||
corpus_sptr c(new corpus("", ctxt.get_environment()));
|
||||
ctxt.set_corpus(c);
|
||||
}
|
||||
|
||||
@@ -1498,12 +1522,15 @@ read_corpus_from_input(read_context& ctxt)
|
||||
/// @param input_file a path to the file containing the xml document
|
||||
/// to parse.
|
||||
///
|
||||
/// @param env the environment to use.
|
||||
///
|
||||
/// @return the translation unit resulting from the parsing upon
|
||||
/// successful completion, or nil.
|
||||
translation_unit_sptr
|
||||
read_translation_unit_from_file(const string& input_file)
|
||||
read_translation_unit_from_file(const string& input_file,
|
||||
environment* env)
|
||||
{
|
||||
read_context read_ctxt(xml::new_reader_from_file(input_file));
|
||||
read_context read_ctxt(xml::new_reader_from_file(input_file), env);
|
||||
return read_translation_unit_from_input(read_ctxt);
|
||||
}
|
||||
|
||||
@@ -1513,12 +1540,15 @@ read_translation_unit_from_file(const string& input_file)
|
||||
/// @param buffer the in-memory buffer containing the xml document to
|
||||
/// parse.
|
||||
///
|
||||
/// @param env the environment to use.
|
||||
///
|
||||
/// @return the translation unit resulting from the parsing upon
|
||||
/// successful completion, or nil.
|
||||
translation_unit_sptr
|
||||
read_translation_unit_from_buffer(const string& buffer)
|
||||
read_translation_unit_from_buffer(const string& buffer,
|
||||
environment* env)
|
||||
{
|
||||
read_context read_ctxt(xml::new_reader_from_buffer(buffer));
|
||||
read_context read_ctxt(xml::new_reader_from_buffer(buffer), env);
|
||||
return read_translation_unit_from_input(read_ctxt);
|
||||
}
|
||||
|
||||
@@ -2206,6 +2236,8 @@ build_function_parameter(read_context& ctxt, const xmlNodePtr node)
|
||||
if (!node || !xmlStrEqual(node->name, BAD_CAST("parameter")))
|
||||
return nil;
|
||||
|
||||
assert(ctxt.get_environment());
|
||||
|
||||
bool is_variadic = false;
|
||||
string is_variadic_str;
|
||||
if (xml_char_sptr s =
|
||||
@@ -2230,7 +2262,7 @@ build_function_parameter(read_context& ctxt, const xmlNodePtr node)
|
||||
|
||||
shared_ptr<type_base> type;
|
||||
if (is_variadic)
|
||||
type = type_decl::get_variadic_parameter_type_decl();
|
||||
type = ctxt.get_environment()->get_variadic_parameter_type_decl();
|
||||
else
|
||||
{
|
||||
assert(!type_id.empty());
|
||||
@@ -4077,12 +4109,14 @@ handle_class_tdecl(read_context& ctxt,
|
||||
///
|
||||
/// @param in a pointer to the input stream.
|
||||
///
|
||||
/// @param env the environment to use.
|
||||
///
|
||||
/// @return the translation unit resulting from the parsing upon
|
||||
/// successful completion, or nil.
|
||||
translation_unit_sptr
|
||||
read_translation_unit_from_istream(istream* in)
|
||||
read_translation_unit_from_istream(istream* in, environment* env)
|
||||
{
|
||||
read_context read_ctxt(xml::new_reader_from_istream(in));
|
||||
read_context read_ctxt(xml::new_reader_from_istream(in), env);
|
||||
return read_translation_unit_from_input(read_ctxt);
|
||||
}
|
||||
template<typename T>
|
||||
@@ -4245,16 +4279,19 @@ read_corpus_from_file(const string& path)
|
||||
///
|
||||
/// @param in the input stream to read the XML document from.
|
||||
///
|
||||
/// @param corp the corpus de-serialized from the parsing. This is
|
||||
/// set iff the function returns true.
|
||||
/// @param env the environment to use. Note that the life time of
|
||||
/// this environment must be greater than the lifetime of the
|
||||
/// resulting corpus as the corpus uses resources that are allocated
|
||||
/// in the environment.
|
||||
///
|
||||
/// @return the resulting corpus de-serialized from the parsing. This
|
||||
/// is non-null iff the parsing resulted in a valid corpus.
|
||||
corpus_sptr
|
||||
read_corpus_from_native_xml(std::istream* in)
|
||||
read_corpus_from_native_xml(std::istream* in,
|
||||
environment* env)
|
||||
{
|
||||
read_context read_ctxt(xml::new_reader_from_istream(in));
|
||||
corpus_sptr corp(new corpus(""));
|
||||
read_context read_ctxt(xml::new_reader_from_istream(in), env);
|
||||
corpus_sptr corp(new corpus("", read_ctxt.get_environment()));
|
||||
read_ctxt.set_corpus(corp);
|
||||
return read_corpus_from_input(read_ctxt);
|
||||
}
|
||||
@@ -4265,15 +4302,18 @@ read_corpus_from_native_xml(std::istream* in)
|
||||
/// @param path the path to the input file to read the XML document
|
||||
/// from.
|
||||
///
|
||||
/// @param corp the corpus de-serialized from the parsing. This is
|
||||
/// set iff the function returns true.
|
||||
/// @param env the environment to use. Note that the life time of
|
||||
/// this environment must be greater than the lifetime of the
|
||||
/// resulting corpus as the corpus uses resources that are allocated
|
||||
/// in the environment.
|
||||
///
|
||||
/// @return the resulting corpus de-serialized from the parsing. This
|
||||
/// is non-null if the parsing successfully resulted in a corpus.
|
||||
corpus_sptr
|
||||
read_corpus_from_native_xml_file(const string& path)
|
||||
read_corpus_from_native_xml_file(const string& path,
|
||||
environment* env)
|
||||
{
|
||||
read_context read_ctxt(xml::new_reader_from_file(path));
|
||||
read_context read_ctxt(xml::new_reader_from_file(path), env);
|
||||
corpus_sptr corp = read_corpus_from_input(read_ctxt);
|
||||
if (corp)
|
||||
{
|
||||
|
||||
@@ -33,6 +33,8 @@ using std::string;
|
||||
|
||||
using abigail::comparison::diff;
|
||||
using abigail::comparison::diff_sptr;
|
||||
using abigail::ir::environment;
|
||||
using abigail::ir::environment_sptr;
|
||||
using abigail::comparison::corpus_diff_sptr;
|
||||
using abigail::comparison::compute_diff;
|
||||
using abigail::comparison::print_diff_tree;
|
||||
@@ -118,7 +120,8 @@ main(int argc, char* argv[])
|
||||
dwarf_reader::status c1_status, c2_status;
|
||||
corpus_sptr c1, c2;
|
||||
|
||||
c1 = dwarf_reader::read_corpus_from_elf(opts.elf1, 0,
|
||||
environment_sptr env(new environment);
|
||||
c1 = dwarf_reader::read_corpus_from_elf(opts.elf1, 0, env.get(),
|
||||
/*load_all_types=*/false,
|
||||
c1_status);
|
||||
if (c1_status != dwarf_reader::STATUS_OK)
|
||||
@@ -127,7 +130,7 @@ main(int argc, char* argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
c2 = dwarf_reader::read_corpus_from_elf(opts.elf2, 0,
|
||||
c2 = dwarf_reader::read_corpus_from_elf(opts.elf2, 0, env.get(),
|
||||
/*load_all_types=*/false,
|
||||
c2_status);
|
||||
if (c2_status != dwarf_reader::STATUS_OK)
|
||||
|
||||
@@ -114,6 +114,8 @@ using std::ofstream;
|
||||
using abigail::tools_utils::file_type;
|
||||
using abigail::tools_utils::check_file;
|
||||
using abigail::tools_utils::guess_file_type;
|
||||
using abigail::ir::environment;
|
||||
using abigail::ir::environment_sptr;
|
||||
using abigail::corpus_sptr;
|
||||
using abigail::translation_unit;
|
||||
using abigail::translation_unit_sptr;
|
||||
@@ -154,13 +156,14 @@ main(int, char*[])
|
||||
continue;
|
||||
}
|
||||
|
||||
environment_sptr env(new environment);
|
||||
translation_unit_sptr tu1, tu2;
|
||||
corpus_sptr corpus1, corpus2;
|
||||
file_type t = guess_file_type(first_in_path);
|
||||
if (t == abigail::tools_utils::FILE_TYPE_NATIVE_BI)
|
||||
tu1 = read_translation_unit_from_file(first_in_path);
|
||||
tu1 = read_translation_unit_from_file(first_in_path, env.get());
|
||||
else if (t == abigail::tools_utils::FILE_TYPE_XML_CORPUS)
|
||||
corpus1 = read_corpus_from_native_xml_file(first_in_path);
|
||||
corpus1 = read_corpus_from_native_xml_file(first_in_path, env.get());
|
||||
else
|
||||
abort();
|
||||
if (!tu1 && !corpus1)
|
||||
@@ -172,9 +175,9 @@ main(int, char*[])
|
||||
|
||||
t = guess_file_type(second_in_path);
|
||||
if (t == abigail::tools_utils::FILE_TYPE_NATIVE_BI)
|
||||
tu2 = read_translation_unit_from_file(second_in_path);
|
||||
tu2 = read_translation_unit_from_file(second_in_path, env.get());
|
||||
else if (t == abigail::tools_utils::FILE_TYPE_XML_CORPUS)
|
||||
corpus2 = read_corpus_from_native_xml_file(second_in_path);
|
||||
corpus2 = read_corpus_from_native_xml_file(second_in_path, env.get());
|
||||
else
|
||||
abort();
|
||||
if (!tu2 && !corpus2)
|
||||
|
||||
@@ -267,6 +267,8 @@ main()
|
||||
using abigail::dwarf_reader::read_corpus_from_elf;
|
||||
using abigail::comparison::compute_diff;
|
||||
using abigail::comparison::corpus_diff_sptr;
|
||||
using abigail::ir::environment;
|
||||
using abigail::ir::environment_sptr;
|
||||
|
||||
bool is_ok = true;
|
||||
string in_elfv0_path, in_elfv1_path,
|
||||
@@ -289,15 +291,18 @@ main()
|
||||
abigail::dwarf_reader::status status =
|
||||
abigail::dwarf_reader::STATUS_UNKNOWN;
|
||||
|
||||
environment_sptr env(new environment);
|
||||
abigail::corpus_sptr corp0 =
|
||||
read_corpus_from_elf(in_elfv0_path,
|
||||
/*debug_info_root_path=*/0,
|
||||
env.get(),
|
||||
/*load_all_types=*/false,
|
||||
status);
|
||||
|
||||
abigail::corpus_sptr corp1 =
|
||||
read_corpus_from_elf(in_elfv1_path,
|
||||
/*debug_info_root_path=*/0,
|
||||
env.get(),
|
||||
/*load_all_types=*/false,
|
||||
status);
|
||||
|
||||
|
||||
@@ -136,8 +136,10 @@ main(int argc, char **argv)
|
||||
|
||||
string file_name = argv[1];
|
||||
|
||||
abigail::ir::environment_sptr env(new abigail::ir::environment);
|
||||
abigail::translation_unit_sptr tu;
|
||||
if (!(tu = abigail::xml_reader::read_translation_unit_from_file(file_name)))
|
||||
if (!(tu = abigail::xml_reader::read_translation_unit_from_file(file_name,
|
||||
env.get())))
|
||||
{
|
||||
cerr << "failed to read " << file_name << "\n";
|
||||
return 1;
|
||||
|
||||
@@ -143,21 +143,25 @@ InOutSpec in_out_specs[] =
|
||||
int
|
||||
main()
|
||||
{
|
||||
using abigail::dwarf_reader::read_corpus_from_elf;
|
||||
unsigned result = 1;
|
||||
|
||||
bool is_ok = true;
|
||||
string in_elf_path, in_abi_path, out_abi_path;
|
||||
abigail::ir::environment_sptr env;
|
||||
abigail::corpus_sptr corp;
|
||||
|
||||
for (InOutSpec* s = in_out_specs; s->in_elf_path; ++s)
|
||||
{
|
||||
in_elf_path = abigail::tests::get_src_dir() + "/tests/" + s->in_elf_path;
|
||||
env.reset(new abigail::ir::environment);
|
||||
abigail::dwarf_reader::status status =
|
||||
abigail::dwarf_reader::STATUS_UNKNOWN;
|
||||
corp = abigail::dwarf_reader::read_corpus_from_elf(in_elf_path,
|
||||
/*debug_info_root_path=*/0,
|
||||
/*load_all_types=*/false,
|
||||
status);
|
||||
corp = read_corpus_from_elf(in_elf_path,
|
||||
/*debug_info_root_path=*/0,
|
||||
env.get(),
|
||||
/*load_all_types=*/false,
|
||||
status);
|
||||
if (!corp)
|
||||
{
|
||||
cerr << "failed to read " << in_elf_path << "\n";
|
||||
|
||||
@@ -40,6 +40,8 @@ using abigail::tools_utils::file_type;
|
||||
using abigail::tools_utils::check_file;
|
||||
using abigail::tools_utils::guess_file_type;
|
||||
using abigail::tests::get_build_dir;
|
||||
using abigail::ir::environment;
|
||||
using abigail::ir::environment_sptr;
|
||||
using abigail::translation_unit_sptr;
|
||||
using abigail::corpus_sptr;
|
||||
using abigail::xml_reader::read_translation_unit_from_file;
|
||||
@@ -187,15 +189,16 @@ main()
|
||||
if (!check_file(in_path, cerr))
|
||||
return true;
|
||||
|
||||
environment_sptr env(new environment);
|
||||
translation_unit_sptr tu;
|
||||
corpus_sptr corpus;
|
||||
|
||||
bool read = false;
|
||||
file_type t = guess_file_type(in_path);
|
||||
if (t == abigail::tools_utils::FILE_TYPE_NATIVE_BI)
|
||||
read = (tu = read_translation_unit_from_file(in_path));
|
||||
read = (tu = read_translation_unit_from_file(in_path, env.get()));
|
||||
else if (t == abigail::tools_utils::FILE_TYPE_XML_CORPUS)
|
||||
read = (corpus = read_corpus_from_native_xml_file(in_path));
|
||||
read = (corpus = read_corpus_from_native_xml_file(in_path, env.get()));
|
||||
else
|
||||
abort();
|
||||
if (!read)
|
||||
|
||||
+8
-4
@@ -213,6 +213,8 @@ parse_command_line(int argc, char* argv[], options& opts)
|
||||
using abigail::tools_utils::check_file;
|
||||
using abigail::tools_utils::base_name;
|
||||
using abigail::tools_utils::abidiff_status;
|
||||
using abigail::ir::environment;
|
||||
using abigail::ir::environment_sptr;
|
||||
using abigail::corpus;
|
||||
using abigail::corpus_sptr;
|
||||
using abigail::ir::elf_symbols;
|
||||
@@ -606,9 +608,10 @@ main(int argc, char* argv[])
|
||||
// Read the application ELF file.
|
||||
char * app_di_root = opts.app_di_root_path.get();
|
||||
status status = abigail::dwarf_reader::STATUS_UNKNOWN;
|
||||
environment_sptr env(new environment);
|
||||
corpus_sptr app_corpus=
|
||||
read_corpus_from_elf(opts.app_path,
|
||||
&app_di_root,
|
||||
&app_di_root, env.get(),
|
||||
/*load_all_types=*/opts.weak_mode,
|
||||
status);
|
||||
|
||||
@@ -654,9 +657,9 @@ main(int argc, char* argv[])
|
||||
|
||||
char * lib1_di_root = opts.lib1_di_root_path.get();
|
||||
corpus_sptr lib1_corpus = read_corpus_from_elf(opts.lib1_path,
|
||||
&lib1_di_root,
|
||||
/*load_all_types=*/false,
|
||||
status);
|
||||
&lib1_di_root, env.get(),
|
||||
/*load_all_types=*/false,
|
||||
status);
|
||||
if (status & abigail::dwarf_reader::STATUS_DEBUG_INFO_NOT_FOUND)
|
||||
cerr << "could not read debug info for " << opts.lib1_path << "\n";
|
||||
if (status & abigail::dwarf_reader::STATUS_NO_SYMBOLS_FOUND)
|
||||
@@ -678,6 +681,7 @@ main(int argc, char* argv[])
|
||||
char * lib2_di_root = opts.lib2_di_root_path.get();
|
||||
lib2_corpus = read_corpus_from_elf(opts.lib2_path,
|
||||
&lib2_di_root,
|
||||
env.get(),
|
||||
/*load_all_types=*/false,
|
||||
status);
|
||||
if (status & abigail::dwarf_reader::STATUS_DEBUG_INFO_NOT_FOUND)
|
||||
|
||||
+13
-6
@@ -37,6 +37,8 @@ using std::ostream;
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::tr1::shared_ptr;
|
||||
using abigail::ir::environment;
|
||||
using abigail::ir::environment_sptr;
|
||||
using abigail::translation_unit;
|
||||
using abigail::translation_unit_sptr;
|
||||
using abigail::corpus_sptr;
|
||||
@@ -524,6 +526,7 @@ main(int argc, char* argv[])
|
||||
return abigail::tools_utils::ABIDIFF_ERROR;
|
||||
}
|
||||
|
||||
environment_sptr env(new environment);
|
||||
translation_unit_sptr t1, t2;
|
||||
abigail::dwarf_reader::status c1_status =
|
||||
abigail::dwarf_reader::STATUS_OK,
|
||||
@@ -538,7 +541,8 @@ main(int argc, char* argv[])
|
||||
return abigail::tools_utils::ABIDIFF_ERROR;
|
||||
break;
|
||||
case abigail::tools_utils::FILE_TYPE_NATIVE_BI:
|
||||
t1 = abigail::xml_reader::read_translation_unit_from_file(opts.file1);
|
||||
t1 = abigail::xml_reader::read_translation_unit_from_file(opts.file1,
|
||||
env.get());
|
||||
break;
|
||||
case abigail::tools_utils::FILE_TYPE_ELF:
|
||||
case abigail::tools_utils::FILE_TYPE_AR:
|
||||
@@ -546,7 +550,7 @@ main(int argc, char* argv[])
|
||||
di_dir1 = opts.di_root_path1.get();
|
||||
abigail::dwarf_reader::read_context_sptr ctxt =
|
||||
abigail::dwarf_reader::create_read_context(opts.file1,
|
||||
&di_dir1,
|
||||
&di_dir1, env.get(),
|
||||
/*read_all_types=*/false);
|
||||
assert(ctxt);
|
||||
abigail::dwarf_reader::set_show_stats
|
||||
@@ -557,7 +561,8 @@ main(int argc, char* argv[])
|
||||
break;
|
||||
case abigail::tools_utils::FILE_TYPE_XML_CORPUS:
|
||||
c1 =
|
||||
abigail::xml_reader::read_corpus_from_native_xml_file(opts.file1);
|
||||
abigail::xml_reader::read_corpus_from_native_xml_file(opts.file1,
|
||||
env.get());
|
||||
break;
|
||||
case abigail::tools_utils::FILE_TYPE_ZIP_CORPUS:
|
||||
#ifdef WITH_ZIP_ARCHIVE
|
||||
@@ -579,7 +584,8 @@ main(int argc, char* argv[])
|
||||
return abigail::tools_utils::ABIDIFF_ERROR;
|
||||
break;
|
||||
case abigail::tools_utils::FILE_TYPE_NATIVE_BI:
|
||||
t2 = abigail::xml_reader::read_translation_unit_from_file(opts.file2);
|
||||
t2 = abigail::xml_reader::read_translation_unit_from_file(opts.file2,
|
||||
env.get());
|
||||
break;
|
||||
case abigail::tools_utils::FILE_TYPE_ELF:
|
||||
case abigail::tools_utils::FILE_TYPE_AR:
|
||||
@@ -587,7 +593,7 @@ main(int argc, char* argv[])
|
||||
di_dir2 = opts.di_root_path2.get();
|
||||
abigail::dwarf_reader::read_context_sptr ctxt =
|
||||
abigail::dwarf_reader::create_read_context(opts.file2,
|
||||
&di_dir2,
|
||||
&di_dir2, env.get(),
|
||||
/*read_all_types=*/false);
|
||||
assert(ctxt);
|
||||
abigail::dwarf_reader::set_show_stats
|
||||
@@ -597,7 +603,8 @@ main(int argc, char* argv[])
|
||||
break;
|
||||
case abigail::tools_utils::FILE_TYPE_XML_CORPUS:
|
||||
c2 =
|
||||
abigail::xml_reader::read_corpus_from_native_xml_file(opts.file2);
|
||||
abigail::xml_reader::read_corpus_from_native_xml_file(opts.file2,
|
||||
env.get());
|
||||
break;
|
||||
case abigail::tools_utils::FILE_TYPE_ZIP_CORPUS:
|
||||
#ifdef WITH_ZIP_ARCHIVE
|
||||
|
||||
+5
-1
@@ -182,6 +182,8 @@ main(int argc, char* argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
using abigail::ir::environment_sptr;
|
||||
using abigail::ir::environment;
|
||||
using abigail::corpus;
|
||||
using abigail::corpus_sptr;
|
||||
using abigail::translation_units;
|
||||
@@ -192,8 +194,10 @@ main(int argc, char* argv[])
|
||||
using namespace abigail;
|
||||
|
||||
char* p = opts.di_root_path.get();
|
||||
environment_sptr env(new environment);
|
||||
corpus_sptr corp;
|
||||
read_context_sptr c = create_read_context(opts.in_file_path, &p,
|
||||
read_context_sptr c = create_read_context(opts.in_file_path,
|
||||
&p, env.get(),
|
||||
opts.load_all_types);
|
||||
set_show_stats(c, opts.show_stats);
|
||||
read_context& ctxt = *c;
|
||||
|
||||
+9
-8
@@ -160,6 +160,7 @@ main(int argc, char* argv[])
|
||||
return true;
|
||||
}
|
||||
|
||||
abigail::ir::environment_sptr env(new abigail::ir::environment);
|
||||
if (opts.read_from_stdin)
|
||||
{
|
||||
if (!cin.good())
|
||||
@@ -168,7 +169,7 @@ main(int argc, char* argv[])
|
||||
if (opts.read_tu)
|
||||
{
|
||||
abigail::translation_unit_sptr tu =
|
||||
read_translation_unit_from_istream(&cin);
|
||||
read_translation_unit_from_istream(&cin, env.get());
|
||||
|
||||
if (!tu)
|
||||
{
|
||||
@@ -182,7 +183,7 @@ main(int argc, char* argv[])
|
||||
}
|
||||
else
|
||||
{
|
||||
corpus_sptr corp = read_corpus_from_native_xml(&cin);
|
||||
corpus_sptr corp = read_corpus_from_native_xml(&cin, env.get());
|
||||
if (!opts.noout)
|
||||
write_corpus_to_native_xml(corp, /*indent=*/0, cout);
|
||||
return false;
|
||||
@@ -192,7 +193,6 @@ main(int argc, char* argv[])
|
||||
{
|
||||
if (!check_file(opts.file_path, cerr))
|
||||
return true;
|
||||
|
||||
abigail::translation_unit_sptr tu;
|
||||
abigail::corpus_sptr corp;
|
||||
abigail::dwarf_reader::status s = abigail::dwarf_reader::STATUS_OK;
|
||||
@@ -205,18 +205,19 @@ main(int argc, char* argv[])
|
||||
cerr << "Unknown file type given in input: " << opts.file_path;
|
||||
return true;
|
||||
case abigail::tools_utils::FILE_TYPE_NATIVE_BI:
|
||||
tu = read_translation_unit_from_file(opts.file_path);
|
||||
tu = read_translation_unit_from_file(opts.file_path, env.get());
|
||||
break;
|
||||
case abigail::tools_utils::FILE_TYPE_ELF:
|
||||
case abigail::tools_utils::FILE_TYPE_AR:
|
||||
di_root_path = opts.di_root_path.get();
|
||||
corp = read_corpus_from_elf(opts.file_path,
|
||||
&di_root_path,
|
||||
/*load_all_types=*/false,
|
||||
s);
|
||||
&di_root_path,
|
||||
env.get(),
|
||||
/*load_all_types=*/false,
|
||||
s);
|
||||
break;
|
||||
case abigail::tools_utils::FILE_TYPE_XML_CORPUS:
|
||||
corp = read_corpus_from_native_xml_file(opts.file_path);
|
||||
corp = read_corpus_from_native_xml_file(opts.file_path, env.get());
|
||||
break;
|
||||
case abigail::tools_utils::FILE_TYPE_ZIP_CORPUS:
|
||||
#if WITH_ZIP_ARCHIVE
|
||||
|
||||
+3
-2
@@ -715,13 +715,14 @@ compare(const elf_file& elf1,
|
||||
|
||||
abigail::dwarf_reader::status c1_status = abigail::dwarf_reader::STATUS_OK,
|
||||
c2_status = abigail::dwarf_reader::STATUS_OK;
|
||||
abigail::ir::environment_sptr env(new abigail::ir::environment);
|
||||
|
||||
if (verbose)
|
||||
cerr << " Reading file "
|
||||
<< elf1.path
|
||||
<< " ...";
|
||||
|
||||
corpus_sptr corpus1 = read_corpus_from_elf(elf1.path, &di_dir1,
|
||||
corpus_sptr corpus1 = read_corpus_from_elf(elf1.path, &di_dir1, env.get(),
|
||||
/*load_all_types=*/false,
|
||||
c1_status);
|
||||
if (!(c1_status & abigail::dwarf_reader::STATUS_OK))
|
||||
@@ -753,7 +754,7 @@ compare(const elf_file& elf1,
|
||||
<< elf2.path
|
||||
<< " ...";
|
||||
|
||||
corpus_sptr corpus2 = read_corpus_from_elf(elf2.path, &di_dir2,
|
||||
corpus_sptr corpus2 = read_corpus_from_elf(elf2.path, &di_dir2, env.get(),
|
||||
/*load_all_types=*/false,
|
||||
c2_status);
|
||||
if (!(c2_status & abigail::dwarf_reader::STATUS_OK))
|
||||
|
||||
Reference in New Issue
Block a user