mirror of
git://sourceware.org/git/libabigail.git
synced 2025-01-29 12:42:50 +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>
This commit is contained in:
parent
445923157d
commit
cf8eba68c3
@ -1,5 +1,6 @@
|
||||
pkginclude_HEADERS = \
|
||||
abg-sptr-utils.h \
|
||||
abg-interned-str.h \
|
||||
abg-ir.h \
|
||||
abg-corpus.h \
|
||||
abg-reader.h \
|
||||
|
@ -81,14 +81,14 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
corpus(const string&, ir::environment*);
|
||||
|
||||
environment*
|
||||
get_environment();
|
||||
corpus(ir::environment*, const string&);
|
||||
|
||||
const environment*
|
||||
get_environment() const;
|
||||
|
||||
environment*
|
||||
get_environment();
|
||||
|
||||
void
|
||||
set_environment(environment*) const;
|
||||
|
||||
|
@ -103,13 +103,15 @@ read_corpus_from_elf(const std::string& elf_path,
|
||||
status&);
|
||||
|
||||
bool
|
||||
lookup_symbol_from_elf(const string& elf_path,
|
||||
lookup_symbol_from_elf(const environment* env,
|
||||
const string& elf_path,
|
||||
const string& symbol_name,
|
||||
bool demangle,
|
||||
vector<elf_symbol_sptr>& symbols);
|
||||
|
||||
bool
|
||||
lookup_public_function_symbol_from_elf(const string& path,
|
||||
lookup_public_function_symbol_from_elf(const environment* env,
|
||||
const string& path,
|
||||
const string& symname,
|
||||
vector<elf_symbol_sptr>& func_syms);
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <typeinfo>
|
||||
#include <utility> // for std::rel_ops, at least.
|
||||
#include <ostream>
|
||||
#include "abg-interned-str.h"
|
||||
#include "abg-hash.h"
|
||||
|
||||
/// Toplevel namespace for libabigail.
|
||||
@ -533,37 +534,38 @@ get_type_scope(type_base*);
|
||||
scope_decl*
|
||||
get_type_scope(const shared_ptr<type_base>&);
|
||||
|
||||
string
|
||||
interned_string
|
||||
get_type_name(const shared_ptr<type_base>,
|
||||
bool qualified = true,
|
||||
bool internal = false);
|
||||
|
||||
string
|
||||
interned_string
|
||||
get_type_name(const type_base*,
|
||||
bool qualified = true,
|
||||
bool internal = false);
|
||||
|
||||
string
|
||||
interned_string
|
||||
get_type_name(const type_base&,
|
||||
bool qualified = true,
|
||||
bool internal = false);
|
||||
|
||||
string
|
||||
interned_string
|
||||
get_function_type_name(const shared_ptr<function_type>&,
|
||||
bool internal = false);
|
||||
|
||||
string
|
||||
interned_string
|
||||
get_function_type_name(const function_type*, bool internal = false);
|
||||
|
||||
string
|
||||
interned_string
|
||||
get_function_type_name(const function_type&, bool internal = false);
|
||||
|
||||
string
|
||||
interned_string
|
||||
get_method_type_name(const shared_ptr<method_type>&, bool internal = false);
|
||||
string
|
||||
|
||||
interned_string
|
||||
get_method_type_name(const method_type*, bool internal = false);
|
||||
|
||||
string
|
||||
interned_string
|
||||
get_method_type_name(const method_type&, bool internal = false);
|
||||
|
||||
string
|
||||
|
247
include/abg-interned-str.h
Normal file
247
include/abg-interned-str.h
Normal file
@ -0,0 +1,247 @@
|
||||
// -*- Mode: C++ -*-
|
||||
//
|
||||
// Copyright (C) 2016 Red Hat, Inc.
|
||||
//
|
||||
// This file is part of the GNU Application Binary Interface Generic
|
||||
// Analysis and Instrumentation Library (libabigail). This library is
|
||||
// free software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Lesser General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option) any
|
||||
// later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Lesser Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; see the file COPYING-LGPLV3. If
|
||||
// not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Author: Dodji Seketeli
|
||||
|
||||
/// @file
|
||||
///
|
||||
/// Declaration of types pertaining to the interned string pool used
|
||||
/// throughout Libabigail, for performance reasons.
|
||||
///
|
||||
/// For the record, the concept of the String Interning method is
|
||||
/// explained at https://en.wikipedia.org/wiki/String_interning.
|
||||
|
||||
#ifndef __ABG_INTERNED_STR_H__
|
||||
#define __ABG_INTERNED_STR_H__
|
||||
|
||||
#include <tr1/memory>
|
||||
#include <tr1/functional>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
using std::tr1::shared_ptr;
|
||||
|
||||
namespace abigail
|
||||
{
|
||||
|
||||
/// The abstraction of an interned string.
|
||||
///
|
||||
/// It's a wrapper around a pointer to a std::string, along with a set
|
||||
/// of method that helps make this string integrate with std::string
|
||||
/// seamlessly. For instance, the type provides equality operators
|
||||
/// that help compare it against std::string.
|
||||
///
|
||||
/// Note that this @ref interned_string type is design to have the
|
||||
/// same size as a pointer to a string.
|
||||
class interned_string
|
||||
{
|
||||
std::string* raw_;
|
||||
|
||||
/// Constructor.
|
||||
///
|
||||
/// @param raw the pointer to string that this interned_string
|
||||
/// wraps.
|
||||
interned_string(std::string* raw)
|
||||
: raw_(raw)
|
||||
{}
|
||||
|
||||
public:
|
||||
|
||||
/// Default constructor.
|
||||
///
|
||||
/// Constructs an empty pointer to string.
|
||||
interned_string()
|
||||
: raw_()
|
||||
{}
|
||||
|
||||
/// Copy constructor.
|
||||
///
|
||||
/// @param o the other instance to copy from.
|
||||
interned_string(const interned_string& o)
|
||||
{raw_ = o.raw_;}
|
||||
|
||||
/// Test if the current instance of @ref interned_string is empty.
|
||||
///
|
||||
/// @return true iff the currentisntance of @ref interned_string is
|
||||
/// empty.
|
||||
bool
|
||||
empty() const
|
||||
{return !raw_;}
|
||||
|
||||
/// Return the underlying pointer to std::string that this
|
||||
/// interned_string wraps.
|
||||
///
|
||||
/// @return a pointer to the underlying std::string, or 0 if this
|
||||
/// interned_string is empty.
|
||||
const std::string*
|
||||
raw() const
|
||||
{return raw_;}
|
||||
|
||||
/// Compare the current instance of @ref interned_string against
|
||||
/// another instance of @ref interned_string.
|
||||
///
|
||||
/// Note that this comparison is done in O(1), because it compares
|
||||
/// the pointer values of the two underlying pointers to std::string
|
||||
/// held by each instances of @ref interned_string.
|
||||
///
|
||||
/// @param o the other @ref interned_string to compare against.
|
||||
///
|
||||
/// @return true iff the current instance equals @p o.
|
||||
bool
|
||||
operator==(const interned_string& o) const
|
||||
{return raw_ == o.raw_;}
|
||||
|
||||
/// Inequality operator.
|
||||
///
|
||||
/// @param o the other @ref interned_string to compare the current
|
||||
/// instance against.
|
||||
///
|
||||
/// @return true iff the current instance is different from the @p
|
||||
/// o.
|
||||
bool
|
||||
operator!=(const interned_string& o) const
|
||||
{return !operator==(o);}
|
||||
|
||||
/// Compare the current instance of @ref interned_string against
|
||||
/// an instance of std::string.
|
||||
///
|
||||
/// Note that this comparison is done in O(N), N being the size (in
|
||||
/// number of characters) of the strings being compared.
|
||||
///
|
||||
/// @param o the instance of std::string to compare against.
|
||||
///
|
||||
/// @return true iff the current instance equals @p o.
|
||||
bool
|
||||
operator==(const std::string& o) const
|
||||
{
|
||||
if (raw_)
|
||||
return *raw_ == o;
|
||||
return o.empty();
|
||||
}
|
||||
|
||||
/// Inequality operator.
|
||||
///
|
||||
/// Takes the current instance of @ref interned_string and an
|
||||
/// instance of std::string.
|
||||
///
|
||||
/// @param o the instance of std::string to compare the current
|
||||
/// instance of @ref interned_string against.
|
||||
///
|
||||
/// @return true if the current instance of @ref interned_string is
|
||||
/// different from @p o.
|
||||
bool
|
||||
operator!=(const std::string& o) const
|
||||
{return ! operator==(o);}
|
||||
|
||||
/// "Less than" operator.
|
||||
///
|
||||
/// Lexicographically compares the current instance of @ref
|
||||
/// interned_string against another instance.
|
||||
///
|
||||
/// @param o the other instance of @ref interned_string to compare
|
||||
/// against.
|
||||
///
|
||||
/// @return true iff the current instance of interned_string is
|
||||
/// lexicographycally less than the string @p o.
|
||||
bool
|
||||
operator<(const interned_string& o) const
|
||||
{return static_cast<std::string>(*this) < static_cast<std::string>(o);}
|
||||
|
||||
/// Conversion operator to string.
|
||||
///
|
||||
/// @return the underlying string this instance refers too.
|
||||
operator std::string() const
|
||||
{
|
||||
if (!raw_)
|
||||
return "";
|
||||
return *raw_;
|
||||
}
|
||||
|
||||
friend class interned_string_pool;
|
||||
}; // end class interned_string
|
||||
|
||||
bool
|
||||
operator==(const std::string& l, const interned_string& r);
|
||||
|
||||
bool
|
||||
operator!=(const std::string& l, const interned_string& r);
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& o, const interned_string& s);
|
||||
|
||||
std::string
|
||||
operator+(const interned_string& s1,const std::string& s2);
|
||||
|
||||
std::string
|
||||
operator+(const std::string& s1, const interned_string& s2);
|
||||
|
||||
/// A functor to hash instances of @ref interned_string.
|
||||
struct hash_interned_string
|
||||
{
|
||||
/// The hash operator.
|
||||
///
|
||||
/// It's super fast because hashing an interned string amounts to
|
||||
/// hashing the pointer to it's underlying string. It's because
|
||||
/// every distinct string is present only in one copy in the
|
||||
/// environment.
|
||||
///
|
||||
/// @param s the instance of @ref interned_string to hash.
|
||||
///
|
||||
/// @return the returned hash value.
|
||||
size_t
|
||||
operator()(const interned_string& s) const
|
||||
{
|
||||
std::tr1::hash<size_t> hash_size_t;
|
||||
return hash_size_t(reinterpret_cast<size_t>(s.raw()));
|
||||
}
|
||||
}; // end struct hash_interned_string
|
||||
|
||||
|
||||
/// The interned string pool.
|
||||
///
|
||||
/// This is where all the distinct strings represented by the interned
|
||||
/// strings leave. The pool is the actor responsible for creating
|
||||
/// interned strings.
|
||||
class interned_string_pool
|
||||
{
|
||||
struct priv;
|
||||
typedef shared_ptr<priv> priv_sptr;
|
||||
|
||||
priv_sptr priv_;
|
||||
|
||||
public:
|
||||
|
||||
interned_string_pool();
|
||||
|
||||
interned_string
|
||||
create_string(const std::string&);
|
||||
|
||||
bool
|
||||
has_string(const char* s) const;
|
||||
|
||||
const char*
|
||||
get_string(const char* s) const;
|
||||
|
||||
~interned_string_pool();
|
||||
}; // end class interned_string_pool
|
||||
|
||||
} // end namespace abigail
|
||||
|
||||
#endif // __ABG_INTERNED_STR_H__
|
211
include/abg-ir.h
211
include/abg-ir.h
@ -167,6 +167,9 @@ public:
|
||||
void
|
||||
canonicalization_is_done(bool);
|
||||
|
||||
interned_string
|
||||
intern(const string&) const;
|
||||
|
||||
friend class class_decl;
|
||||
|
||||
friend void keep_type_alive(type_base_sptr);
|
||||
@ -389,9 +392,9 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
translation_unit(const std::string& path,
|
||||
ir::environment* env,
|
||||
char address_size = 0);
|
||||
translation_unit(const ir::environment* env,
|
||||
const std::string& path,
|
||||
char address_size = 0);
|
||||
|
||||
virtual ~translation_unit();
|
||||
|
||||
@ -402,7 +405,7 @@ public:
|
||||
get_environment();
|
||||
|
||||
void
|
||||
set_environment(environment*);
|
||||
set_environment(const environment*);
|
||||
|
||||
language
|
||||
get_language() const;
|
||||
@ -577,7 +580,8 @@ private:
|
||||
|
||||
elf_symbol();
|
||||
|
||||
elf_symbol(size_t i,
|
||||
elf_symbol(const environment* e,
|
||||
size_t i,
|
||||
size_t s,
|
||||
const string& n,
|
||||
type t,
|
||||
@ -597,14 +601,21 @@ public:
|
||||
create();
|
||||
|
||||
static elf_symbol_sptr
|
||||
create(size_t i,
|
||||
size_t s,
|
||||
const string& n,
|
||||
type t,
|
||||
binding b,
|
||||
bool d,
|
||||
bool c,
|
||||
const version& v);
|
||||
create(const environment* e,
|
||||
size_t i,
|
||||
size_t s,
|
||||
const string& n,
|
||||
type t,
|
||||
binding b,
|
||||
bool d,
|
||||
bool c,
|
||||
const version& v);
|
||||
|
||||
const environment*
|
||||
get_environment() const;
|
||||
|
||||
void
|
||||
set_environment(const environment*) const;
|
||||
|
||||
size_t
|
||||
get_index() const;
|
||||
@ -927,6 +938,8 @@ class type_or_decl_base : public ir_traversable_base
|
||||
typedef shared_ptr<priv> priv_sptr;
|
||||
mutable priv_sptr priv_;
|
||||
|
||||
type_or_decl_base();
|
||||
|
||||
protected:
|
||||
|
||||
bool hashing_started() const;
|
||||
@ -935,7 +948,7 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
type_or_decl_base();
|
||||
type_or_decl_base(const environment*);
|
||||
|
||||
type_or_decl_base(const type_or_decl_base&);
|
||||
|
||||
@ -948,7 +961,7 @@ public:
|
||||
get_environment();
|
||||
|
||||
void
|
||||
set_environment(environment*);
|
||||
set_environment(const environment*);
|
||||
|
||||
const corpus*
|
||||
get_corpus() const;
|
||||
@ -959,6 +972,9 @@ public:
|
||||
const translation_unit*
|
||||
get_translation_unit() const;
|
||||
|
||||
type_or_decl_base&
|
||||
operator=(const type_or_decl_base&);
|
||||
|
||||
virtual bool
|
||||
traverse(ir_node_visitor&);
|
||||
|
||||
@ -977,11 +993,11 @@ 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);
|
||||
const environment* env);
|
||||
|
||||
void
|
||||
set_environment_for_artifact(type_or_decl_base_sptr artifact,
|
||||
environment* env);
|
||||
const environment* env);
|
||||
|
||||
/// The base type of all declarations.
|
||||
class decl_base : public virtual type_or_decl_base
|
||||
@ -993,17 +1009,17 @@ class decl_base : public virtual type_or_decl_base
|
||||
|
||||
protected:
|
||||
|
||||
const string&
|
||||
const interned_string&
|
||||
peek_qualified_name() const;
|
||||
|
||||
void
|
||||
set_qualified_name(const string&) const;
|
||||
set_qualified_name(const interned_string&) const;
|
||||
|
||||
const string&
|
||||
const interned_string&
|
||||
peek_temporary_qualified_name() const;
|
||||
|
||||
void
|
||||
set_temporary_qualified_name(const string&) const;
|
||||
set_temporary_qualified_name(const interned_string&) const;
|
||||
|
||||
public:
|
||||
// This is public because some internals of the library need to
|
||||
@ -1054,11 +1070,19 @@ protected:
|
||||
set_context_rel(context_rel_sptr c);
|
||||
|
||||
public:
|
||||
decl_base(const std::string& name, const location& locus,
|
||||
const std::string& mangled_name = "",
|
||||
decl_base(const environment* e,
|
||||
const string& name,
|
||||
const location& locus,
|
||||
const string& mangled_name = "",
|
||||
visibility vis = VISIBILITY_DEFAULT);
|
||||
|
||||
decl_base(const location&);
|
||||
decl_base(const environment* e,
|
||||
const interned_string& name,
|
||||
const location& locus,
|
||||
const interned_string& mangled_name = interned_string(),
|
||||
visibility vis = VISIBILITY_DEFAULT);
|
||||
|
||||
decl_base(const environment*, const location&);
|
||||
|
||||
decl_base(const decl_base&);
|
||||
|
||||
@ -1080,9 +1104,10 @@ public:
|
||||
get_pretty_representation(bool internal = false) const;
|
||||
|
||||
virtual void
|
||||
get_qualified_name(string& qualified_name, bool internal = false) const;
|
||||
get_qualified_name(interned_string& qualified_name,
|
||||
bool internal = false) const;
|
||||
|
||||
virtual const string&
|
||||
virtual const interned_string&
|
||||
get_qualified_name(bool internal = false) const;
|
||||
|
||||
bool
|
||||
@ -1097,10 +1122,10 @@ public:
|
||||
void
|
||||
set_location(const location& l);
|
||||
|
||||
const string&
|
||||
const interned_string&
|
||||
get_name() const;
|
||||
|
||||
const string&
|
||||
const interned_string&
|
||||
get_qualified_parent_name() const;
|
||||
|
||||
void
|
||||
@ -1112,11 +1137,11 @@ public:
|
||||
void
|
||||
set_is_anonymous(bool);
|
||||
|
||||
const string&
|
||||
const interned_string&
|
||||
get_linkage_name() const;
|
||||
|
||||
virtual void
|
||||
set_linkage_name(const std::string& m);
|
||||
set_linkage_name(const string& m);
|
||||
|
||||
scope_decl*
|
||||
get_scope() const;
|
||||
@ -1230,13 +1255,16 @@ protected:
|
||||
public:
|
||||
struct hash;
|
||||
|
||||
scope_decl(const std::string& name, const location& locus,
|
||||
scope_decl(const environment* env,
|
||||
const string& name, const location& locus,
|
||||
visibility vis = VISIBILITY_DEFAULT)
|
||||
: type_or_decl_base(),
|
||||
decl_base(name, locus, /*mangled_name=*/name, vis)
|
||||
: type_or_decl_base(env),
|
||||
decl_base(env, name, locus, /*mangled_name=*/name, vis)
|
||||
{}
|
||||
|
||||
scope_decl(location& l) : decl_base("", l)
|
||||
scope_decl(const environment* env, location& l)
|
||||
: type_or_decl_base(env),
|
||||
decl_base(env, "", l)
|
||||
{}
|
||||
|
||||
virtual size_t
|
||||
@ -1317,8 +1345,10 @@ class global_scope : public scope_decl
|
||||
translation_unit* translation_unit_;
|
||||
|
||||
global_scope(translation_unit *tu)
|
||||
: decl_base("", location()), scope_decl("", location()),
|
||||
translation_unit_(tu)
|
||||
: type_or_decl_base(tu->get_environment()),
|
||||
decl_base(tu->get_environment(), "", location()),
|
||||
scope_decl(tu->get_environment(), "", location()),
|
||||
translation_unit_(tu)
|
||||
{}
|
||||
|
||||
public:
|
||||
@ -1373,7 +1403,7 @@ public:
|
||||
/// runtime type of the type pointed to.
|
||||
struct shared_ptr_hash;
|
||||
|
||||
type_base(size_t s, size_t a);
|
||||
type_base(const environment* e, size_t s, size_t a);
|
||||
|
||||
friend type_base_sptr
|
||||
canonicalize(type_base_sptr);
|
||||
@ -1475,12 +1505,13 @@ public:
|
||||
/// Facility to hash instance of type_decl
|
||||
struct hash;
|
||||
|
||||
type_decl(const std::string& name,
|
||||
size_t size_in_bits,
|
||||
size_t alignment_in_bits,
|
||||
const location& locus,
|
||||
const std::string& mangled_name = "",
|
||||
visibility vis = VISIBILITY_DEFAULT);
|
||||
type_decl(const environment* env,
|
||||
const string& name,
|
||||
size_t size_in_bits,
|
||||
size_t alignment_in_bits,
|
||||
const location& locus,
|
||||
const string& mangled_name = "",
|
||||
visibility vis = VISIBILITY_DEFAULT);
|
||||
|
||||
virtual bool
|
||||
operator==(const type_base&) const;
|
||||
@ -1521,9 +1552,9 @@ public:
|
||||
/// Hasher for instances of scope_type_decl
|
||||
struct hash;
|
||||
|
||||
scope_type_decl(const std::string& name, size_t size_in_bits,
|
||||
size_t alignment_in_bits, const location& locus,
|
||||
visibility vis = VISIBILITY_DEFAULT);
|
||||
scope_type_decl(const environment* env, const string& name,
|
||||
size_t size_in_bits, size_t alignment_in_bits,
|
||||
const location& locus, visibility vis = VISIBILITY_DEFAULT);
|
||||
|
||||
virtual bool
|
||||
operator==(const decl_base&) const;
|
||||
@ -1545,8 +1576,8 @@ class namespace_decl : public scope_decl
|
||||
{
|
||||
public:
|
||||
|
||||
namespace_decl(const std::string& name, const location& locus,
|
||||
visibility vis = VISIBILITY_DEFAULT);
|
||||
namespace_decl(const environment* env, const string& name,
|
||||
const location& locus, visibility vis = VISIBILITY_DEFAULT);
|
||||
|
||||
virtual string
|
||||
get_pretty_representation(bool internal = false) const;
|
||||
@ -1620,9 +1651,10 @@ public:
|
||||
get_underlying_type() const;
|
||||
|
||||
virtual void
|
||||
get_qualified_name(string& qualified_name, bool internal = false) const;
|
||||
get_qualified_name(interned_string& qualified_name,
|
||||
bool internal = false) const;
|
||||
|
||||
virtual const string&
|
||||
virtual const interned_string&
|
||||
get_qualified_name(bool internal = false) const;
|
||||
|
||||
virtual bool
|
||||
@ -1687,9 +1719,9 @@ public:
|
||||
get_pointed_to_type() const;
|
||||
|
||||
virtual void
|
||||
get_qualified_name(string&, bool internal = false) const;
|
||||
get_qualified_name(interned_string&, bool internal = false) const;
|
||||
|
||||
virtual const string&
|
||||
virtual const interned_string&
|
||||
get_qualified_name(bool internal = false) const;
|
||||
|
||||
virtual bool
|
||||
@ -1744,9 +1776,10 @@ public:
|
||||
is_lvalue() const;
|
||||
|
||||
virtual void
|
||||
get_qualified_name(string& qualified_name, bool internal = false) const;
|
||||
get_qualified_name(interned_string& qualified_name,
|
||||
bool internal = false) const;
|
||||
|
||||
virtual const string&
|
||||
virtual const interned_string&
|
||||
get_qualified_name(bool internal = false) const;
|
||||
|
||||
virtual bool
|
||||
@ -1851,9 +1884,10 @@ public:
|
||||
operator==(const type_base&) const;
|
||||
|
||||
virtual void
|
||||
get_qualified_name(string& qualified_name, bool internal = false) const;
|
||||
get_qualified_name(interned_string& qualified_name,
|
||||
bool internal = false) const;
|
||||
|
||||
virtual const string&
|
||||
virtual const interned_string&
|
||||
get_qualified_name(bool internal = false) const;
|
||||
|
||||
const type_base_sptr
|
||||
@ -1983,7 +2017,7 @@ public:
|
||||
|
||||
enumerator();
|
||||
|
||||
enumerator(const string& name, int64_t value);
|
||||
enumerator(const environment* env, const string& name, int64_t value);
|
||||
|
||||
enumerator(const enumerator&);
|
||||
|
||||
@ -1993,10 +2027,13 @@ public:
|
||||
bool
|
||||
operator!=(const enumerator& other) const;
|
||||
|
||||
const string&
|
||||
const environment*
|
||||
get_environment() const;
|
||||
|
||||
const interned_string&
|
||||
get_name() const;
|
||||
|
||||
const string&
|
||||
const interned_string&
|
||||
get_qualified_name(bool internal = false) const;
|
||||
|
||||
void
|
||||
@ -2191,7 +2228,7 @@ public:
|
||||
var_decl_sptr
|
||||
clone() const;
|
||||
|
||||
const string&
|
||||
interned_string
|
||||
get_id() const;
|
||||
|
||||
virtual size_t
|
||||
@ -2338,7 +2375,7 @@ public:
|
||||
virtual size_t
|
||||
get_hash() const;
|
||||
|
||||
const string&
|
||||
interned_string
|
||||
get_id() const;
|
||||
|
||||
virtual bool
|
||||
@ -2394,13 +2431,13 @@ public:
|
||||
const type_base_sptr
|
||||
get_type()const;
|
||||
|
||||
const string
|
||||
interned_string
|
||||
get_type_name() const;
|
||||
|
||||
const string
|
||||
get_type_pretty_representation() const;
|
||||
|
||||
const string
|
||||
interned_string
|
||||
get_name_id() const;
|
||||
|
||||
unsigned
|
||||
@ -2431,7 +2468,8 @@ public:
|
||||
get_hash() const;
|
||||
|
||||
virtual void
|
||||
get_qualified_name(string& qualified_name, bool internal = false) const;
|
||||
get_qualified_name(interned_string& qualified_name,
|
||||
bool internal = false) const;
|
||||
|
||||
virtual string
|
||||
get_pretty_representation(bool internal = false) const;
|
||||
@ -2494,8 +2532,9 @@ public:
|
||||
size_t size_in_bits,
|
||||
size_t alignment_in_bits);
|
||||
|
||||
function_type(size_t size_in_bits,
|
||||
size_t alignment_in_bits);
|
||||
function_type(const environment* env,
|
||||
size_t size_in_bits,
|
||||
size_t alignment_in_bits);
|
||||
|
||||
type_base_sptr
|
||||
get_return_type() const;
|
||||
@ -2576,7 +2615,8 @@ public:
|
||||
size_t size_in_bits,
|
||||
size_t alignment_in_bits);
|
||||
|
||||
method_type(size_t size_in_bits,
|
||||
method_type(const environment* env,
|
||||
size_t size_in_bits,
|
||||
size_t alignment_in_bits);
|
||||
|
||||
class_decl_sptr
|
||||
@ -2615,7 +2655,8 @@ public:
|
||||
/// Hasher.
|
||||
struct hash;
|
||||
|
||||
template_decl(const string& name,
|
||||
template_decl(const environment* env,
|
||||
const string& name,
|
||||
const location& locus,
|
||||
visibility vis = VISIBILITY_DEFAULT);
|
||||
|
||||
@ -2871,7 +2912,8 @@ public:
|
||||
struct hash;
|
||||
struct shared_ptr_hash;
|
||||
|
||||
function_tdecl(const location& locus,
|
||||
function_tdecl(const environment* env,
|
||||
const location& locus,
|
||||
visibility vis = VISIBILITY_DEFAULT,
|
||||
binding bind = BINDING_NONE);
|
||||
|
||||
@ -2924,7 +2966,8 @@ public:
|
||||
struct hash;
|
||||
struct shared_ptr_hash;
|
||||
|
||||
class_tdecl(const location& locus, visibility vis = VISIBILITY_DEFAULT);
|
||||
class_tdecl(const environment* env, const location& locus,
|
||||
visibility vis = VISIBILITY_DEFAULT);
|
||||
|
||||
class_tdecl(class_decl_sptr pattern,
|
||||
const location& locus,
|
||||
@ -3010,16 +3053,18 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
class_decl(const std::string& name, size_t size_in_bits,
|
||||
size_t align_in_bits, bool is_struct,
|
||||
const location& locus, visibility vis,
|
||||
base_specs& bases, member_types& mbrs,
|
||||
data_members& data_mbrs, member_functions& member_fns);
|
||||
class_decl(const environment* env, const string& name,
|
||||
size_t size_in_bits, size_t align_in_bits,
|
||||
bool is_struct, const location& locus,
|
||||
visibility vis, base_specs& bases,
|
||||
member_types& mbrs, data_members& data_mbrs,
|
||||
member_functions& member_fns);
|
||||
|
||||
class_decl(const std::string& name, size_t size_in_bits,
|
||||
size_t align_in_bits, bool is_struct,
|
||||
const location& locus, visibility vis);
|
||||
class_decl(const std::string& name, bool is_struct,
|
||||
class_decl(const environment* env, const string& name,
|
||||
size_t size_in_bits, size_t align_in_bits,
|
||||
bool is_struct, const location& locus, visibility vis);
|
||||
|
||||
class_decl(const environment* env, const string& name, bool is_struct,
|
||||
bool is_declaration_only = true);
|
||||
|
||||
virtual void
|
||||
@ -3593,7 +3638,8 @@ public:
|
||||
member_function_template(function_tdecl_sptr f,
|
||||
access_specifier access, bool is_static,
|
||||
bool is_constructor, bool is_const)
|
||||
: decl_base(f->get_name(), location()),
|
||||
: type_or_decl_base(f->get_environment()),
|
||||
decl_base(f->get_environment(), f->get_name(), location()),
|
||||
member_base(access, is_static), is_constructor_(is_constructor),
|
||||
is_const_(is_const), fn_tmpl_(f)
|
||||
{}
|
||||
@ -3643,9 +3689,10 @@ public:
|
||||
/// Hasher.
|
||||
struct hash;
|
||||
|
||||
member_class_template(shared_ptr<class_tdecl> c,
|
||||
member_class_template(class_tdecl_sptr c,
|
||||
access_specifier access, bool is_static)
|
||||
: decl_base(c->get_name(), location()),
|
||||
: type_or_decl_base(c->get_environment()),
|
||||
decl_base(c->get_environment(), c->get_name(), location()),
|
||||
member_base(access, is_static),
|
||||
class_tmpl_(c)
|
||||
{}
|
||||
|
@ -2697,8 +2697,9 @@ function_suppression::suppresses_function(const function_decl* fn,
|
||||
// properties matches.
|
||||
|
||||
string fn_return_type_name = fn->get_type()->get_return_type()
|
||||
? (get_type_declaration(fn->get_type()->get_return_type())
|
||||
->get_qualified_name())
|
||||
? static_cast<string>
|
||||
((get_type_declaration(fn->get_type()->get_return_type())
|
||||
->get_qualified_name()))
|
||||
: "";
|
||||
|
||||
if (!get_return_type_name().empty())
|
||||
|
@ -304,7 +304,7 @@ public:
|
||||
/// @param fn the function to calculate the ID for.
|
||||
///
|
||||
/// @return a reference to a string representing the function ID.
|
||||
const string&
|
||||
interned_string
|
||||
get_id(const function_decl& fn)
|
||||
{return fn.get_id();}
|
||||
|
||||
@ -313,7 +313,7 @@ public:
|
||||
/// @param var the variable to calculate the ID for.
|
||||
///
|
||||
/// @return a reference to a string representing the variable ID.
|
||||
const string&
|
||||
interned_string
|
||||
get_id(const var_decl& var)
|
||||
{return var.get_id();}
|
||||
|
||||
@ -1173,10 +1173,10 @@ corpus::lookup_canonical_type(const string& qualified_name) const
|
||||
|
||||
/// Constructor of the @ref corpus type.
|
||||
///
|
||||
/// @param path the path to the file containing the ABI corpus.
|
||||
///
|
||||
/// @param env the environment of the corpus.
|
||||
corpus::corpus(const string& path, ir::environment* env)
|
||||
///
|
||||
/// @param path the path to the file containing the ABI corpus.
|
||||
corpus::corpus(ir::environment* env, const string& path)
|
||||
{priv_.reset(new priv(path, env));}
|
||||
|
||||
/// Getter of the enviroment of the corpus.
|
||||
|
@ -1192,6 +1192,8 @@ get_version_for_symbol(Elf* elf_handle,
|
||||
///
|
||||
/// Use it at your own risks. :-)
|
||||
///
|
||||
///@parm env the environment we are operating from.
|
||||
///
|
||||
/// @param elf_handle the elf_handle to use.
|
||||
///
|
||||
/// @param sym_name the symbol name to look for.
|
||||
@ -1208,7 +1210,8 @@ get_version_for_symbol(Elf* elf_handle,
|
||||
/// @param syms_found a vector of symbols found with the name @p
|
||||
/// sym_name. table.
|
||||
static bool
|
||||
lookup_symbol_from_sysv_hash_tab(Elf* elf_handle,
|
||||
lookup_symbol_from_sysv_hash_tab(const environment* env,
|
||||
Elf* elf_handle,
|
||||
const string& sym_name,
|
||||
size_t ht_index,
|
||||
size_t sym_tab_index,
|
||||
@ -1272,7 +1275,8 @@ lookup_symbol_from_sysv_hash_tab(Elf* elf_handle,
|
||||
/*get_def_version=*/true, ver))
|
||||
assert(!ver.str().empty());
|
||||
elf_symbol_sptr symbol_found =
|
||||
elf_symbol::create(symbol_index,
|
||||
elf_symbol::create(env,
|
||||
symbol_index,
|
||||
sym_size,
|
||||
sym_name_str,
|
||||
sym_type,
|
||||
@ -1473,7 +1477,8 @@ setup_gnu_ht(Elf* elf_handle,
|
||||
///
|
||||
/// @return true if a symbol was actually found.
|
||||
static bool
|
||||
lookup_symbol_from_gnu_hash_tab(Elf* elf_handle,
|
||||
lookup_symbol_from_gnu_hash_tab(const environment* env,
|
||||
Elf* elf_handle,
|
||||
const string& sym_name,
|
||||
size_t ht_index,
|
||||
size_t sym_tab_index,
|
||||
@ -1547,7 +1552,7 @@ lookup_symbol_from_gnu_hash_tab(Elf* elf_handle,
|
||||
assert(!ver.str().empty());
|
||||
|
||||
elf_symbol_sptr symbol_found =
|
||||
elf_symbol::create(i, symbol.st_size, sym_name_str,
|
||||
elf_symbol::create(env, i, symbol.st_size, sym_name_str,
|
||||
sym_type, sym_binding,
|
||||
symbol.st_shndx != SHN_UNDEF,
|
||||
symbol.st_shndx == SHN_COMMON,
|
||||
@ -1571,6 +1576,8 @@ lookup_symbol_from_gnu_hash_tab(Elf* elf_handle,
|
||||
/// This function uses the elf hash table (be it the GNU hash table or
|
||||
/// the sysv hash table) for the symbol lookup.
|
||||
///
|
||||
/// @param env the environment we are operating from.
|
||||
///
|
||||
/// @param elf_handle the elf handle to use.
|
||||
///
|
||||
/// @param ht_kind the kind of hash table to use. This is returned by
|
||||
@ -1592,7 +1599,8 @@ lookup_symbol_from_gnu_hash_tab(Elf* elf_handle,
|
||||
/// @return true iff the function found the symbol from the elf hash
|
||||
/// table.
|
||||
static bool
|
||||
lookup_symbol_from_elf_hash_tab(Elf* elf_handle,
|
||||
lookup_symbol_from_elf_hash_tab(const environment* env,
|
||||
Elf* elf_handle,
|
||||
hash_table_kind ht_kind,
|
||||
size_t ht_index,
|
||||
size_t symtab_index,
|
||||
@ -1607,13 +1615,15 @@ lookup_symbol_from_elf_hash_tab(Elf* elf_handle,
|
||||
return false;
|
||||
|
||||
if (ht_kind == SYSV_HASH_TABLE_KIND)
|
||||
return lookup_symbol_from_sysv_hash_tab(elf_handle, symbol_name,
|
||||
return lookup_symbol_from_sysv_hash_tab(env,
|
||||
elf_handle, symbol_name,
|
||||
ht_index,
|
||||
symtab_index,
|
||||
demangle,
|
||||
syms_found);
|
||||
else if (ht_kind == GNU_HASH_TABLE_KIND)
|
||||
return lookup_symbol_from_gnu_hash_tab(elf_handle, symbol_name,
|
||||
return lookup_symbol_from_gnu_hash_tab(env,
|
||||
elf_handle, symbol_name,
|
||||
ht_index,
|
||||
symtab_index,
|
||||
demangle,
|
||||
@ -1623,6 +1633,9 @@ lookup_symbol_from_elf_hash_tab(Elf* elf_handle,
|
||||
|
||||
/// Lookup a symbol from the symbol table directly.
|
||||
///
|
||||
///
|
||||
/// @param env the environment we are operating from.
|
||||
///
|
||||
/// @param elf_handle the elf handle to use.
|
||||
///
|
||||
/// @param sym_name the name of the symbol to look up.
|
||||
@ -1643,7 +1656,8 @@ lookup_symbol_from_elf_hash_tab(Elf* elf_handle,
|
||||
///
|
||||
/// @return true iff the symbol was found.
|
||||
static bool
|
||||
lookup_symbol_from_symtab(Elf* elf_handle,
|
||||
lookup_symbol_from_symtab(const environment* env,
|
||||
Elf* elf_handle,
|
||||
const string& sym_name,
|
||||
size_t sym_tab_index,
|
||||
bool demangle,
|
||||
@ -1687,7 +1701,8 @@ lookup_symbol_from_symtab(Elf* elf_handle,
|
||||
ver))
|
||||
assert(!ver.str().empty());
|
||||
elf_symbol_sptr symbol_found =
|
||||
elf_symbol::create(i, sym->st_size, name_str, sym_type,
|
||||
elf_symbol::create(env, i, sym->st_size,
|
||||
name_str, sym_type,
|
||||
sym_binding, sym_is_defined,
|
||||
sym_is_common, ver);
|
||||
syms_found.push_back(symbol_found);
|
||||
@ -1704,6 +1719,8 @@ lookup_symbol_from_symtab(Elf* elf_handle,
|
||||
/// Look into the symbol tables of the underlying elf file and see
|
||||
/// if we find a given symbol.
|
||||
///
|
||||
/// @param env the environment we are operating from.
|
||||
///
|
||||
/// @param symbol_name the name of the symbol to look for.
|
||||
///
|
||||
/// @param demangle if true, try to demangle the symbol name found in
|
||||
@ -1727,7 +1744,8 @@ lookup_symbol_from_symtab(Elf* elf_handle,
|
||||
///
|
||||
/// @return true iff a symbol with the name @p symbol_name was found.
|
||||
static bool
|
||||
lookup_symbol_from_elf(Elf* elf_handle,
|
||||
lookup_symbol_from_elf(const environment* env,
|
||||
Elf* elf_handle,
|
||||
const string& symbol_name,
|
||||
bool demangle,
|
||||
vector<elf_symbol_sptr>& syms_found)
|
||||
@ -1745,14 +1763,16 @@ lookup_symbol_from_elf(Elf* elf_handle,
|
||||
if (!find_symbol_table_section_index(elf_handle, symbol_table_index))
|
||||
return false;
|
||||
|
||||
return lookup_symbol_from_symtab(elf_handle,
|
||||
return lookup_symbol_from_symtab(env,
|
||||
elf_handle,
|
||||
symbol_name,
|
||||
symbol_table_index,
|
||||
demangle,
|
||||
syms_found);
|
||||
}
|
||||
|
||||
return lookup_symbol_from_elf_hash_tab(elf_handle,
|
||||
return lookup_symbol_from_elf_hash_tab(env,
|
||||
elf_handle,
|
||||
ht_kind,
|
||||
hash_table_index,
|
||||
symbol_table_index,
|
||||
@ -1764,6 +1784,8 @@ lookup_symbol_from_elf(Elf* elf_handle,
|
||||
/// Look into the symbol tables of the underlying elf file and see if
|
||||
/// we find a given public (global or weak) symbol of function type.
|
||||
///
|
||||
/// @param env the environment we are operating from.
|
||||
///
|
||||
/// @param elf_handle the elf handle to use for the query.
|
||||
///
|
||||
/// @param symbol_name the function symbol to look for.
|
||||
@ -1773,17 +1795,16 @@ lookup_symbol_from_elf(Elf* elf_handle,
|
||||
///
|
||||
/// @return true iff the symbol was found.
|
||||
static bool
|
||||
lookup_public_function_symbol_from_elf(Elf* elf_handle,
|
||||
lookup_public_function_symbol_from_elf(const environment* env,
|
||||
Elf* elf_handle,
|
||||
const string& symbol_name,
|
||||
vector<elf_symbol_sptr>& func_syms)
|
||||
{
|
||||
vector<elf_symbol_sptr> syms_found;
|
||||
bool found = false;
|
||||
|
||||
if (lookup_symbol_from_elf(elf_handle,
|
||||
symbol_name,
|
||||
/*demangle=*/false,
|
||||
syms_found))
|
||||
if (lookup_symbol_from_elf(env, elf_handle, symbol_name,
|
||||
/*demangle=*/false, syms_found))
|
||||
{
|
||||
for (vector<elf_symbol_sptr>::const_iterator i = syms_found.begin();
|
||||
i != syms_found.end();
|
||||
@ -1810,6 +1831,8 @@ lookup_public_function_symbol_from_elf(Elf* elf_handle,
|
||||
/// Look into the symbol tables of the underlying elf file and see if
|
||||
/// we find a given public (global or weak) symbol of variable type.
|
||||
///
|
||||
/// @param env the environment we are operating from.
|
||||
///
|
||||
/// @param elf the elf handle to use for the query.
|
||||
///
|
||||
/// @param symname the variable symbol to look for.
|
||||
@ -1818,17 +1841,15 @@ lookup_public_function_symbol_from_elf(Elf* elf_handle,
|
||||
///
|
||||
/// @return true iff symbol @p symname was found.
|
||||
static bool
|
||||
lookup_public_variable_symbol_from_elf(Elf* elf,
|
||||
lookup_public_variable_symbol_from_elf(const environment* env,
|
||||
Elf* elf,
|
||||
const string& symname,
|
||||
vector<elf_symbol_sptr>& var_syms)
|
||||
{
|
||||
vector<elf_symbol_sptr> syms_found;
|
||||
bool found = false;
|
||||
|
||||
if (lookup_symbol_from_elf(elf,
|
||||
symname,
|
||||
/*demangle=*/false,
|
||||
syms_found))
|
||||
if (lookup_symbol_from_elf(env, elf, symname, /*demangle=*/false, syms_found))
|
||||
{
|
||||
for (vector<elf_symbol_sptr>::const_iterator i = syms_found.begin();
|
||||
i != syms_found.end();
|
||||
@ -3087,7 +3108,8 @@ public:
|
||||
bool demangle,
|
||||
vector<elf_symbol_sptr>& syms) const
|
||||
{
|
||||
return dwarf_reader::lookup_symbol_from_elf(elf_handle(),
|
||||
return dwarf_reader::lookup_symbol_from_elf(env(),
|
||||
elf_handle(),
|
||||
symbol_name,
|
||||
demangle,
|
||||
syms);
|
||||
@ -3139,7 +3161,7 @@ public:
|
||||
v);
|
||||
|
||||
elf_symbol_sptr sym =
|
||||
elf_symbol::create(symbol_index, s->st_size, name_str,
|
||||
elf_symbol::create(env(), symbol_index, s->st_size, name_str,
|
||||
stt_to_elf_symbol_type(GELF_ST_TYPE(s->st_info)),
|
||||
stb_to_elf_symbol_binding(GELF_ST_BIND(s->st_info)),
|
||||
sym_is_defined, sym_is_common, v);
|
||||
@ -3205,7 +3227,8 @@ public:
|
||||
lookup_public_function_symbol_from_elf(const string& sym_name,
|
||||
vector<elf_symbol_sptr>& syms)
|
||||
{
|
||||
return dwarf_reader::lookup_public_function_symbol_from_elf(elf_handle(),
|
||||
return dwarf_reader::lookup_public_function_symbol_from_elf(env(),
|
||||
elf_handle(),
|
||||
sym_name,
|
||||
syms);
|
||||
}
|
||||
@ -3223,7 +3246,8 @@ public:
|
||||
lookup_public_variable_symbol_from_elf(const string& sym_name,
|
||||
vector<elf_symbol_sptr>& syms)
|
||||
{
|
||||
return dwarf_reader::lookup_public_variable_symbol_from_elf(elf_handle(),
|
||||
return dwarf_reader::lookup_public_variable_symbol_from_elf(env(),
|
||||
elf_handle(),
|
||||
sym_name,
|
||||
syms);
|
||||
}
|
||||
@ -6651,8 +6675,8 @@ 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,
|
||||
ctxt.env(),
|
||||
result.reset(new translation_unit(ctxt.env(),
|
||||
path,
|
||||
address_size));
|
||||
|
||||
uint64_t l = 0;
|
||||
@ -6782,7 +6806,7 @@ build_namespace_decl_and_add_to_ir(read_context& ctxt,
|
||||
location loc;
|
||||
die_loc_and_name(ctxt, die, loc, name, linkage_name);
|
||||
|
||||
result.reset(new namespace_decl(name, loc));
|
||||
result.reset(new namespace_decl(ctxt.env(), name, loc));
|
||||
add_decl_to_scope(result, scope.get());
|
||||
ctxt.associate_die_to_decl(dwarf_dieoffset(die), die_is_from_alt_di, result);
|
||||
|
||||
@ -6835,9 +6859,8 @@ build_type_decl(read_context& ctxt,
|
||||
location loc;
|
||||
die_loc_and_name(ctxt, die, loc, type_name, linkage_name);
|
||||
|
||||
result.reset(new type_decl(type_name, bit_size,
|
||||
/*alignment=*/0, loc,
|
||||
linkage_name));
|
||||
result.reset(new type_decl(ctxt.env(), type_name, bit_size,
|
||||
/*alignment=*/0, loc, linkage_name));
|
||||
ctxt.associate_die_to_type(dwarf_dieoffset(die),
|
||||
die_is_from_alt_di,
|
||||
result);
|
||||
@ -6907,7 +6930,7 @@ build_enum_type(read_context& ctxt,
|
||||
die_loc_and_name(ctxt, &child, loc, n, m);
|
||||
uint64_t val = 0;
|
||||
die_unsigned_constant_attribute(&child, DW_AT_const_value, val);
|
||||
enms.push_back(enum_type_decl::enumerator(n, val));
|
||||
enms.push_back(enum_type_decl::enumerator(ctxt.env(), n, val));
|
||||
}
|
||||
while (dwarf_siblingof(&child, &child) == 0);
|
||||
}
|
||||
@ -6916,7 +6939,7 @@ build_enum_type(read_context& ctxt,
|
||||
// underlying type, so let's create an artificial one here, which
|
||||
// sole purpose is to be passed to the constructor of the
|
||||
// enum_type_decl type.
|
||||
type_decl_sptr t(new type_decl(underlying_type_name,
|
||||
type_decl_sptr t(new type_decl(ctxt.env(), underlying_type_name,
|
||||
size, size, location()));
|
||||
t->set_is_anonymous(enum_underlying_type_is_anonymous);
|
||||
translation_unit_sptr tu = ctxt.cur_tu();
|
||||
@ -6958,7 +6981,7 @@ finish_member_function_reading(Dwarf_Die* die,
|
||||
|
||||
bool is_ctor = (f->get_name() == klass->get_name());
|
||||
bool is_dtor = (!f->get_name().empty()
|
||||
&& f->get_name()[0] == '~');
|
||||
&& static_cast<string>(f->get_name())[0] == '~');
|
||||
bool is_virtual = die_is_virtual(die);
|
||||
size_t vindex = 0;
|
||||
if (is_virtual)
|
||||
@ -7097,7 +7120,8 @@ build_class_type_and_add_to_ir(read_context& ctxt,
|
||||
}
|
||||
else
|
||||
{
|
||||
result.reset(new class_decl(name, size, /*alignment=*/0, is_struct, loc,
|
||||
result.reset(new class_decl(ctxt.env(), name, size,
|
||||
/*alignment=*/0, is_struct, loc,
|
||||
decl_base::VISIBILITY_DEFAULT));
|
||||
result->set_is_anonymous(is_anonymous);
|
||||
|
||||
@ -7647,7 +7671,7 @@ build_function_type(read_context& ctxt,
|
||||
? new method_type(is_method,
|
||||
tu->get_address_size(),
|
||||
/*alignment=*/0)
|
||||
: new function_type(tu->get_address_size(),
|
||||
: new function_type(ctxt.env(), tu->get_address_size(),
|
||||
/*alignment=*/0));
|
||||
tu->bind_function_type_life_time(result);
|
||||
ctxt.associate_die_to_type(dwarf_dieoffset(die),
|
||||
@ -8154,7 +8178,7 @@ read_debug_info_into_corpus(read_context& ctxt)
|
||||
|
||||
if (!ctxt.current_corpus())
|
||||
{
|
||||
corpus_sptr corp (new corpus(ctxt.elf_path(), ctxt.env()));
|
||||
corpus_sptr corp (new corpus(ctxt.env(), ctxt.elf_path()));
|
||||
ctxt.current_corpus(corp);
|
||||
if (!ctxt.env())
|
||||
ctxt.env(corp->get_environment());
|
||||
@ -9060,6 +9084,8 @@ read_corpus_from_elf(const std::string& elf_path,
|
||||
/// Look into the symbol tables of a given elf file and see if we find
|
||||
/// a given symbol.
|
||||
///
|
||||
/// @param env the environment we are operating from.
|
||||
///
|
||||
/// @param elf_path the path to the elf file to consider.
|
||||
///
|
||||
/// @param symbol_name the name of the symbol to look for.
|
||||
@ -9072,7 +9098,8 @@ read_corpus_from_elf(const std::string& elf_path,
|
||||
/// @return true iff the symbol was found among the publicly exported
|
||||
/// symbols of the ELF file.
|
||||
bool
|
||||
lookup_symbol_from_elf(const string& elf_path,
|
||||
lookup_symbol_from_elf(const environment* env,
|
||||
const string& elf_path,
|
||||
const string& symbol_name,
|
||||
bool demangle,
|
||||
vector<elf_symbol_sptr>& syms)
|
||||
@ -9093,7 +9120,7 @@ lookup_symbol_from_elf(const string& elf_path,
|
||||
if (elf == 0)
|
||||
return false;
|
||||
|
||||
bool value = lookup_symbol_from_elf(elf, symbol_name,
|
||||
bool value = lookup_symbol_from_elf(env, elf, symbol_name,
|
||||
demangle, syms);
|
||||
elf_end(elf);
|
||||
close(fd);
|
||||
@ -9104,6 +9131,8 @@ lookup_symbol_from_elf(const string& elf_path,
|
||||
/// Look into the symbol tables of an elf file to see if a public
|
||||
/// function of a given name is found.
|
||||
///
|
||||
/// @param env the environment we are operating from.
|
||||
///
|
||||
/// @param elf_path the path to the elf file to consider.
|
||||
///
|
||||
/// @param symbol_name the name of the function to look for.
|
||||
@ -9114,7 +9143,8 @@ lookup_symbol_from_elf(const string& elf_path,
|
||||
/// @return true iff a function with symbol name @p symbol_name is
|
||||
/// found.
|
||||
bool
|
||||
lookup_public_function_symbol_from_elf(const string& path,
|
||||
lookup_public_function_symbol_from_elf(const environment* env,
|
||||
const string& path,
|
||||
const string& symname,
|
||||
vector<elf_symbol_sptr>& syms)
|
||||
{
|
||||
@ -9133,7 +9163,7 @@ lookup_public_function_symbol_from_elf(const string& path,
|
||||
if (elf == 0)
|
||||
return false;
|
||||
|
||||
bool value = lookup_public_function_symbol_from_elf(elf, symname, syms);
|
||||
bool value = lookup_public_function_symbol_from_elf(env, elf, symname, syms);
|
||||
elf_end(elf);
|
||||
close(fd);
|
||||
|
||||
|
1205
src/abg-ir.cc
1205
src/abg-ir.cc
File diff suppressed because it is too large
Load Diff
@ -1127,7 +1127,7 @@ read_translation_unit(read_context& ctxt, xmlNodePtr node)
|
||||
|
||||
ctxt.set_corpus_node(node);
|
||||
|
||||
tu.reset(new translation_unit("", ctxt.get_environment()));
|
||||
tu.reset(new translation_unit(ctxt.get_environment(), ""));
|
||||
tu->set_corpus(ctxt.get_corpus().get());
|
||||
|
||||
xml::xml_char_sptr addrsize_str =
|
||||
@ -1465,7 +1465,7 @@ read_corpus_from_input(read_context& ctxt)
|
||||
|
||||
if (!ctxt.get_corpus())
|
||||
{
|
||||
corpus_sptr c(new corpus("", ctxt.get_environment()));
|
||||
corpus_sptr c(new corpus(ctxt.get_environment(), ""));
|
||||
ctxt.set_corpus(c);
|
||||
}
|
||||
|
||||
@ -2059,7 +2059,8 @@ build_namespace_decl(read_context& ctxt,
|
||||
location loc;
|
||||
read_location(ctxt, node, loc);
|
||||
|
||||
shared_ptr<namespace_decl> decl(new namespace_decl(name, loc));
|
||||
const environment* env = ctxt.get_environment();
|
||||
namespace_decl_sptr decl(new namespace_decl(env, name, loc));
|
||||
ctxt.push_decl_to_current_scope(decl, add_to_current_scope);
|
||||
ctxt.map_xml_node_to_decl(node, decl);
|
||||
|
||||
@ -2078,11 +2079,13 @@ build_namespace_decl(read_context& ctxt,
|
||||
/// Build an instance of @ref elf_symbol from an XML element node
|
||||
/// which name is 'elf-symbol'.
|
||||
///
|
||||
/// @param ctxt the context used for reading the XML input.
|
||||
///
|
||||
/// @param node the XML node to read.
|
||||
///
|
||||
/// @return the @ref elf_symbol built, or nil if it couldn't be built.
|
||||
static elf_symbol_sptr
|
||||
build_elf_symbol(read_context&, const xmlNodePtr node)
|
||||
build_elf_symbol(read_context& ctxt, const xmlNodePtr node)
|
||||
{
|
||||
elf_symbol_sptr nil;
|
||||
|
||||
@ -2142,8 +2145,9 @@ build_elf_symbol(read_context&, const xmlNodePtr node)
|
||||
|
||||
elf_symbol::version version(version_string, is_default_version);
|
||||
|
||||
elf_symbol_sptr e = elf_symbol::create(/*index=*/0, size,
|
||||
name, type, binding,
|
||||
const environment* env = ctxt.get_environment();
|
||||
elf_symbol_sptr e = elf_symbol::create(env, /*index=*/0, size,
|
||||
name, type, binding,
|
||||
is_defined, is_common,
|
||||
version);
|
||||
return e;
|
||||
@ -2344,6 +2348,7 @@ build_function_parameter(read_context& ctxt, const xmlNodePtr node)
|
||||
type = ctxt.build_or_get_type_decl(type_id, true);
|
||||
}
|
||||
assert(type);
|
||||
assert(type->get_environment() == ctxt.get_environment());
|
||||
|
||||
string name;
|
||||
if (xml_char_sptr a = xml::build_sptr(xmlGetProp(node, BAD_CAST("name"))))
|
||||
@ -2412,8 +2417,10 @@ build_function_decl(read_context& ctxt,
|
||||
location loc;
|
||||
read_location(ctxt, node, loc);
|
||||
|
||||
std::vector<shared_ptr<function_decl::parameter> > parms;
|
||||
type_base_sptr return_type;
|
||||
environment* env = ctxt.get_environment();
|
||||
assert(env);
|
||||
std::vector<function_decl::parameter_sptr> parms;
|
||||
type_base_sptr return_type = env->get_void_type_decl();
|
||||
|
||||
for (xmlNodePtr n = node->children; n ; n = n->next)
|
||||
{
|
||||
@ -2437,22 +2444,24 @@ build_function_decl(read_context& ctxt,
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<function_type> fn_type(as_method_decl
|
||||
? new method_type(return_type,
|
||||
as_method_decl,
|
||||
parms, size, align)
|
||||
: new function_type(return_type,
|
||||
parms, size, align));
|
||||
assert(return_type);
|
||||
|
||||
shared_ptr<function_decl> fn_decl(as_method_decl
|
||||
? new class_decl::method_decl
|
||||
(name, fn_type,
|
||||
declared_inline, loc,
|
||||
mangled_name, vis, bind)
|
||||
: new function_decl(name, fn_type,
|
||||
declared_inline, loc,
|
||||
mangled_name, vis,
|
||||
bind));
|
||||
function_type_sptr fn_type(as_method_decl
|
||||
? new method_type(return_type,
|
||||
as_method_decl,
|
||||
parms, size, align)
|
||||
: new function_type(return_type,
|
||||
parms, size, align));
|
||||
|
||||
function_decl_sptr fn_decl(as_method_decl
|
||||
? new class_decl::method_decl
|
||||
(name, fn_type,
|
||||
declared_inline, loc,
|
||||
mangled_name, vis, bind)
|
||||
: new function_decl(name, fn_type,
|
||||
declared_inline, loc,
|
||||
mangled_name, vis,
|
||||
bind));
|
||||
|
||||
ctxt.push_decl_to_current_scope(fn_decl, add_to_current_scope);
|
||||
|
||||
@ -2597,9 +2606,9 @@ build_type_decl(read_context& ctxt,
|
||||
return ty;
|
||||
}
|
||||
|
||||
type_decl_sptr decl(new type_decl(name, size_in_bits,
|
||||
alignment_in_bits,
|
||||
loc));
|
||||
const environment* env = ctxt.get_environment();
|
||||
type_decl_sptr decl(new type_decl(env, name, size_in_bits,
|
||||
alignment_in_bits, loc));
|
||||
decl->set_is_anonymous(is_anonymous);
|
||||
if (ctxt.push_and_key_type_decl(decl, id, add_to_current_scope))
|
||||
{
|
||||
@ -2910,8 +2919,10 @@ build_function_type(read_context& ctxt,
|
||||
size_t size = 0, align = 0;
|
||||
read_size_and_alignment(node, size, align);
|
||||
|
||||
environment* env = ctxt.get_environment();
|
||||
assert(env);
|
||||
std::vector<shared_ptr<function_decl::parameter> > parms;
|
||||
type_base_sptr return_type;
|
||||
type_base_sptr return_type = env->get_void_type_decl();;
|
||||
|
||||
function_type_sptr fn_type(new function_type(return_type,
|
||||
parms, size, align));
|
||||
@ -3170,6 +3181,9 @@ build_enum_type_decl(read_context& ctxt,
|
||||
|
||||
assert(!id.empty());
|
||||
|
||||
const environment* env = ctxt.get_environment();
|
||||
assert(env);
|
||||
|
||||
string base_type_id;
|
||||
enum_type_decl::enumerators enums;
|
||||
for (xmlNodePtr n = node->children; n; n = n->next)
|
||||
@ -3202,17 +3216,17 @@ build_enum_type_decl(read_context& ctxt,
|
||||
return nil;
|
||||
}
|
||||
|
||||
enums.push_back(enum_type_decl::enumerator(name, value));
|
||||
enums.push_back(enum_type_decl::enumerator(env, name, value));
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<type_base> underlying_type =
|
||||
type_base_sptr underlying_type =
|
||||
ctxt.build_or_get_type_decl(base_type_id, true);
|
||||
assert(underlying_type);
|
||||
|
||||
shared_ptr<enum_type_decl> t(new enum_type_decl(name, loc,
|
||||
underlying_type,
|
||||
enums, linkage_name));
|
||||
enum_type_decl_sptr t(new enum_type_decl(name, loc,
|
||||
underlying_type,
|
||||
enums, linkage_name));
|
||||
if (ctxt.push_and_key_type_decl(t, id, add_to_current_scope))
|
||||
{
|
||||
ctxt.map_xml_node_to_decl(node, t);
|
||||
@ -3391,6 +3405,9 @@ build_class_decl(read_context& ctxt,
|
||||
return previous_declaration;
|
||||
}
|
||||
|
||||
const environment* env = ctxt.get_environment();
|
||||
assert(env);
|
||||
|
||||
if (!is_decl_only && previous_definition)
|
||||
// We are in the case where we've read this class definition
|
||||
// before, but we might need to update it to add some new stuff to
|
||||
@ -3401,11 +3418,11 @@ build_class_decl(read_context& ctxt,
|
||||
else
|
||||
{
|
||||
if (is_decl_only)
|
||||
decl.reset(new class_decl(name, is_struct));
|
||||
decl.reset(new class_decl(env, name, is_struct));
|
||||
else
|
||||
decl.reset(new class_decl(name, size_in_bits, alignment_in_bits,
|
||||
is_struct, loc, vis, bases, mbrs, data_mbrs,
|
||||
mbr_functions));
|
||||
decl.reset(new class_decl(env, name, size_in_bits, alignment_in_bits,
|
||||
is_struct, loc, vis, bases, mbrs,
|
||||
data_mbrs, mbr_functions));
|
||||
decl->set_is_anonymous(is_anonymous);
|
||||
}
|
||||
|
||||
@ -3724,7 +3741,10 @@ build_function_tdecl(read_context& ctxt,
|
||||
decl_base::binding bind = decl_base::BINDING_NONE;
|
||||
read_binding(node, bind);
|
||||
|
||||
function_tdecl_sptr fn_tmpl_decl(new function_tdecl(loc, vis, bind));
|
||||
const environment* env = ctxt.get_environment();
|
||||
assert(env);
|
||||
|
||||
function_tdecl_sptr fn_tmpl_decl(new function_tdecl(env, loc, vis, bind));
|
||||
|
||||
ctxt.push_decl_to_current_scope(fn_tmpl_decl, add_to_current_scope);
|
||||
|
||||
@ -3785,7 +3805,10 @@ build_class_tdecl(read_context& ctxt,
|
||||
decl_base::visibility vis = decl_base::VISIBILITY_NONE;
|
||||
read_visibility(node, vis);
|
||||
|
||||
class_tdecl_sptr class_tmpl (new class_tdecl(loc, vis));
|
||||
const environment* env = ctxt.get_environment();
|
||||
assert(env);
|
||||
|
||||
class_tdecl_sptr class_tmpl (new class_tdecl(env, loc, vis));
|
||||
|
||||
ctxt.push_decl_to_current_scope(class_tmpl, add_to_current_scope);
|
||||
|
||||
@ -4534,7 +4557,7 @@ read_corpus_from_native_xml(std::istream* in,
|
||||
environment* env)
|
||||
{
|
||||
read_context read_ctxt(xml::new_reader_from_istream(in), env);
|
||||
corpus_sptr corp(new corpus("", read_ctxt.get_environment()));
|
||||
corpus_sptr corp(new corpus(env, ""));
|
||||
read_ctxt.set_corpus(corp);
|
||||
return read_corpus_from_input(read_ctxt);
|
||||
}
|
||||
|
@ -77,34 +77,45 @@ namespace xml_writer
|
||||
|
||||
class id_manager
|
||||
{
|
||||
unsigned long long m_cur_id;
|
||||
const environment* m_env;
|
||||
mutable unsigned long long m_cur_id;
|
||||
|
||||
unsigned long long
|
||||
get_new_id()
|
||||
get_new_id() const
|
||||
{ return ++m_cur_id; }
|
||||
|
||||
public:
|
||||
id_manager() : m_cur_id(0) { }
|
||||
id_manager(const environment* env)
|
||||
: m_env(env),
|
||||
m_cur_id(0) {}
|
||||
|
||||
const environment*
|
||||
get_environment() const
|
||||
{return m_env;}
|
||||
|
||||
/// Return a unique string representing a numerical id.
|
||||
string
|
||||
get_id()
|
||||
interned_string
|
||||
get_id() const
|
||||
{
|
||||
ostringstream o;
|
||||
o << get_new_id();
|
||||
return o.str();
|
||||
const environment* env = get_environment();
|
||||
assert(env);
|
||||
return env->intern(o.str());
|
||||
}
|
||||
|
||||
/// Return a unique string representing a numerical ID, prefixed by
|
||||
/// prefix.
|
||||
///
|
||||
/// @param prefix the prefix of the returned unique id.
|
||||
string
|
||||
get_id_with_prefix(const string& prefix)
|
||||
interned_string
|
||||
get_id_with_prefix(const string& prefix) const
|
||||
{
|
||||
ostringstream o;
|
||||
o << prefix << get_new_id();
|
||||
return o.str();
|
||||
const environment* env = get_environment();
|
||||
assert(env);
|
||||
return env->intern(o.str());
|
||||
}
|
||||
};
|
||||
|
||||
@ -119,7 +130,7 @@ struct type_hasher
|
||||
/// A convenience typedef for a map that associates a pointer to type
|
||||
/// to a string. The pointer to type is hashed as fast as possible.
|
||||
typedef unordered_map<type_base*,
|
||||
string,
|
||||
interned_string,
|
||||
type_hasher,
|
||||
abigail::diff_utils::deep_ptr_eq_functor> type_ptr_map;
|
||||
|
||||
@ -133,11 +144,13 @@ typedef unordered_map<shared_ptr<class_tdecl>,
|
||||
|
||||
class write_context
|
||||
{
|
||||
const environment* m_env;
|
||||
id_manager m_id_manager;
|
||||
config m_config;
|
||||
ostream& m_ostream;
|
||||
type_ptr_map m_type_id_map;
|
||||
unordered_map<string, bool> m_emitted_type_id_map;
|
||||
mutable type_ptr_map m_type_id_map;
|
||||
mutable unordered_map<interned_string,
|
||||
bool, hash_interned_string> m_emitted_type_id_map;
|
||||
type_ptr_map m_emitted_decl_only_map;
|
||||
// A map of types that are referenced by emitted pointers,
|
||||
// references or typedefs
|
||||
@ -151,9 +164,24 @@ class write_context
|
||||
|
||||
public:
|
||||
|
||||
write_context(ostream& os) : m_ostream(os)
|
||||
/// Constructor.
|
||||
///
|
||||
/// @param env the enviroment we are operating from.
|
||||
///
|
||||
/// @param os the output stream to write to.
|
||||
write_context(const environment* env, ostream& os)
|
||||
: m_env(env),
|
||||
m_id_manager(env),
|
||||
m_ostream(os)
|
||||
{}
|
||||
|
||||
/// Getter of the environment we are operating from.
|
||||
///
|
||||
/// @return the environment we are operating from.
|
||||
const environment*
|
||||
get_environment() const
|
||||
{return m_env;}
|
||||
|
||||
const config&
|
||||
get_config() const
|
||||
{return m_config;}
|
||||
@ -162,6 +190,14 @@ public:
|
||||
get_ostream()
|
||||
{return m_ostream;}
|
||||
|
||||
/// Getter of the @ref id_manager.
|
||||
///
|
||||
/// @return the @ref id_manager used by the current instance of @ref
|
||||
/// write_context.
|
||||
const id_manager&
|
||||
get_id_manager() const
|
||||
{return m_id_manager;}
|
||||
|
||||
id_manager&
|
||||
get_id_manager()
|
||||
{return m_id_manager;}
|
||||
@ -180,21 +216,22 @@ public:
|
||||
/// in a hash table, hashing the type. So if the type has no id
|
||||
/// associated to it, create a new one and return it. Otherwise,
|
||||
/// return the existing id for that type.
|
||||
string
|
||||
get_id_for_type(shared_ptr<type_base> t)
|
||||
interned_string
|
||||
get_id_for_type(const type_base_sptr& t)
|
||||
{return get_id_for_type(t.get());}
|
||||
|
||||
/// Associate a unique id to a given type. For that, put the type
|
||||
/// in a hash table, hashing the type. So if the type has no id
|
||||
/// associated to it, create a new one and return it. Otherwise,
|
||||
/// return the existing id for that type.
|
||||
string
|
||||
get_id_for_type(type_base* t)
|
||||
interned_string
|
||||
get_id_for_type(type_base* t) const
|
||||
{
|
||||
type_ptr_map::const_iterator it = m_type_id_map.find(t);
|
||||
if (it == m_type_id_map.end())
|
||||
{
|
||||
string id = get_id_manager().get_id_with_prefix("type-id-");
|
||||
interned_string id =
|
||||
get_id_manager().get_id_with_prefix("type-id-");
|
||||
m_type_id_map[t] = id;
|
||||
return id;
|
||||
}
|
||||
@ -237,7 +274,11 @@ public:
|
||||
/// @param id the ID of the type.
|
||||
void
|
||||
record_type_id_as_emitted(const string& id)
|
||||
{m_emitted_type_id_map[id] = true;}
|
||||
{
|
||||
const environment* env = get_environment();
|
||||
assert(env);
|
||||
m_emitted_type_id_map[env->intern(id)] = true;
|
||||
}
|
||||
|
||||
/// Getter of the map of types that were referenced by a pointer,
|
||||
/// reference or typedef.
|
||||
@ -254,7 +295,7 @@ public:
|
||||
/// @param t a shared pointer to a type
|
||||
void
|
||||
record_type_as_referenced(const type_base_sptr& t)
|
||||
{m_referenced_types_map[t.get()] = true;}
|
||||
{m_referenced_types_map[t.get()] = interned_string();}
|
||||
|
||||
/// Test if a given type has been referenced by a pointer, a
|
||||
/// reference or a typedef type that was emitted to the XML output.
|
||||
@ -358,7 +399,7 @@ public:
|
||||
/// @return true if the type has already been emitted, false
|
||||
/// otherwise.
|
||||
bool
|
||||
type_id_is_emitted(const string& id)
|
||||
type_id_is_emitted(const interned_string& id)
|
||||
{return m_emitted_type_id_map.find(id) != m_emitted_type_id_map.end();}
|
||||
|
||||
/// Test if a given type has been written out to the XML output.
|
||||
@ -372,7 +413,7 @@ public:
|
||||
{
|
||||
if (!type_has_existing_id(t))
|
||||
return false;
|
||||
string id = get_id_for_type(t);
|
||||
const interned_string& id = get_id_for_type(t);
|
||||
return type_id_is_emitted(id);
|
||||
}
|
||||
|
||||
@ -387,7 +428,7 @@ public:
|
||||
{
|
||||
class_decl* cl = is_class_type(t);
|
||||
assert(cl && cl->get_is_declaration_only());
|
||||
m_emitted_decl_only_map[t] = true;
|
||||
m_emitted_decl_only_map[t] = interned_string();
|
||||
}
|
||||
|
||||
/// Record a declaration-only class as being emitted.
|
||||
@ -1257,7 +1298,7 @@ write_translation_unit(const translation_unit& tu,
|
||||
&& !ctxt.decl_only_type_is_emitted(type))
|
||||
// A referenced type that was not emitted at all must be
|
||||
// emitted now.
|
||||
referenced_types_to_emit[type.get()] = "";
|
||||
referenced_types_to_emit[type.get()] = interned_string();
|
||||
}
|
||||
|
||||
// Ok, now let's emit the referenced type for good.
|
||||
@ -1310,7 +1351,7 @@ write_translation_unit(const translation_unit& tu,
|
||||
if (get_type_declaration(type)
|
||||
&& !ctxt.type_is_emitted(type)
|
||||
&& !ctxt.decl_only_type_is_emitted(type))
|
||||
referenced_types_to_emit[type.get()] = "";
|
||||
referenced_types_to_emit[type.get()] = interned_string();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1350,8 +1391,8 @@ write_translation_unit(const translation_unit& tu,
|
||||
unsigned indent,
|
||||
std::ostream& out)
|
||||
{
|
||||
write_context ctxt(out);
|
||||
return write_translation_unit(tu, ctxt, indent);
|
||||
write_context ctxt(tu.get_environment(), out);
|
||||
return write_translation_unit(tu, ctxt, indent);
|
||||
}
|
||||
|
||||
/// Serialize a translation unit to a file.
|
||||
@ -3141,7 +3182,7 @@ write_corpus_to_native_xml(const corpus_sptr corpus,
|
||||
if (!corpus)
|
||||
return false;
|
||||
|
||||
write_context ctxt(out);
|
||||
write_context ctxt(corpus->get_environment(), out);
|
||||
|
||||
do_indent_to_level(ctxt, indent, 0);
|
||||
out << "<abi-corpus";
|
||||
@ -3267,7 +3308,7 @@ using namespace abigail::ir;
|
||||
void
|
||||
dump(const decl_base_sptr d, std::ostream& o)
|
||||
{
|
||||
xml_writer::write_context ctxt(o);
|
||||
xml_writer::write_context ctxt(d->get_environment(), o);
|
||||
write_decl(d, ctxt, /*indent=*/0);
|
||||
o << "\n";
|
||||
}
|
||||
@ -3303,7 +3344,7 @@ dump(const type_base_sptr t)
|
||||
void
|
||||
dump(const var_decl_sptr v, std::ostream& o)
|
||||
{
|
||||
xml_writer::write_context ctxt(o);
|
||||
xml_writer::write_context ctxt(v->get_environment(), o);
|
||||
write_var_decl(v, ctxt, /*linkage_name*/true, /*indent=*/0);
|
||||
cerr << "\n";
|
||||
}
|
||||
@ -3323,7 +3364,7 @@ dump(const var_decl_sptr v)
|
||||
void
|
||||
dump(const translation_unit& t, std::ostream& o)
|
||||
{
|
||||
xml_writer::write_context ctxt(o);
|
||||
xml_writer::write_context ctxt(t.get_environment(), o);
|
||||
write_translation_unit(t, ctxt, /*indent=*/0);
|
||||
o << "\n";
|
||||
}
|
||||
|
@ -7,13 +7,15 @@
|
||||
<parameter type-id='type-id-3' name='l' filepath='/home/dodji/test-bidw/test-v0.cc' line='5' column='1'/>
|
||||
<return type-id='type-id-1'/>
|
||||
</function-decl>
|
||||
<type-decl name='void' id='type-id-4'/>
|
||||
<function-decl name='bar' mangled-name='_Z3bariz' filepath='/home/dodji/test-bidw/test-v0.cc' line='9' column='1' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='64'>
|
||||
<parameter type-id='type-id-3' name='c' filepath='/home/dodji/test-bidw/test-v0.cc' line='9' column='1'/>
|
||||
<parameter is-variadic='yes'/>
|
||||
</function-decl>
|
||||
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-4'/>
|
||||
<function-decl name='main' filepath='/home/dodji/test-bidw/test-v0.cc' line='17' column='1' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='64'>
|
||||
<return type-id='type-id-4'/>
|
||||
</function-decl>
|
||||
<var-decl name='global' type-id='type-id-4' visibility='default' filepath='/home/dodji/test-bidw/test-v0.cc' line='2' column='1'/>
|
||||
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-5'/>
|
||||
<function-decl name='main' filepath='/home/dodji/test-bidw/test-v0.cc' line='17' column='1' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='64'>
|
||||
<return type-id='type-id-5'/>
|
||||
</function-decl>
|
||||
<var-decl name='global' type-id='type-id-5' visibility='default' filepath='/home/dodji/test-bidw/test-v0.cc' line='2' column='1'/>
|
||||
</abi-instr>
|
||||
|
@ -7,13 +7,15 @@
|
||||
<parameter type-id='type-id-3' name='l' filepath='/home/dodji/test-bidw/test-v0.cc' line='5' column='1'/>
|
||||
<return type-id='type-id-1'/>
|
||||
</function-decl>
|
||||
<type-decl name='void' id='type-id-4'/>
|
||||
<function-decl name='bar' mangled-name='_Z3bariz' filepath='/home/dodji/test-bidw/test-v0.cc' line='9' column='1' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='64'>
|
||||
<parameter type-id='type-id-3' name='c' filepath='/home/dodji/test-bidw/test-v0.cc' line='9' column='1'/>
|
||||
<parameter is-variadic='yes'/>
|
||||
</function-decl>
|
||||
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-4'/>
|
||||
<function-decl name='main' filepath='/home/dodji/test-bidw/test-v0.cc' line='17' column='1' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='64'>
|
||||
<return type-id='type-id-4'/>
|
||||
</function-decl>
|
||||
<var-decl name='global' type-id='type-id-4' visibility='default' filepath='/home/dodji/test-bidw/test-v0.cc' line='2' column='1'/>
|
||||
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-5'/>
|
||||
<function-decl name='main' filepath='/home/dodji/test-bidw/test-v0.cc' line='17' column='1' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='64'>
|
||||
<return type-id='type-id-5'/>
|
||||
</function-decl>
|
||||
<var-decl name='global' type-id='type-id-5' visibility='default' filepath='/home/dodji/test-bidw/test-v0.cc' line='2' column='1'/>
|
||||
</abi-instr>
|
||||
|
@ -24,9 +24,11 @@
|
||||
</data-member>
|
||||
</class-decl>
|
||||
<pointer-type-def type-id='type-id-6' size-in-bits='64' alignment-in-bits='64' id='type-id-7'/>
|
||||
<type-decl name='void' id='type-id-8'/>
|
||||
<function-decl name='foo' mangled-name='foo' filepath='/home/dodji/tests/test-v0.c' line='9' column='1' visibility='default' binding='global' size-in-bits='64' alignment-in-bits='64' elf-symbol-id='foo'>
|
||||
<parameter type-id='type-id-5' name='p' filepath='/home/dodji/tests/test-v0.c' line='9' column='1'/>
|
||||
<parameter type-id='type-id-7' name='t' filepath='/home/dodji/tests/test-v0.c' line='10' column='1'/>
|
||||
<return type-id='type-id-8'/>
|
||||
</function-decl>
|
||||
</abi-instr>
|
||||
</abi-corpus>
|
||||
|
@ -40,6 +40,8 @@ using std::ostream;
|
||||
using std::ostringstream;
|
||||
using std::vector;
|
||||
|
||||
using abigail::ir::environment;
|
||||
using abigail::ir::environment_sptr;
|
||||
using abigail::dwarf_reader::lookup_symbol_from_elf;
|
||||
using abigail::elf_symbol;
|
||||
using abigail::elf_symbol_sptr;
|
||||
@ -142,8 +144,9 @@ main(int argc, char* argv[])
|
||||
&& opts.symbol_name != 0);
|
||||
|
||||
string p = opts.elf_path, n = opts.symbol_name;
|
||||
environment_sptr env(new environment);
|
||||
vector<elf_symbol_sptr> syms;
|
||||
if (!lookup_symbol_from_elf(p, n, opts.demangle, syms))
|
||||
if (!lookup_symbol_from_elf(env.get(), p, n, opts.demangle, syms))
|
||||
{
|
||||
cout << "could not find symbol '"
|
||||
<< opts.symbol_name
|
||||
|
Loading…
Reference in New Issue
Block a user