libabigail/include/abg-fwd.h
Dodji Seketeli b2e5366d3f 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:#️⃣:operator())
	(function_decl:#️⃣:operator()): Do not handle caching (here).
	* include/abg-corpus.h (corpus::{g,s}et_environment): Declare new
	accessors.
	* src/abg-corpus.cc (corpus::priv::env): New data member.
	(corpus::priv::priv): Initialize it.
	(corpus::corpus):  Take an environment in parameter.
	(corpus::{g,s}et_environment): Define new member functions
	(corpus::add): Set the environment of the newly added translation
	unit, if it's not set already set.  In any case, assert that the
	translation unit must use the same environment as the corpus.
	* include/abg-dwarf-reader.h (create_read_context)
	(read_corpus_from_elf): Take an environment parameter.
	({s,g}et_debug_info_root_path, {s,g}et_environment): Declare new
	functions.
	* src/abg-dwarf-reader.cc (read_context::{env_,
	offline_callbacks_}): New data members.
	(read_context::read_context): Initialize them.
	(read_context::clear_per_translation_unit_data): Do not touch the
	void type declaration, it doesn't belong to the translation unit.
	(read_context::{env, offline_callbacks}): New accessors.
	(read_context::{create_default_dwfl}): New member function.
	(read_context::dwfl_handle): Add a setter overload.
	({s,g}et_debug_info_root_path): Define new accessors.
	(create_default_dwfl, create_dwfl_sptr, create_default_dwfl_sptr):
	Remove these.
	(build_translation_unit_and_add_to_ir): Adjust to pass the
	environment to the newly created translation unit.
	(build_function_decl): Adjust to pass the environment to the
	created function and parameter types.  Get variadic parameter type
	node from the current environment, not from a global variable.
	And do not try to canonicalize function types here.
	(read_debug_info_into_corpus): Set the environment of the newly
	created corpus.
	(build_ir_node_for_void_type): Get the void type node from the
	current environment, rather than from a global variable.
	(create_read_context): Take the environment in parameter.
	Create the default dwarf front end library handle using the new
	member function of the read context.  Set the current environment
	used by the reader.
	(read_corpus_from_elf): Take an environment in
	parameter. Overhaul.  This is now simpler.
	(has_alt_debug_info): Adjust the call to create_read_context() to
	make it pass an empty environment.
	* include/abg-fwd.h (class environment): Forward declare.
	* include/abg-reader.h (read_translation_unit_from_file)
	(read_translation_unit_from_buffer)
	(read_translation_unit_from_istream)
	(read_corpus_from_native_xml): Take an environment in parameter.
	* src/abg-reader.cc (read_context::m_env): New data member.
	(read_context::read_context): Initialize it.
	(read_context::{get_environment, set_environment}): New data
	member.
	(read_translation_unit): Set environment of the new translation
	unit.
	(read_corpus_from_input): Set the environment of the new corpus.
	(read_translation_unit_from_file)
	(read_translation_unit_from_buffer)
	(read_translation_unit_from_istream, read_corpus_from_native_xml):
	Take an environment in parameter.
	(build_function_parameter): Get variadic parameter type from the environment.
	* src/abg-comparison.cc (compute_diff): Add asserts in all the
	overloads to ensure that the artifact being compared come from the
	same environment.
	* tests/print-diff-tree.cc (main): Create an env for the ABI
	artifacts to use.
	* tests/test-abidiff.cc (main): Likewise.
	* tests/test-diff-dwarf.cc (main): Likewise.
	* tests/test-ir-walker.cc (main): Likewise.
	* tests/test-read-dwarf.cc (main): Likewise.
	* tests/test-read-write.cc (main): Likewise.
	* tools/abicompat.cc (main): Likewise.
	* tools/abidiff.cc (main): Likewise.
	* tools/abidw.cc (main): Likewise.
	* tools/abilint.cc (main): Likewise.
	* tools/abipkgdiff.cc (main): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-07 23:35:29 +02:00

731 lines
16 KiB
C++

// -*- Mode: C++ -*-
//
// Copyright (C) 2013-2015 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
// free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 3, or (at your option) any
// later version.
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details.
// You should have received a copy of the GNU Lesser General Public
// License along with this program; see the file COPYING-LGPLV3. If
// not, see <http://www.gnu.org/licenses/>.
/// @file
#ifndef __ABG_IRFWD_H__
#define __ABG_IRFWD_H__
#include <cstddef>
#include <tr1/memory>
#include <list>
#include <vector>
#include <string>
#include <tr1/functional>
#include <typeinfo>
#include <utility> // for std::rel_ops, at least.
#include <ostream>
#include "abg-hash.h"
/// Toplevel namespace for libabigail.
namespace abigail
{
/**
@mainpage libabigail
This is the API documentation of the Application Binary
Interface Generic Analysis and Instrumentation Library, aka,
<em>libabigail</em>.
Check out <a href="http://sourceware.org/libabigail"> the project
homepage</a>!
The current libabigail source code can be browsed at
http://sourceware.org/git/gitweb.cgi?p=libabigail.git
It can be checked out with:
<em>git clone git://sourceware.org/git/libabigail.git</em>
The mailing list to send messages and patches to is
libabigail@sourceware.org.
You can hang out with libabigail developers and users on irc at
irc://irc.oftc.net\#libabigail.
*/
// Inject some types.
using std::tr1::shared_ptr;
using std::tr1::weak_ptr;
using std::string;
using std::vector;
// Pull in relational operators.
using namespace std::rel_ops;
namespace ir
{
// Forward declarations for corpus.
class corpus;
// Forward declarations for ir.
class environment;
class location;
class location_manager;
class translation_unit;
class class_decl;
class class_tdecl;
class type_or_decl_base;
class decl_base;
class enum_type_decl;
class function_decl;
class function_tdecl;
class function_type;
class global_scope;
class node_visitor;
class location;
class location_manager;
class method_type;
class namespace_decl;
class parameter;
class pointer_type_def;
class qualified_type_def;
class reference_type_def;
class scope_decl;
class scope_type_decl;
class template_decl;
class template_parameter;
class non_type_tparameter;
class type_tparameter;
class template_tparameter;
class type_composition;
class type_base;
class type_decl;
class typedef_decl;
class var_decl;
class array_type_def;
class subrange_type;
struct type_shared_ptr_equal;
struct traversable_base;
shared_ptr<decl_base>
add_decl_to_scope(shared_ptr<decl_base>, scope_decl*);
shared_ptr<decl_base>
add_decl_to_scope (shared_ptr<decl_base>, shared_ptr<scope_decl>);
const global_scope*
get_global_scope(const decl_base&);
const global_scope*
get_global_scope(const decl_base*);
const global_scope*
get_global_scope(const shared_ptr<decl_base>);
translation_unit*
get_translation_unit(const decl_base&);
translation_unit*
get_translation_unit(const decl_base*);
translation_unit*
get_translation_unit(const shared_ptr<decl_base>);
bool
is_global_scope(const scope_decl&);
const global_scope*
is_global_scope(const scope_decl*);
bool
is_global_scope(const shared_ptr<scope_decl>);
bool
is_at_global_scope(const decl_base&);
bool
is_at_global_scope(const shared_ptr<decl_base>);
bool
is_at_class_scope(const shared_ptr<decl_base>);
bool
is_at_class_scope(const decl_base*);
bool
is_at_class_scope(const decl_base&);
bool
is_at_template_scope(const shared_ptr<decl_base>);
bool
is_template_parameter(const shared_ptr<decl_base>);
shared_ptr<function_decl>
is_function_decl(shared_ptr<decl_base>);
shared_ptr<decl_base>
is_decl(const shared_ptr<type_or_decl_base>&);
bool
is_type(const type_or_decl_base&);
type_base*
is_type(const type_or_decl_base*);
shared_ptr<type_base>
is_type(const shared_ptr<type_or_decl_base>& tod);
bool
is_type(const decl_base&);
shared_ptr<type_base>
is_type(const shared_ptr<decl_base>);
type_base*
is_type(decl_base*);
shared_ptr<type_decl>
is_type_decl(const shared_ptr<type_base>);
shared_ptr<typedef_decl>
is_typedef(const shared_ptr<type_base>);
shared_ptr<typedef_decl>
is_typedef(const shared_ptr<decl_base>);
const typedef_decl*
is_typedef(const type_base*);
typedef_decl*
is_typedef(type_base*);
shared_ptr<enum_type_decl>
is_enum_type(const shared_ptr<type_base>&);
shared_ptr<enum_type_decl>
is_enum_type(const shared_ptr<decl_base>&);
class_decl*
is_class_type(decl_base*);
class_decl*
is_class_type(type_base*);
shared_ptr<class_decl>
is_class_type(const shared_ptr<type_base>);
shared_ptr<class_decl>
is_class_type(const shared_ptr<decl_base>);
shared_ptr<class_decl>
is_compatible_with_class_type(const shared_ptr<type_base>);
shared_ptr<class_decl>
is_compatible_with_class_type(const shared_ptr<decl_base>);
pointer_type_def*
is_pointer_type(type_base*);
const pointer_type_def*
is_pointer_type(const type_base*);
shared_ptr<pointer_type_def>
is_pointer_type(const shared_ptr<type_base>);
reference_type_def*
is_reference_type(type_base*);
const reference_type_def*
is_reference_type(const type_base*);
shared_ptr<reference_type_def>
is_reference_type(const shared_ptr<type_base>);
qualified_type_def*
is_qualified_type(type_base*);
shared_ptr<qualified_type_def>
is_qualified_type(const shared_ptr<type_base>);
shared_ptr<function_type>
is_function_type(const shared_ptr<type_base>);
function_type*
is_function_type(type_base*);
const function_type*
is_function_type(const type_base*);
shared_ptr<method_type>
is_method_type(const shared_ptr<type_base>);
const method_type*
is_method_type(const type_base*);
method_type*
is_method_type(type_base*);
shared_ptr<class_decl>
look_through_decl_only_class(shared_ptr<class_decl>);
shared_ptr<var_decl>
is_var_decl(const shared_ptr<decl_base>);
bool
is_template_parm_composition_type(const shared_ptr<decl_base>);
bool
is_template_decl(const shared_ptr<decl_base>);
bool
is_function_template_pattern(const shared_ptr<decl_base>);
shared_ptr<decl_base>
add_decl_to_scope(shared_ptr<decl_base>, scope_decl*);
shared_ptr<decl_base>
add_decl_to_scope(shared_ptr<decl_base>, shared_ptr<scope_decl>);
shared_ptr<decl_base>
insert_decl_into_scope(shared_ptr<decl_base>,
vector<shared_ptr<decl_base> >::iterator,
scope_decl*);
shared_ptr<decl_base>
insert_decl_into_scope(shared_ptr<decl_base>,
vector<shared_ptr<decl_base> >::iterator,
shared_ptr<scope_decl>);
bool
has_scope(const decl_base&);
bool
has_scope(const shared_ptr<decl_base>);
bool
is_member_decl(const shared_ptr<decl_base>);
bool
is_member_decl(const decl_base*);
bool
is_member_decl(const decl_base&);
bool
is_member_type(const shared_ptr<type_base>);
void
remove_decl_from_scope(shared_ptr<decl_base>);
bool
get_member_is_static(const decl_base&);
bool
get_member_is_static(const decl_base*);
bool
get_member_is_static(const shared_ptr<decl_base>&);
void
set_member_is_static(decl_base&, bool);
void
set_member_is_static(const shared_ptr<decl_base>&, bool);
bool
is_data_member(const var_decl&);
bool
is_data_member(const var_decl*);
bool
is_data_member(const shared_ptr<var_decl>);
shared_ptr<var_decl>
is_data_member(const shared_ptr<decl_base>&);
array_type_def*
is_array_type(const type_base* decl);
shared_ptr<array_type_def>
is_array_type(const shared_ptr<type_base> decl);
void
set_data_member_offset(shared_ptr<var_decl>, size_t);
size_t
get_data_member_offset(const var_decl&);
size_t
get_data_member_offset(const shared_ptr<var_decl>);
size_t
get_data_member_offset(const shared_ptr<decl_base>);
void
set_data_member_is_laid_out(shared_ptr<var_decl>, bool);
bool
get_data_member_is_laid_out(const var_decl&);
bool
get_data_member_is_laid_out(const shared_ptr<var_decl>);
bool
is_member_function(const function_decl&);
bool
is_member_function(const function_decl*);
bool
is_member_function(const shared_ptr<function_decl>&);
bool
get_member_function_is_ctor(const function_decl&);
bool
get_member_function_is_ctor(const shared_ptr<function_decl>&);
void
set_member_function_is_ctor(const function_decl&, bool);
void
set_member_function_is_ctor(const shared_ptr<function_decl>&, bool);
bool
get_member_function_is_dtor(const function_decl&);
bool
get_member_function_is_dtor(const shared_ptr<function_decl>&);
void
set_member_function_is_dtor(function_decl&, bool);
void
set_member_function_is_dtor(const shared_ptr<function_decl>&, bool);
bool
get_member_function_is_const(const function_decl&);
bool
get_member_function_is_const(const shared_ptr<function_decl>&);
void
set_member_function_is_const(function_decl&, bool);
void
set_member_function_is_const(const shared_ptr<function_decl>&, bool);
size_t
get_member_function_vtable_offset(const function_decl&);
size_t
get_member_function_vtable_offset(const shared_ptr<function_decl>&);
void
set_member_function_vtable_offset(const function_decl& f,
size_t s);
void
set_member_function_vtable_offset(const shared_ptr<function_decl> &f,
size_t s);
bool
get_member_function_is_virtual(const function_decl&);
bool
get_member_function_is_virtual(const shared_ptr<function_decl>&);
bool
get_member_function_is_virtual(const function_decl*);
void
set_member_function_is_virtual(function_decl&, bool);
void
set_member_function_is_virtual(const shared_ptr<function_decl>&, bool);
shared_ptr<type_base>
strip_typedef(const shared_ptr<type_base>);
shared_ptr<type_base>
peel_typedef_type(const shared_ptr<type_base>&);
const type_base*
peel_typedef_type(const type_base*);
shared_ptr<type_base>
peel_pointer_type(const shared_ptr<type_base>&);
const type_base*
peel_pointer_type(const type_base*);
shared_ptr<type_base>
peel_reference_type(const shared_ptr<type_base>&);
const type_base*
peel_reference_type(const type_base*);
shared_ptr<type_base>
peel_typedef_pointer_or_reference_type(const shared_ptr<type_base>);
type_base*
peel_typedef_pointer_or_reference_type(const type_base*);
string
get_name(const shared_ptr<type_or_decl_base>&,
bool qualified = true);
scope_decl*
get_type_scope(type_base*);
scope_decl*
get_type_scope(const shared_ptr<type_base>&);
string
get_type_name(const shared_ptr<type_base>, bool qualified = true);
string
get_type_name(const type_base*, bool qualified = true);
string
get_type_name(const type_base&, bool qualified = true);
string
get_function_type_name(const shared_ptr<function_type>&);
string
get_function_type_name(const function_type*);
string
get_function_type_name(const function_type&);
string
get_method_type_name(const shared_ptr<method_type>&
);
string
get_method_type_name(const method_type*);
string
get_method_type_name(const method_type&);
string
get_pretty_representation(const decl_base*);
string
get_pretty_representation(const type_base*);
string
get_pretty_representation(const type_or_decl_base*);
string
get_pretty_representation(const shared_ptr<type_or_decl_base>&);
string
get_pretty_representation(const shared_ptr<decl_base>&);
string
get_pretty_representation(const shared_ptr<type_base>&);
string
get_pretty_representation(const function_type&);
string
get_pretty_representation(const function_type*);
string
get_pretty_representation(const shared_ptr<function_type>&);
string
get_pretty_representation(const method_type&);
string
get_pretty_representation(const method_type*);
string
get_pretty_representation(const shared_ptr<method_type>&);
const decl_base*
get_type_declaration(const type_base*);
decl_base*
get_type_declaration(type_base*);
shared_ptr<decl_base>
get_type_declaration(const shared_ptr<type_base>);
bool
types_are_compatible(const shared_ptr<type_base>,
const shared_ptr<type_base>);
bool
types_are_compatible(const shared_ptr<decl_base>,
const shared_ptr<decl_base>);
const scope_decl*
get_top_most_scope_under(const decl_base*,
const scope_decl*);
const scope_decl*
get_top_most_scope_under(const shared_ptr<decl_base>,
const scope_decl*);
const scope_decl*
get_top_most_scope_under(const shared_ptr<decl_base>,
const shared_ptr<scope_decl>);
void
fqn_to_components(const std::string&,
std::list<string>&);
const shared_ptr<decl_base>
lookup_type_in_corpus(const string&, const corpus&);
const shared_ptr<class_decl>
lookup_class_type_in_corpus(const string&, const corpus&);
const shared_ptr<function_type>
lookup_function_type_in_corpus(const function_type&, const corpus&);
const shared_ptr<decl_base>
lookup_type_in_translation_unit(const string&,
const translation_unit&);
const shared_ptr<decl_base>
lookup_type_in_translation_unit(const std::list<string>&,
const translation_unit&);
const shared_ptr<class_decl>
lookup_class_type_in_translation_unit(const std::list<string>& fqn,
const translation_unit& tu);
const shared_ptr<class_decl>
lookup_class_type_in_translation_unit(const string& fqn,
const translation_unit& tu);
const shared_ptr<type_base>
lookup_type_in_translation_unit(const shared_ptr<type_base>,
const translation_unit&);
shared_ptr<function_type>
lookup_function_type_in_translation_unit(const function_type&,
const translation_unit&);
shared_ptr<type_base>
synthesize_type_from_translation_unit(const shared_ptr<type_base>& type,
translation_unit& tu);
shared_ptr<function_type>
synthesize_function_type_from_translation_unit(const function_type&,
translation_unit&);
shared_ptr<function_type>
lookup_function_type_in_translation_unit(const shared_ptr<function_type>&,
const translation_unit&);
shared_ptr<function_type>
lookup_function_type_in_corpus(const shared_ptr<function_type>&,
corpus&);
shared_ptr<type_base>
lookup_type_in_corpus(const shared_ptr<type_base>&, corpus&);
const shared_ptr<decl_base>
lookup_type_in_scope(const string&,
const shared_ptr<scope_decl>);
const shared_ptr<decl_base>
lookup_type_in_scope(const std::list<string>&,
const shared_ptr<scope_decl>);
const shared_ptr<decl_base>
lookup_var_decl_in_scope(const string&,
const shared_ptr<scope_decl>);
const shared_ptr<decl_base>
lookup_var_decl_in_scope(const std::list<string>&,
const shared_ptr<scope_decl>);
string
demangle_cplus_mangled_name(const string&);
shared_ptr<type_base>
type_or_void(const shared_ptr<type_base>, const environment*);
shared_ptr<type_base>
canonicalize(shared_ptr<type_base>);
type_base*
type_has_non_canonicalized_subtype(shared_ptr<type_base> t);
bool
type_has_sub_type_changes(shared_ptr<type_base> t_v1,
shared_ptr<type_base> t_v2);
void
keep_type_alive(shared_ptr<type_base> t);
size_t
hash_type_or_decl(const type_or_decl_base *);
size_t
hash_type_or_decl(const shared_ptr<type_or_decl_base>&);
} // end namespace ir
using namespace abigail::ir;
void
dump(const shared_ptr<decl_base>, std::ostream&);
void
dump(const shared_ptr<decl_base>);
void
dump(const shared_ptr<type_base>, std::ostream&);
void
dump(const shared_ptr<type_base>);
void
dump(const shared_ptr<var_decl>, std::ostream&);
void
dump(const shared_ptr<var_decl>);
void
dump(const translation_unit&, std::ostream&);
void
dump(const translation_unit&);
void
dump(const shared_ptr<translation_unit>, std::ostream&);
void
dump(const shared_ptr<translation_unit>);
void
dump_decl_location(const decl_base&);
void
dump_decl_location(const decl_base*);
void
dump_decl_location(const shared_ptr<decl_base>&);
} // end namespace abigail
#endif // __ABG_IRFWD_H__