libabigail/include/abg-ir.h
Dodji Seketeli e7c920edbc Support union types
This patch makes Libabigail understand C and C++ union types.  It
defines a new class abigail::ir::union_decl to represent the
declaration of a union type.  It also defines a new type
abigail::comparison::union_diff to represent the changes between two
union types.  The patch then adds facilities to read union types from
DWARF and abixml and also to write union types into the abixml format.

As union types and class types have a lot in common, the patch tries
very hard to share code between the abigail::ir::class_decl and
abigail::ir::union_decl.  To do so, a new class
abigail::ir::class_or_union is created.  It's the base class for both
abigai::ir::class_decl and abigail::ir::union_decl.  Its data members
and methods represent the set of data and behaviour that are common to
classes and unions.  A lot of code and data that were initially in
abigail::ir::class_decl got moved into the new
abigail::ir::class_or_union class.

Similary, the patch creates a new class
abigail::comparison::class_or_union_diff that is a base class for both
the existing class abigail::comparison::class_diff and the newly
created class abigail::comparison::union_diff.  The new class
abigail::comparison::class_or_union_diff contains data and behaviour
that are common to both union_diff and class_diff and that were
previously in class_diff.

The rest of the patch is mostly adjustment so that code that was
supposed to work with class class_decl only can now work with class
class_or_union when it makes sense.  Similarly for class_diff and
class_or_union_diff.

The patch adds regression tests into the test suite and adjust many
existing tests involving binaries that contain union types; the
reference output of those tests now take union types into account.

	* include/abg-fwd.h (class_or_union, union_decl): Forward-declare
	new types.
	(is_class_or_union_type, is_union_type): Declare new functions.
	* include/abg-ir.h (method_type::class_type_): Make this be of
	class_or_union_wptr type.
	(method_type::method_type): Make the class_type parameter be of
	class_or_union_wptr type.
	(method_type::{g,s}et_class_type): Take or return a
	class_or_union_sptr.
	(member_base, method_decl, member_function_template)
	(member_class_template, member_base::hash)
	(member_function_template::hash, member_class_template::hash):
	Take these class types out of the class_decl scope.
	(is_method_decl): Adjust.
	(operator==, opertor!=): Adjust overloads for
	member_function_template_sptr and member_class_template_sptr.
	(class class_or_union): Declare new type.
	(class class_decl): Make this class inherit class_or_union class.
	(class_decl::{add_member_decl, insert_member_decl,
	remove_member_decl, set_size_in_bits, get_size_in_bits,
	get_alignment_in_bits, set_alignment_in_bits,
	get_is_declaration_only, set_is_declaration_only,
	set_definition_of_declaration, get_definition_of_declaration,
	get_earlier_declaration, set_earlier_declaration,
	insert_member_type, add_member_type, remove_member_type,
	get_member_type, find_member_type, add_data_member,
	get_data_members, find_data_member, get_non_static_data_members,
	add_member_function, get_member_functions, find_member_function,
	add_member_function_template, get_member_function_templates,
	add_member_class_template, get_member_class_templates): Move these
	to the parent class class_or_union.
	(copy_member_function, equals): Add overloads for class_or_union.
	(struct class_or_union::hash): Declare new type.
	(class union_decl): Declare new type.
	(equals, copy_member_function): New overloads for class union_decl
	type.
	(ir_node_visitor::visit): Add new overloads for union_decl* and
	class_or_union*.
	* src/abg-ir.cc (get_member_function_is_ctor)
	(set_member_function_is_ctor, get_member_function_is_dtor)
	(set_member_function_is_dtor, get_member_function_is_const)
	(set_member_function_is_const, get_member_function_vtable_offset)
	(set_member_function_vtable_offset)
	(get_member_function_is_virtual, set_member_function_is_virtual)
	(maybe_update_types_lookup_map, get_location)
	(get_method_type_name, is_at_global_scope, is_at_class_scope):
	Adjust.
	(is_class_or_union_type, is_union_type): Define new functions.
	(type_base::get_canonical_type_for, maybe_adjust_canonical_type)
	(method_type::method_type, method_type::set_class_type)
	(function_decl::get_pretty_representation)
	(function_decl::get_first_non_implicit_parm)
	(function_decl::clone): Adjust.
	(equals): Adjust the overload for function_type.
	(struct class_or_union::priv): Define new type.
	(class::priv::{declaration_, definition_of_declaration_,
	member_types_, data_members_, non_static_data_members_,
	member_functions_, mem_fns_map_, member_function_templates_,
	member_class_templates_, is_declaration_only_}): Move these data
	member into class_or_union::priv.
	(class_priv::{mark_as_being_compared, unmark_as_being_compared,
	comparison_started}): Moved these member functions to
	class_or_union::priv.
	(class_or_union::{class_or_union, traverse, ~class_or_union,
	add_member_decl, remove_member_decl, insert_member_type,
	add_member_type, get_size_in_bits, remove_member_type,
	get_alignment_in_bits, set_alignment_in_bits, set_size_in_bits,
	get_is_declaration_only, set_is_declaration_only,
	set_definition_of_declaration, get_definition_of_declaration,
	get_earlier_declaration, set_earlier_declaration,
	get_member_types, find_member_type, add_data_member,
	get_data_member, find_data_member, add_member_function,
	get_member_functions, find_member_function,
	add_member_function_template, get_member_function_templates,
	add_member_class_template, get_member_class_templates,
	has_no_member, insert_member_decl, operator==}): Define new member
	functions.
	(class_decl::{add_member_decl, remove_member_decl,
	insert_member_type, add_member_type, get_size_in_bits,
	remove_member_type, get_alignment_in_bits, set_alignment_in_bits,
	set_size_in_bits, get_is_declaration_only,
	set_is_declaration_only, set_definition_of_declaration,
	get_earlier_declaration, set_earlier_declaration,
	get_member_types, find_member_type, add_data_member,
	get_data_member, find_data_member, add_member_function,
	get_member_functions, find_member_function,
	add_member_function_template, get_member_function_templates,
	add_member_class_template, get_member_class_templates): Move these
	member functions into class_or_union.
	(class_decl::{class_decl, get_definition_of_declaration,
	insert_member_decl, add_member_function, has_no_base_nor_member}):
	Adjust.
	(equals, copy_member_function): Define new overloads for
	class_or_union.
	(equals): Adjust the overload for class_decl.
	(method_decl::{method_decl, set_linkage_name, ~method_decl,
	get_type, set_scope}): Remove from the class_decl scope.
	(member_base::operator==, member_function_template::operator==):
	Likewise.
	(member_function_template::traverse)
	(member_class_template::operator==)
	(member_class_template::traverse): Likewise.
	(operator==, operator!=): Adjust the overlod for
	member_function_template_sptr.
	(is_method_decl, fixup_virtual_member_function)
	(set_member_is_static): Adjust.
	(virtual_member_function_less_than::operator()): Likewise.
	(union_decl::{union_decl, get_pretty_representation, operator==,
	traverse}): Define new member functions.
	(equals, copy_member_function): Define new overloads for
	union_decl.
	(hash_type_or_decl): Adjust.
	(ir_node_visitor::visit_{begin, end}): Adjust. Add new overloads
	for class_or_union* and union_decl*.
	* include/abg-comparison.h (changed_member_function_sptr)
	(string_member_function_sptr_map): Adjust these typedefs.
	(class class_or_union_diff): Declare new type.
	(class_diff): Adjust to make this inherit the new
	class_or_union_diff type.
	(class_diff::{get_priv, member_types_changes,
	data_members_changes, inserted_data_members, deleted_data_members,
	member_fn_tmpls_changes, member_fn_tmpls_changes,
	member_class_tmpls_changes}): These member functions got moved
	into -- and shared with -- class_or_union_diff class.
	(class union_diff): Declare new type.
	(typedef union_diff_sptr): New typedef.
	(compute_diff): New overload for union_diff
	(is_class_diff, is_union_diff): Declare new functions.
	* src/abg-comparison.cc (is_class_diff, is_union_diff): Define new
	functions.
	(compute_diff_for_types): Support union_decl.
	(represent):  Adjust.
	(represent_data_member): Do not show offset information for data
	members of unions as all union data members are at offset 0.
	(struct class_or_union_diff::priv): New type.
	(class_or_union_diff::priv::{member_type_has_changed,
	subtype_changed_dm, member_class_tmpl_has_changed,
	get_deleted_non_static_data_members_number,
	get_inserted_non_static_data_members_number,
	count_filtered_subtype_changed_dm, count_filtered_changed_dm,
	count_filtered_changed_mem_fns, count_filtered_inserted_mem_fns,
	count_filtered_deleted_mem_fns}): Define new member functions.
	(class_or_union_diff::{class_or_union_diff, finish_diff_type,
	lookup_tables_empty, lookup_tables_empty,
	ensure_lookup_tables_populated, allocate_priv_data, get_priv,
	~class_or_union_diff, first_class_or_union, second_class_or_union,
	member_types_changes, member_types_changes, data_members_changes,
	inserted_data_members, deleted_data_members, member_fns_changes,
	changed_member_fns, member_fns_changes, inserted_member_fns,
	member_fn_tmpls_changes, member_fn_tmpls_changes,
	member_class_tmpls_changes, member_class_tmpls_changes,
	has_changes, has_local_changes, report, chain_into_hierarchy}):
	Define new member functions.
	(class_diff::priv::{member_types_changes_, data_members_changes,
	member_fn_tmpls_changes_, member_class_tmpls_changes_,
	deleted_member_types_, inserted_member_types_,
	changed_member_types_, sorted_changed_member_types_,
	deleted_data_members_, deleted_dm_by_offset_,
	inserted_data_members_, inserted_dm_by_offset_,
	subtype_changed_dm_, sorted_subtype_changed_dm_, changed_dm_,
	sorted_changed_dm_, deleted_member_functions_,
	inserted_member_functions_, changed_member_functions_,
	sorted_changed_member_functions_, deleted_member_class_tmpls_,
	inserted_member_class_tmpls_, changed_member_class_tmpls_,
	sorted_changed_member_class_tmpls_}): Move these data members into
	class_or_union_diff::priv.
	(class_diff::{clear_lookup_tables, lookup_tables_empty,
	ensure_lookup_tables_populate}): Adjust.
	(class_diff::allocate_priv_data): Define new function.
	(class_diff::priv::{count_filtered_changed_mem_fns,
	count_filtered_inserted_mem_fns, count_filtered_deleted_mem_fns,
	chain_into_hierarchy, class_diff}): Likewise.
	(class_diff::{member_types_changes, data_members_changes,
	inserted_data_members, deleted_data_members,
	member_fn_tmpls_changes, member_fn_tmpls_changes,
	member_class_tmpls_changes}): These are deleted as they got moved
	to class_or_union_diff.
	(class_diff::report): Adjust.
	(union_diff::{clear_lookup_tables, lookup_tables_empty,
	ensure_lookup_tables_populated, allocate_priv_data, union_diff,
	finish_diff_type, first_union_decl, second_union_decl,
	get_pretty_representation, report}): Define new functions.
	(compute_diff): Define an overload for union_decl_sptr.
	(function_decl_diff::report): Adjust.
	(corpus_diff::priv::apply_suppressions_to_added_removed_fns_vars):
	Adjust.
	(corpus_diff::report): Adjust.
	* src/abg-hash.cc (member_base:#️⃣:operator)
	(member_function_template:#️⃣:operator)
	(member_class_template:#️⃣:operator): Move these out of the
	class_decl scope.
	(class_or_union:#️⃣:operator): Define new member function.
	(class_decl:#️⃣:operator): Adjust.
	(type_base::dynamic_hash::operator): Support hashing of
	union_decl.  Adjust.
	* src/abg-suppression.cc (type_suppression::suppresses_diff):
	Adjust.
	* src/abg-dwarf-reader.cc (typedef die_class_or_union_map_type):
	Define new typedef.
	(read_context::{die_wip_classes_map_,
	alternate_die_wip_classes_map_, type_unit_die_wip_classes_map_):
	Make these data member have type die_class_or_union_map_type.
	(read_context::{lookup_type_from_die_offset, die_wip_classes_map,
	is_wip_class_die_offset, resolve_declaration_only_classes}):
	Adjust.
	(finish_member_function_reading, build_class_type_and_add_to_ir)
	(build_function_type, build_function_decl, build_reference_type)
	(type_is_suppressed, build_function_decl)
	(maybe_canonicalize_type, maybe_set_member_type_access_specifier):
	Adjust.
	(build_union_type_and_add_to_ir): Define new static function.
	(build_ir_node_from_die): Support DW_TAG_union_type DIE tag.
	* src/abg-reader.cc (handle_element_node): Handle union_decl.
	(build_function_decl, build_function_decl_if_not_suppressed):
	Adjust.
	(build_union_decl_if_not_suppressed, build_union_decl)
	(handle_union_decl): Define new functions.
	(build_class_decl): Adjust.
	* src/abg-writer.cc (record_decl_only_type_as_emitted): Adjust.
	(write_decl): Adjust. Support writting union_decl type.
p	(write_class_decl_opening_tag, write_class_decl): Adjust.  Call
	the new write_class_or_union_is_declaration_only.
	(write_union_decl_opening_tag, write_union_decl): Define new
	static functions.
	(write_member_tpe): Support writting union decl.
	* tests/test-diff-dwarf.cc (in_out_specs): Add new tests for this
	union type support.
	* tests/data/test-diff-dwarf/libtest37-union-v0.so: New test input.
	* tests/data/test-diff-dwarf/libtest37-union-v1.so: Likewise.
	* tests/data/test-diff-dwarf/libtest38-union-v0.so: Likewise.
	* tests/data/test-diff-dwarf/libtest38-union-v1.so: Likewise.
	* tests/data/test-diff-dwarf/libtest39-union-v0.so: Likewise.
	* tests/data/test-diff-dwarf/libtest39-union-v1.so: Likewise.
	* tests/data/test-diff-dwarf/test37-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test38-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test39-union-report-0.txt: Likewise.
	* tests/data/test-diff-dwarf/test37-union-v0.cc: Source code for
	new test input.
	* tests/data/test-diff-dwarf/test37-union-v1.cc: Likewise.
	* tests/data/test-diff-dwarf/test38-union-v0.cc: Likewise.
	* tests/data/test-diff-dwarf/test38-union-v1.cc: Likewise.
	* tests/data/test-diff-dwarf/test39-union-v0.cc: Likewise.
	* tests/data/test-diff-dwarf/test39-union-v1.cc: Likewise.
	* tests/data/test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi:
	Update test reference.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report0.txt:
	Likewise.
	* tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt:
	Likewise.
	* tests/data/test-read-dwarf/libtest23.so.abi: Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns-2.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/libtest24-drop-fns.so.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise.
	* tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-11-22 16:22:25 +01:00

4160 lines
94 KiB
C++

// -*- Mode: C++ -*-
//
// Copyright (C) 2013-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
///
/// Types of the main internal representation of libabigail.
///
/// This internal representation abstracts the artifacts that make up
/// an application binary interface.
#ifndef __ABG_IR_H__
#define __ABG_IR_H__
#include <assert.h>
#include <stdint.h>
#include <cstdlib>
#include <tr1/unordered_map>
#include "abg-fwd.h"
#include "abg-hash.h"
#include "abg-traverse.h"
/// @file
///
/// This file contains the declarations of the Internal Representation
/// of libabigail.
/// @defgroup Memory Memory management
/// @{
///
/// How objects' lifetime is handled in libabigail.
///
/// For memory management and garbage collection of libabigail's IR
/// artifacts, we use std::tr1::shared_ptr and std::tr1::weak_ptr.
///
/// When manipulating these IR artifacts, there are a few rules to keep in
/// mind.
///
/// <b>The declaration for a type is owned by only one scope </b>
///
/// This means that for each instance of abigail::type_base (a type) there
/// is an instance of abigail::scope_decl that owns a @ref
/// abigail::decl_base_sptr (a shared pointer to an abigail::decl_base)
/// that points to the declaration of that type. The
/// abigail::type_base_sptr is added to the scope using the function
/// abigail::add_decl_to_scope().
///
/// There is a kind of type that is usually not syntactically owned by
/// a scope: it's function type. In libabigail, function types are
/// represented by abigail::function_type and abigail::method_type.
/// These types must be owned by the translation unit they originate
/// from. Adding them to the translation unit must be done by a call
/// to the method function
/// abigail::translation::bind_function_type_life_time().
///
/// <b> A declaration that has a type does NOT own the type </b>
///
/// This means that, for instance, in an abigail::var_decl (a variable
/// declaration), the type of the declaration is not owned by the
/// declaration. In other (concrete) words, the variable declaration
/// doesn't have a shared pointer to the type. Rather, it has a *weak*
/// pointer to its type. That means that it has a data member of type
/// abigail::type_base_wptr that contains the type of the declaration.
///
/// But then abigail::var_decl::get_type() returns a shared pointer that
/// is constructed from the internal weak pointer to the type. That way,
/// users of the type of the var can own a temporary reference on it and
/// be assured that the type's life time is long enough for their need.
///
/// Likewise, data members, function and template parameters similarly
/// have weak pointers on their type.
///
/// If, for a reason, you really need to keep a type alive for the
/// entire lifetime of the type system, then you can bind the life
/// time of that type to the life time of the @ref environment that is
/// supposed to outlive the type system. You do that by passing the
/// type to the function environment::keep_type_alive().
///
/// @}
namespace abigail
{
/// The namespace of the internal representation of ABI artifacts like
/// types and decls.
namespace ir
{
// Inject some std::tr1 types in here.
using std::tr1::unordered_map;
/// Convenience typedef for a shared pointer to a @ref corpus.
typedef shared_ptr<corpus> corpus_sptr;
/// Convenience typedef for a weak pointer to a @ref corpus.
typedef weak_ptr<corpus> corpus_wptr;
/// Convenience typedef for a shared pointer on a @ref type_base
typedef shared_ptr<type_base> type_base_sptr;
/// Convenience typedef for a shared pointer on a @ref type_decl.
typedef shared_ptr<type_decl> type_decl_sptr;
class class_or_union;
typedef shared_ptr<class_or_union> class_or_union_sptr;
typedef weak_ptr<class_or_union> class_or_union_wptr;
/// Convenience typedef for a shared pointer to an @ref environment
typedef shared_ptr<environment> environment_sptr;
/// This is an abstraction of the set of resources necessary to manage
/// several aspects of the internal representations of the Abigail
/// library.
///
/// An environment can be seen as the boundaries in which all related
/// Abigail artifacts live. So before doing anything using this
/// library, the first thing to create is, well, you know it now, an
/// environment.
///
/// Note that the lifetime of environment objects must be longer than
/// the lifetime of any other type in the Abigail system. So a given
/// instance of @ref environment must stay around as long as you are
/// using libabigail. It's only when you are done using the library
/// that you can de-allocate the environment instance.
class environment
{
public:
/// A convenience typedef for a map of canonical types. The key is
/// the pretty representation string of a particular type and the
/// value is the vector of canonical types that have the same pretty
/// representation string.
typedef std::tr1::unordered_map<string,
std::vector<type_base_sptr> > canonical_types_map_type;
private:
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
public:
environment();
virtual ~environment();
canonical_types_map_type&
get_canonical_types_map();
const type_base_sptr&
get_void_type() const;
const type_base_sptr&
get_variadic_parameter_type() const;
bool
canonicalization_is_done() const;
void
canonicalization_is_done(bool);
bool
is_void_type(const type_base_sptr&) const;
bool
is_variadic_parameter_type(const type_base*) const;
bool
is_variadic_parameter_type(const type_base_sptr&) const;
interned_string
intern(const string&) const;
friend class class_or_union;
friend class class_decl;
friend class function_type;
friend void keep_type_alive(type_base_sptr);
}; // end class environment
class location_manager;
/// @brief The source location of a token.
///
/// This represents the location of a token coming from a given
/// translation unit. This location is actually an abstraction of
/// cursor in the table of all the locations of all the tokens of the
/// translation unit. That table is managed by the @ref location_manager
/// type. To get the file path, line and column numbers associated to
/// a given instance of @ref location, you need to use the
/// location_manager::expand_location method.
class location
{
unsigned value_;
// The location manager to use to decode the value above. There is
// one location manager per translation unit, and the location
// manager's life time is managed by its translation unit.
location_manager* loc_manager_;
location(unsigned v, location_manager* m)
: value_(v), loc_manager_(m)
{}
/// Get the location manager to use to decode the value of this
/// location.
///
/// @return the location manager for the current location value.
location_manager*
get_location_manager() const
{return loc_manager_;}
public:
/// Copy constructor of the location.
///
/// @param l the location to copy from.
location(const location& l)
: value_(l.value_),
loc_manager_(l.loc_manager_)
{}
/// Default constructor for the @ref location type.
location()
: value_(), loc_manager_()
{}
/// Get the value of the location.
unsigned
get_value() const
{return value_;}
/// Convert the location into a boolean.
///
/// @return true iff the value of the location is different from
/// zero.
operator bool() const
{return !!value_;}
/// Equality operator of the @ref location type.
///
/// @param other the other location to compare against.
///
/// @return true iff both locations are equal.
bool
operator==(const location other) const
{return value_ == other.value_;}
/// "Less than" operator of the @ref location type.
///
/// @parm other the other location type to compare against.
///
/// @return true iff the current instance is less than the @p other
/// one.
bool
operator<(const location other) const
{return value_ < other.value_;}
/// Expand the current location into a tripplet file path, line and
/// column number.
///
/// @param path the output parameter this function sets the expanded
/// path to.
///
/// @param line the output parameter this function sets the expanded
/// line number to.
///
/// @param column the output parameter this function sets the
/// expanded column number to.
void
expand(std::string& path, unsigned& line, unsigned& column) const;
friend class location_manager;
}; // end class location
/// @brief The entry point to manage locations.
///
/// This type keeps a table of all the locations for tokens of a
/// given translation unit.
class location_manager
{
struct priv;
/// Pimpl.
shared_ptr<priv> priv_;
public:
location_manager();
location
create_new_location(const std::string& fle, size_t lne, size_t col);
void
expand_location(const location& location, std::string& path,
unsigned& line, unsigned& column) const;
};
struct ir_node_visitor;
/// Convenience typedef for a shared pointer on a @ref
/// translation_unit type.
typedef shared_ptr<translation_unit> translation_unit_sptr;
/// Convenience typedef for a vector of @ref translation_unit_sptr.
typedef std::vector<translation_unit_sptr> translation_units;
/// Convenience typedef for a weak pointer on a @ref type_base
typedef weak_ptr<type_base> type_base_wptr;
/// Convenience typedef for a smart pointer on @ref decl_base.
typedef shared_ptr<decl_base> decl_base_sptr;
class function_type;
class function_decl;
/// Convenience typedef for a shared pointer on a @ref function_type
typedef shared_ptr<function_type> function_type_sptr;
/// Convenience typedef fo a vector of @ref function_type_sptr
typedef vector<function_type_sptr> function_types_type;
/// Convenience typedef for a weak pointer on a @ref function_type
typedef weak_ptr<function_type> function_type_wptr;
struct ir_traversable_base;
/// Convenience typedef for a shared pointer to @ref
/// ir_traversable_base.
typedef shared_ptr<ir_traversable_base> ir_traversable_base_sptr;
/// The base of an entity of the intermediate representation that is
/// to be traversed.
struct ir_traversable_base : public traversable_base
{
/// Traverse a given IR node and its children, calling an visitor on
/// each node.
///
/// @param v the visitor to call on each traversed node.
///
/// @return true if the all the IR node tree was traversed.
virtual bool
traverse(ir_node_visitor& v);
}; // end class ir_traversable_base
/// A convenience typedef for a map which key is a string and which
/// value is a @ref type_base_wptr.
typedef unordered_map<string, type_base_wptr> string_type_base_wptr_map_type;
/// This is the abstraction of the set of relevant artefacts (types,
/// variable declarations, functions, templates, etc) bundled together
/// into a translation unit.
class translation_unit : public traversable_base
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
// Forbidden
translation_unit();
public:
/// Convenience typedef for a shared pointer on a @ref global_scope.
typedef shared_ptr<global_scope> global_scope_sptr;
/// The language of the translation unit.
enum language
{
LANG_UNKNOWN = 0,
LANG_Cobol74,
LANG_Cobol85,
LANG_C89,
LANG_C99,
LANG_C11,
LANG_C,
LANG_C_plus_plus_11,
LANG_C_plus_plus_14,
LANG_C_plus_plus,
LANG_ObjC,
LANG_ObjC_plus_plus,
LANG_Fortran77,
LANG_Fortran90,
LANG_Fortran95,
LANG_Ada83,
LANG_Ada95,
LANG_Pascal83,
LANG_Modula2,
LANG_Java,
LANG_PL1,
LANG_UPC,
LANG_D,
LANG_Python,
LANG_Go,
LANG_Mips_Assembler
};
public:
translation_unit(const ir::environment* env,
const std::string& path,
char address_size = 0);
virtual ~translation_unit();
const environment*
get_environment() const;
environment*
get_environment();
void
set_environment(const environment*);
language
get_language() const;
void
set_language(language l);
const std::string&
get_path() const;
void
set_path(const string&);
void
set_corpus(corpus*);
const corpus*
get_corpus() const;
corpus*
get_corpus();
const global_scope_sptr
get_global_scope() const;
const function_types_type
get_function_types() const;
const string_type_base_wptr_map_type&
get_types() const;
string_type_base_wptr_map_type&
get_types();
location_manager&
get_loc_mgr();
const location_manager&
get_loc_mgr() const;
bool
is_empty() const;
char
get_address_size() const;
void
set_address_size(char);
bool
is_constructed() const;
void
set_is_constructed(bool);
bool
operator==(const translation_unit&) const;
bool
operator!=(const translation_unit&) const;
void
bind_function_type_life_time(function_type_sptr) const;
virtual bool
traverse(ir_node_visitor& v);
friend function_type_sptr
lookup_function_type_in_translation_unit(const function_type& t,
const translation_unit& tu);
friend function_type_sptr
synthesize_function_type_from_translation_unit(const function_type& fn_type,
translation_unit& tu);
friend type_base_sptr
synthesize_type_from_translation_unit(const type_base_sptr& type,
translation_unit& tu);
};//end class translation_unit
string
translation_unit_language_to_string(translation_unit::language);
translation_unit::language
string_to_translation_unit_language(const string&);
bool
is_c_language(translation_unit::language l);
bool
is_cplus_plus_language(translation_unit::language l);
bool
operator==(const translation_unit_sptr&, const translation_unit_sptr&);
bool
operator!=(const translation_unit_sptr&, const translation_unit_sptr&);
/// Access specifier for class members.
enum access_specifier
{
no_access,
public_access,
protected_access,
private_access,
};
class elf_symbol;
/// A convenience typedef for a shared pointer to elf_symbol.
typedef shared_ptr<elf_symbol> elf_symbol_sptr;
/// A convenience typedef for a weak pointer to elf_symbol.
typedef weak_ptr<elf_symbol> elf_symbol_wptr;
/// Convenience typedef for a map which key is a string and which
/// value if the elf symbol of the same name.
typedef std::tr1::unordered_map<string, elf_symbol_sptr>
string_elf_symbol_sptr_map_type;
/// Convenience typedef for a shared pointer to an
/// string_elf_symbol_sptr_map_type.
typedef shared_ptr<string_elf_symbol_sptr_map_type>
string_elf_symbol_sptr_map_sptr;
/// Convenience typedef for a vector of elf_symbol
typedef std::vector<elf_symbol_sptr> elf_symbols;
/// Convenience typedef for a map which key is a string and which
/// value is a vector of elf_symbol.
typedef std::tr1::unordered_map<string, elf_symbols>
string_elf_symbols_map_type;
/// Convenience typedef for a shared pointer to
/// string_elf_symbols_map_type.
typedef shared_ptr<string_elf_symbols_map_type> string_elf_symbols_map_sptr;
/// Abstraction of an elf symbol.
///
/// This is useful when a given corpus has been read from an ELF file.
/// In that case, a given decl might be associated to its underlying
/// ELF symbol, if that decl is publicly exported in the ELF file. In
/// that case, comparing decls might involve comparing their
/// underlying symbols as well.
class elf_symbol
{
public:
/// The type of a symbol.
enum type
{
NOTYPE_TYPE = 0,
OBJECT_TYPE,
FUNC_TYPE,
SECTION_TYPE,
FILE_TYPE,
COMMON_TYPE,
TLS_TYPE,
GNU_IFUNC_TYPE
};
/// The binding of a symbol.
enum binding
{
LOCAL_BINDING = 0,
GLOBAL_BINDING,
WEAK_BINDING,
GNU_UNIQUE_BINDING
};
/// Inject the elf_symbol::version here.
class version;
private:
struct priv;
shared_ptr<priv> priv_;
elf_symbol();
elf_symbol(const environment* e,
size_t i,
size_t s,
const string& n,
type t,
binding b,
bool d,
bool c,
const version& v);
elf_symbol(const elf_symbol&);
elf_symbol&
operator=(const elf_symbol& s);
public:
static elf_symbol_sptr
create();
static elf_symbol_sptr
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;
void
set_index(size_t);
const string&
get_name() const;
void
set_name(const string& n);
type
get_type() const;
void
set_type(type t);
size_t
get_size() const;
void
set_size(size_t);
binding
get_binding() const;
void
set_binding(binding b);
version&
get_version() const;
void
set_version(const version& v);
bool
is_defined() const;
void
is_defined(bool d);
bool
is_public() const;
bool
is_function() const;
bool
is_variable() const;
const elf_symbol_sptr
get_main_symbol() const;
elf_symbol_sptr
get_main_symbol();
bool
is_main_symbol() const;
elf_symbol_sptr
get_next_alias() const;
bool
has_aliases() const;
int
get_number_of_aliases() const;
void
add_alias(const elf_symbol_sptr&);
bool
is_common_symbol() const;
bool
has_other_common_instances() const;
elf_symbol_sptr
get_next_common_instance() const;
void
add_common_instance(const elf_symbol_sptr&);
const string&
get_id_string() const;
elf_symbol_sptr
get_alias_from_name(const string& name) const;
elf_symbol_sptr
get_alias_which_equals(const elf_symbol& other) const;
string
get_aliases_id_string(const string_elf_symbols_map_type& symtab,
bool include_symbol_itself = true) const;
string
get_aliases_id_string(bool include_symbol_itself = true) const;
static bool
get_name_and_version_from_id(const string& id,
string& name,
string& ver);
bool
operator==(const elf_symbol&) const;
bool
does_alias(const elf_symbol&) const;
}; // end class elf_symbol.
std::ostream&
operator<<(std::ostream& o, elf_symbol::type t);
std::ostream&
operator<<(std::ostream& o, elf_symbol::binding t);
bool
string_to_elf_symbol_type(const string&, elf_symbol::type&);
bool
string_to_elf_symbol_binding(const string&, elf_symbol::binding&);
bool
operator==(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs);
bool
operator!=(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs);
bool
elf_symbols_alias(const elf_symbol& s1, const elf_symbol& s2);
void
compute_aliases_for_elf_symbol(const elf_symbol& symbol,
const string_elf_symbols_map_type& symtab,
vector<elf_symbol_sptr>& alias_set);
/// The abstraction of the version of an ELF symbol.
class elf_symbol::version
{
struct priv;
shared_ptr<priv> priv_;
public:
version();
version(const string& v,
bool is_default);
version(const version& v);
operator const string&() const;
const string&
str() const;
void
str(const string& s);
bool
is_default() const;
void
is_default(bool f);
bool
is_empty() const;
bool
operator==(const version& o) const;
bool
operator!=(const version& o) const;
version&
operator=(const version& o);
};// end class elf_symbol::version
class context_rel;
/// A convenience typedef for shared pointers to @ref context_rel
typedef shared_ptr<context_rel> context_rel_sptr;
/// The abstraction of the relationship between an entity and its
/// containing scope (its context). That relationship can carry
/// properties like access rights (if the parent is a class_decl),
/// etc.
///
/// But importantly, this relationship carries a pointer to the
/// actualy parent.
class context_rel
{
protected:
scope_decl* scope_;
enum access_specifier access_;
bool is_static_;
public:
context_rel()
: scope_(0),
access_(no_access),
is_static_(false)
{}
context_rel(scope_decl* s)
: scope_(s),
access_(no_access),
is_static_(false)
{}
context_rel(scope_decl* s,
access_specifier a,
bool f)
: scope_(s),
access_(a),
is_static_(f)
{}
scope_decl*
get_scope() const
{return scope_;}
access_specifier
get_access_specifier() const
{return access_;}
void
set_access_specifier(access_specifier a)
{access_ = a;}
bool
get_is_static() const
{return is_static_;}
void
set_is_static(bool s)
{is_static_ = s;}
void
set_scope(scope_decl* s)
{scope_ = s;}
bool
operator==(const context_rel& o)const
{
return (access_ == o.access_
&& is_static_ == o.is_static_);
}
/// Inequality operator.
///
/// @param o the other instance of @ref context_rel to compare the
/// current instance against.
///
/// @return true iff the current instance of @ref context_rel is
/// different from @p o.
bool
operator!=(const context_rel& o) const
{return !operator==(o);}
virtual ~context_rel();
};// end class context_rel
class class_decl;
/// Convenience typedef for a shared pointer on a @ref class_decl
typedef shared_ptr<class_decl> class_decl_sptr;
/// Convenience typedef for a vector of @ref class_decl_sptr
typedef vector<class_decl_sptr> classes_type;
/// Convenience typedef for a weak pointer on a @ref class_decl.
typedef weak_ptr<class_decl> class_decl_wptr;
/// A bitfield that gives callers of abigail::ir::equals() some
/// insight about how different two internal representation artifacts
/// are.
enum change_kind
{
NO_CHANGE_KIND = 0,
/// This means that a given IR artifact has local differences, with
/// respect to the other artifact it was compared against. A local
/// change is a change that is carried by the artifact itself,
/// rather than by one off its sub-types.
LOCAL_CHANGE_KIND = 1,
/// This means that a given IR artifact has changes in some of its
/// sub-types, with respect to the other artifact it was compared
/// against.
SUBTYPE_CHANGE_KIND = 1 << 1
};// end enum change_kink
change_kind
operator|(change_kind, change_kind);
change_kind
operator&(change_kind, change_kind);
change_kind&
operator|=(change_kind&, change_kind);
change_kind&
operator&=(change_kind&, change_kind);
bool
equals(const decl_base&, const decl_base&, change_kind*);
class type_or_decl_base;
/// A convenience typedef for a shared_ptr to @ref type_or_decl_base.
typedef shared_ptr<type_or_decl_base> type_or_decl_base_sptr;
/// The base class of both types and declarations.
class type_or_decl_base : public ir_traversable_base
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
mutable priv_sptr priv_;
type_or_decl_base();
protected:
bool hashing_started() const;
void hashing_started(bool) const;
public:
type_or_decl_base(const environment*);
type_or_decl_base(const type_or_decl_base&);
virtual ~type_or_decl_base();
const environment*
get_environment() const;
environment*
get_environment();
void
set_environment(const environment*);
const corpus*
get_corpus() const;
corpus*
get_corpus();
void
set_translation_unit(translation_unit*);
const translation_unit*
get_translation_unit() const;
translation_unit*
get_translation_unit();
type_or_decl_base&
operator=(const type_or_decl_base&);
virtual bool
traverse(ir_node_visitor&);
virtual string
get_pretty_representation(bool internal = false) const = 0;
}; // end class type_or_decl_base
bool
operator==(const type_or_decl_base&, const type_or_decl_base&);
bool
operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&);
bool
operator!=(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&);
void
set_environment_for_artifact(type_or_decl_base* artifact,
const environment* env);
void
set_environment_for_artifact(type_or_decl_base_sptr artifact,
const environment* env);
/// The base type of all declarations.
class decl_base : public virtual type_or_decl_base
{
// Forbidden
decl_base();
struct priv;
protected:
const interned_string&
peek_qualified_name() const;
void
set_qualified_name(const interned_string&) const;
const interned_string&
peek_temporary_qualified_name() const;
void
set_temporary_qualified_name(const interned_string&) const;
public:
// This is public because some internals of the library need to
// update it. But it's opaque to client code anyway, so no big
// deal. Also, it's not handled by a shared_ptr because accessing
// the data members of the priv struct for this decl_base shows up
// on performance profiles when dealing with big binaries with a lot
// of types; dereferencing the shared_ptr involves locking of some
// sort and that is slower than just dereferencing a pointer likere
// here. There are other types for which the priv pointer is
// managed using shared_ptr just fine, because those didn't show up
// during our performance profiling.
priv* priv_;
/// Facility to hash instances of decl_base.
struct hash;
/// ELF visibility
enum visibility
{
VISIBILITY_NONE,
VISIBILITY_DEFAULT,
VISIBILITY_PROTECTED,
VISIBILITY_HIDDEN,
VISIBILITY_INTERNAL
};
/// ELF binding
enum binding
{
BINDING_NONE,
BINDING_LOCAL,
BINDING_GLOBAL,
BINDING_WEAK
};
virtual void
set_scope(scope_decl*);
protected:
const context_rel*
get_context_rel() const;
context_rel*
get_context_rel();
void
set_context_rel(context_rel_sptr c);
public:
decl_base(const environment* e,
const string& name,
const location& locus,
const string& mangled_name = "",
visibility vis = VISIBILITY_DEFAULT);
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&);
virtual bool
operator==(const decl_base&) const;
virtual bool
operator!=(const decl_base&) const;
virtual bool
traverse(ir_node_visitor& v);
virtual ~decl_base();
virtual size_t
get_hash() const;
virtual string
get_pretty_representation(bool internal = false) const;
virtual void
get_qualified_name(interned_string& qualified_name,
bool internal = false) const;
virtual const interned_string&
get_qualified_name(bool internal = false) const;
bool
get_is_in_public_symbol_table() const;
void
set_is_in_public_symbol_table(bool);
const location&
get_location() const;
void
set_location(const location& l);
const interned_string&
get_name() const;
const interned_string&
get_qualified_parent_name() const;
void
set_name(const string& n);
bool
get_is_anonymous() const;
void
set_is_anonymous(bool);
const interned_string&
get_linkage_name() const;
virtual void
set_linkage_name(const string& m);
scope_decl*
get_scope() const;
visibility
get_visibility() const;
void
set_visibility(visibility v);
friend bool
equals(const decl_base&, const decl_base&, change_kind*);
friend bool
equals(const var_decl&, const var_decl&, change_kind*);
friend decl_base_sptr
add_decl_to_scope(decl_base_sptr decl, scope_decl* scpe);
friend void
remove_decl_from_scope(decl_base_sptr);
friend decl_base_sptr
insert_decl_into_scope(decl_base_sptr,
vector<shared_ptr<decl_base> >::iterator,
scope_decl*);
friend enum access_specifier
get_member_access_specifier(const decl_base& d);
friend enum access_specifier
get_member_access_specifier(const decl_base_sptr& d);
friend void
set_member_access_specifier(decl_base& d,
access_specifier a);
friend bool
get_member_is_static(const decl_base& d);
friend bool
get_member_is_static(const decl_base_sptr& d);
friend void
set_member_is_static(const decl_base_sptr& d, bool s);
friend void
set_member_is_static(decl_base& d, bool s);
friend bool
get_member_function_is_virtual(const function_decl& f);
friend void
set_member_function_is_virtual(function_decl&, bool);
friend class class_decl;
friend class scope_decl;
};// end class decl_base
bool
operator==(const decl_base_sptr&, const decl_base_sptr&);
bool
operator==(const type_base_sptr&, const type_base_sptr&);
bool
operator!=(const type_base_sptr&, const type_base_sptr&);
std::ostream&
operator<<(std::ostream&, decl_base::visibility);
std::ostream&
operator<<(std::ostream&, decl_base::binding);
bool
equals(const scope_decl&, const scope_decl&, change_kind*);
/// Convenience typedef for a shared pointer on a @ref scope_decl.
typedef shared_ptr<scope_decl> scope_decl_sptr;
/// A declaration that introduces a scope.
class scope_decl : public virtual decl_base
{
public:
/// Convenience typedef for a vector of @ref decl_base_sptr.
typedef std::vector<decl_base_sptr > declarations;
/// Convenience typedef for a vector of @ref function_type_sptr.
typedef std::vector<function_type_sptr > function_types;
/// Convenience typedef for a vector of @ref scope_decl_sptr.
typedef std::vector<scope_decl_sptr> scopes;
/// The type of the private data of @ref scope_decl.
struct priv;
/// A convenience typedef for a shared pointer to scope_decl::priv.
typedef shared_ptr<priv> priv_sptr;
private:
priv_sptr priv_;
scope_decl();
protected:
virtual decl_base_sptr
add_member_decl(const decl_base_sptr& member);
virtual decl_base_sptr
insert_member_decl(const decl_base_sptr& member,
declarations::iterator before);
virtual void
remove_member_decl(decl_base_sptr member);
public:
struct hash;
scope_decl(const environment* env,
const string& name, const location& locus,
visibility vis = VISIBILITY_DEFAULT);
scope_decl(const environment* env, location& l);
virtual size_t
get_hash() const;
virtual bool
operator==(const decl_base&) const;
const declarations&
get_member_decls() const;
declarations&
get_member_decls();
scopes&
get_member_scopes();
const scopes&
get_member_scopes() const;
bool
is_empty() const;
bool
find_iterator_for_member(const decl_base*, declarations::iterator&);
bool
find_iterator_for_member(const decl_base_sptr, declarations::iterator&);
virtual bool
traverse(ir_node_visitor&);
virtual ~scope_decl();
friend decl_base_sptr
add_decl_to_scope(decl_base_sptr decl, scope_decl* scope);
friend decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,
scope_decl::declarations::iterator before,
scope_decl* scope);
friend void
remove_decl_from_scope(decl_base_sptr decl);
};//end class scope_decl
bool
operator==(const scope_decl_sptr&, const scope_decl_sptr&);
bool
operator!=(const scope_decl_sptr&, const scope_decl_sptr&);
/// Hasher for the @ref scope_decl type.
struct scope_decl::hash
{
size_t
operator()(const scope_decl& d) const;
size_t
operator()(const scope_decl* d) const;
};
/// Convenience typedef for shared pointer on @ref global_scope.
typedef shared_ptr<global_scope> global_scope_sptr;
/// This abstracts the global scope of a given translation unit.
///
/// Only one instance of this class must be present in a given
/// translation_unit. That instance is implicitely created the first
/// time translatin_unit::get_global_scope is invoked.
class global_scope : public scope_decl
{
translation_unit* translation_unit_;
global_scope(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:
friend class translation_unit;
translation_unit*
get_translation_unit() const
{return translation_unit_;}
virtual ~global_scope();
};
bool
equals(const type_base&, const type_base&, change_kind*);
/// An abstraction helper for type declarations
class type_base : public virtual type_or_decl_base
{
struct priv;
protected:
// This priv pointer is not handled by a shared_ptr because
// accessing the data members of the priv struct for this type_base
// shows up on performance profiles when dealing with big binaries
// with a lot of types; dereferencing the shared_ptr involves
// locking of some sort and that is slower than just dereferencing a
// pointer likere here. There are other types for which the priv
// pointer is managed using shared_ptr just fine, because those
// didn't show up during our performance profiling.
priv* priv_;
private:
// Forbid this.
type_base();
static type_base_sptr
get_canonical_type_for(type_base_sptr);
public:
/// A hasher for type_base types.
struct hash;
/// A hasher for types. It gets the dynamic type of the current
/// instance of type and hashes it accordingly. Note that the hashing
/// function of this hasher must be updated each time a new kind of
/// type is added to the IR.
struct dynamic_hash;
/// A hasher for shared_ptr<type_base> that will hash it based on the
/// runtime type of the type pointed to.
struct shared_ptr_hash;
type_base(const environment* e, size_t s, size_t a);
friend type_base_sptr
canonicalize(type_base_sptr);
type_base_sptr
get_canonical_type() const;
type_base*
get_naked_canonical_type() const;
virtual bool
operator==(const type_base&) const;
virtual bool
operator!=(const type_base&) const;
virtual bool
traverse(ir_node_visitor&);
virtual ~type_base();
virtual void
set_size_in_bits(size_t);
virtual size_t
get_size_in_bits() const;
virtual void
set_alignment_in_bits(size_t);
virtual size_t
get_alignment_in_bits() const;
};//end class type_base
/// Hash functor for instances of @ref type_base.
struct type_base::hash
{
size_t
operator()(const type_base& t) const;
size_t
operator()(const type_base* t) const;
size_t
operator()(const type_base_sptr t) const;
}; // end struct type_base::hash
/// A predicate for deep equality of instances of
/// type_base*
struct type_ptr_equal
{
bool
operator()(const type_base* l, const type_base* r) const
{
if (!!l != !!r)
return false;
if (l == r)
return true;
if (l)
return *l == *r;
return true;
}
};
/// A predicate for deep equality of instances of
/// shared_ptr<type_base>
struct type_shared_ptr_equal
{
bool
operator()(const type_base_sptr l, const type_base_sptr r) const
{
if (!!l != !!r)
return false;
if (l.get() == r.get())
return true;
if (l)
return *l == *r;
return true;
}
};
bool
equals(const type_decl&, const type_decl&, change_kind*);
/// A basic type declaration that introduces no scope.
class type_decl : public virtual decl_base, public virtual type_base
{
// Forbidden.
type_decl();
public:
/// Facility to hash instance of type_decl
struct hash;
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;
virtual bool
operator==(const decl_base&) const;
virtual bool
operator==(const type_decl&) const;
bool operator!=(const type_decl&)const;
virtual string
get_pretty_representation(bool internal = false) const;
virtual bool
traverse(ir_node_visitor&);
virtual ~type_decl();
};// end class type_decl.
bool
equals(const scope_type_decl&, const scope_type_decl&, change_kind*);
bool
operator==(const type_decl_sptr&, const type_decl_sptr&);
bool
operator!=(const type_decl_sptr&, const type_decl_sptr&);
/// A type that introduces a scope.
class scope_type_decl : public scope_decl, public virtual type_base
{
scope_type_decl();
public:
/// Hasher for instances of scope_type_decl
struct hash;
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;
virtual bool
operator==(const type_base&) const;
virtual bool
traverse(ir_node_visitor&);
virtual ~scope_type_decl();
};
/// Convenience typedef for a shared pointer on namespace_decl.
typedef shared_ptr<namespace_decl> namespace_decl_sptr;
/// The abstraction of a namespace declaration
class namespace_decl : public scope_decl
{
public:
namespace_decl(const environment* env, const string& name,
const location& locus, visibility vis = VISIBILITY_DEFAULT);
virtual string
get_pretty_representation(bool internal = false) const;
virtual bool
operator==(const decl_base&) const;
virtual bool
traverse(ir_node_visitor&);
virtual ~namespace_decl();
bool is_empty_or_has_empty_sub_namespaces() const;
};// end class namespace_decl
bool
equals(const qualified_type_def&, const qualified_type_def&, change_kind*);
typedef shared_ptr<qualified_type_def> qualified_type_def_sptr;
/// The abstraction of a qualified type.
class qualified_type_def : public virtual type_base, public virtual decl_base
{
class priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
// Forbidden.
qualified_type_def();
protected:
string build_name(bool, bool internal = false) const;
public:
/// A Hasher for instances of qualified_type_def
struct hash;
/// Bit field values representing the cv qualifiers of the
/// underlying type.
enum CV
{
CV_NONE = 0,
CV_CONST = 1,
CV_VOLATILE = 1 << 1,
CV_RESTRICT = 1 << 2
};
qualified_type_def(type_base_sptr type, CV quals, const location& locus);
virtual size_t
get_size_in_bits() const;
virtual bool
operator==(const decl_base&) const;
virtual bool
operator==(const type_base&) const;
virtual bool
operator==(const qualified_type_def&) const;
CV
get_cv_quals() const;
void
set_cv_quals(CV cv_quals);
string
get_cv_quals_string_prefix() const;
type_base_sptr
get_underlying_type() const;
virtual void
get_qualified_name(interned_string& qualified_name,
bool internal = false) const;
virtual const interned_string&
get_qualified_name(bool internal = false) const;
virtual bool
traverse(ir_node_visitor& v);
virtual ~qualified_type_def();
}; // end class qualified_type_def.
bool
operator==(const qualified_type_def_sptr&, const qualified_type_def_sptr&);
bool
operator!=(const qualified_type_def_sptr&, const qualified_type_def_sptr&);
qualified_type_def::CV
operator|(qualified_type_def::CV, qualified_type_def::CV);
qualified_type_def::CV
operator&(qualified_type_def::CV, qualified_type_def::CV);
qualified_type_def::CV
operator~(qualified_type_def::CV);
std::ostream&
operator<<(std::ostream&, qualified_type_def::CV);
bool
equals(const pointer_type_def&, const pointer_type_def&, change_kind*);
/// Convenience typedef for a shared pointer on a @ref pointer_type_def
typedef shared_ptr<pointer_type_def> pointer_type_def_sptr;
/// The abstraction of a pointer type.
class pointer_type_def : public virtual type_base, public virtual decl_base
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
// Forbidden.
pointer_type_def();
public:
/// A hasher for instances of pointer_type_def
struct hash;
pointer_type_def(const type_base_sptr& pointed_to_type, size_t size_in_bits,
size_t alignment_in_bits, const location& locus);
virtual bool
operator==(const decl_base&) const;
virtual bool
operator==(const type_base&) const;
bool
operator==(const pointer_type_def&) const;
const type_base_sptr
get_pointed_to_type() const;
type_base*
get_naked_pointed_to_type() const;
virtual void
get_qualified_name(interned_string&, bool internal = false) const;
virtual const interned_string&
get_qualified_name(bool internal = false) const;
virtual bool
traverse(ir_node_visitor& v);
virtual ~pointer_type_def();
}; // end class pointer_type_def
bool
operator==(const pointer_type_def_sptr&, const pointer_type_def_sptr&);
bool
operator!=(const pointer_type_def_sptr&, const pointer_type_def_sptr&);
bool
equals(const reference_type_def&, const reference_type_def&, change_kind*);
/// Convenience typedef for a shared pointer on a @ref reference_type_def
typedef shared_ptr<reference_type_def> reference_type_def_sptr;
/// Abstracts a reference type.
class reference_type_def : public virtual type_base, public virtual decl_base
{
type_base_wptr pointed_to_type_;
bool is_lvalue_;
// Forbidden.
reference_type_def();
public:
/// Hasher for intances of reference_type_def.
struct hash;
reference_type_def(const type_base_sptr pointed_to_type,
bool lvalue, size_t size_in_bits,
size_t alignment_in_bits, const location& locus);
virtual bool
operator==(const decl_base&) const;
virtual bool
operator==(const type_base&) const;
bool
operator==(const reference_type_def&) const;
type_base_sptr
get_pointed_to_type() const;
bool
is_lvalue() const;
virtual void
get_qualified_name(interned_string& qualified_name,
bool internal = false) const;
virtual const interned_string&
get_qualified_name(bool internal = false) const;
virtual bool
traverse(ir_node_visitor& v);
virtual ~reference_type_def();
}; // end class reference_type_def
bool
operator==(const reference_type_def_sptr&, const reference_type_def_sptr&);
bool
operator!=(const reference_type_def_sptr&, const reference_type_def_sptr&);
bool
equals(const array_type_def&, const array_type_def&, change_kind*);
/// Convenience typedef for a shared pointer on a @ref array_type_def
typedef shared_ptr<array_type_def> array_type_def_sptr;
/// The abstraction of an array type.
class array_type_def : public virtual type_base, public virtual decl_base
{
private:
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
// Forbidden.
array_type_def();
public:
/// Hasher for intances of array_type_def.
struct hash;
class subrange_type;
/// Convenience typedef for a shared pointer on a @ref
/// function_decl::subrange
typedef shared_ptr<subrange_type> subrange_sptr;
/// Convenience typedef for a vector of @ref subrange_sptr
typedef std::vector<subrange_sptr> subranges_type;
/// Abtraction for an array dimension
class subrange_type
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
// Forbidden.
subrange_type();
public:
/// Hasher for an instance of array::subrange
struct hash;
subrange_type(size_t lower_bound,
size_t upper_bound,
const location& loc);
subrange_type(size_t upper_bound, const location& loc);
size_t
get_upper_bound() const;
size_t
get_lower_bound() const;
void
set_upper_bound(size_t ub);
void
set_lower_bound(size_t lb);
size_t
get_length() const;
bool
is_infinite() const;
bool
operator==(const subrange_type& o) const;
bool
operator!=(const subrange_type& o) const;
const location&
get_location() const;
string
as_string() const;
static string
vector_as_string(const vector<subrange_sptr>&);
};
array_type_def(const type_base_sptr type,
const std::vector<subrange_sptr>& subs,
const location& locus);
virtual bool
operator==(const decl_base&) const;
virtual bool
operator==(const type_base&) const;
virtual void
get_qualified_name(interned_string& qualified_name,
bool internal = false) const;
virtual const interned_string&
get_qualified_name(bool internal = false) const;
const type_base_sptr
get_element_type() const;
virtual void
append_subrange(subrange_sptr sub);
virtual void
append_subranges(const std::vector<subrange_sptr>& subs);
virtual int
get_dimension_count() const;
virtual bool
is_infinite() const;
virtual string
get_pretty_representation(bool internal = false) const;
virtual string
get_subrange_representation() const;
virtual bool
traverse(ir_node_visitor& v);
const location&
get_location() const;
const std::vector<subrange_sptr>&
get_subranges() const;
virtual ~array_type_def();
}; // end class array_type_def
bool
equals(const enum_type_decl&, const enum_type_decl&, change_kind*);
/// Convenience typedef for shared pointer on enum_type_decl.
typedef shared_ptr<enum_type_decl> enum_type_decl_sptr;
/// Abstracts a declaration for an enum type.
class enum_type_decl : public virtual type_base, public virtual decl_base
{
public:
/// A hasher for an enum_type_decl.
struct hash;
/// Enumerator Datum.
class enumerator;
/// Convenience typedef for a list of @ref enumerator.
typedef std::vector<enumerator> enumerators;
private:
class priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
// Forbidden
enum_type_decl();
public:
/// Constructor of an enum type declaration.
///
/// @param name the name of the enum
///
/// @param locus the locus at which the enum appears in the source
/// code.
///
/// @param underlying_type the underlying type of the enum
///
/// @param enms a list of enumerators for this enum.
///
/// @param mangled_name the mangled name of the enum type.
///
/// @param vis the visibility of instances of this type.
enum_type_decl(const string& name,
const location& locus,
type_base_sptr underlying_type,
enumerators& enms,
const string& mangled_name = "",
visibility vis = VISIBILITY_DEFAULT);
type_base_sptr
get_underlying_type() const;
const enumerators&
get_enumerators() const;
enumerators&
get_enumerators();
virtual string
get_pretty_representation(bool internal = false) const;
virtual bool
operator==(const decl_base&) const;
virtual bool
operator==(const type_base&) const;
virtual bool
traverse(ir_node_visitor& v);
virtual ~enum_type_decl();
}; // end class enum_type_decl
bool
operator==(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r);
bool
operator!=(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r);
/// The abstraction of an enumerator
class enum_type_decl::enumerator
{
class priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
public:
enumerator();
enumerator(const environment* env, const string& name, int64_t value);
enumerator(const enumerator&);
bool
operator==(const enumerator& other) const;
bool
operator!=(const enumerator& other) const;
const environment*
get_environment() const;
const interned_string&
get_name() const;
const interned_string&
get_qualified_name(bool internal = false) const;
void
set_name(const string& n);
int64_t
get_value() const;
void
set_value(int64_t v);
enum_type_decl*
get_enum_type() const;
void
set_enum_type(enum_type_decl*);
}; // end class enum_type_def::enumerator
bool
equals(const typedef_decl&, const typedef_decl&, change_kind*);
/// Convenience typedef for a shared pointer on a @ref typedef_decl.
typedef shared_ptr<typedef_decl> typedef_decl_sptr;
/// The abstraction of a typedef declaration.
class typedef_decl : public virtual type_base, public virtual decl_base
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
// Forbidden
typedef_decl();
public:
/// Hasher for the typedef_decl type.
struct hash;
typedef_decl(const string& name,
const type_base_sptr underlying_type,
const location& locus,
const string& mangled_name = "",
visibility vis = VISIBILITY_DEFAULT);
virtual size_t
get_size_in_bits() const;
virtual size_t
get_alignment_in_bits() const;
virtual bool
operator==(const decl_base&) const;
virtual bool
operator==(const type_base&) const;
virtual string
get_pretty_representation(bool internal = false) const;
type_base_sptr
get_underlying_type() const;
virtual bool
traverse(ir_node_visitor&);
virtual ~typedef_decl();
};// end class typedef_decl
class dm_context_rel;
/// A convenience typedef for a shared pointer to dm_context_rel.
typedef shared_ptr<dm_context_rel> dm_context_rel_sptr;
/// The abstraction for a data member context relationship. This
/// relates a data member to its parent class.
///
/// The relationship carries properties like the offset of the data
/// member, if applicable.
class dm_context_rel : public context_rel
{
protected:
bool is_laid_out_;
size_t offset_in_bits_;
public:
dm_context_rel()
: context_rel(),
is_laid_out_(!is_static_),
offset_in_bits_(0)
{}
dm_context_rel(scope_decl* s,
bool is_laid_out,
size_t offset_in_bits,
access_specifier a,
bool is_static)
: context_rel(s, a, is_static),
is_laid_out_(is_laid_out),
offset_in_bits_(offset_in_bits)
{}
dm_context_rel(scope_decl* s)
: context_rel(s),
is_laid_out_(!is_static_),
offset_in_bits_(0)
{}
bool
get_is_laid_out() const
{return is_laid_out_;}
void
set_is_laid_out(bool f)
{is_laid_out_ = f;}
size_t
get_offset_in_bits() const
{return offset_in_bits_;}
void
set_offset_in_bits(size_t o)
{offset_in_bits_ = o;}
bool
operator==(const dm_context_rel& o) const
{
if (!context_rel::operator==(o))
return false;
return (is_laid_out_ == o.is_laid_out_
&& offset_in_bits_ == o.offset_in_bits_);
}
bool
operator!=(const dm_context_rel& o) const
{return !operator==(o);}
virtual ~dm_context_rel();
};// end class class_decl::dm_context_rel
bool
equals(const var_decl&, const var_decl&, change_kind*);
/// Convenience typedef for a shared pointer on a @ref var_decl
typedef shared_ptr<var_decl> var_decl_sptr;
/// Abstracts a variable declaration.
class var_decl : public virtual decl_base
{
struct priv;
shared_ptr<priv> priv_;
// Forbidden
var_decl();
virtual void
set_scope(scope_decl*);
public:
/// Hasher for a var_decl type.
struct hash;
/// Equality functor to compare pointers to variable_decl.
struct ptr_equal;
var_decl(const string& name,
type_base_sptr type,
const location& locus,
const string& mangled_name,
visibility vis = VISIBILITY_DEFAULT,
binding bind = BINDING_NONE);
virtual bool
operator==(const decl_base&) const;
const type_base_sptr
get_type() const;
const type_base*
get_naked_type() const;
binding
get_binding() const;
void
set_binding(binding b);
void
set_symbol(const elf_symbol_sptr& sym);
const elf_symbol_sptr&
get_symbol() const;
var_decl_sptr
clone() const;
interned_string
get_id() const;
virtual size_t
get_hash() const;
virtual string
get_pretty_representation(bool internal = false) const;
virtual bool
traverse(ir_node_visitor& v);
virtual ~var_decl();
friend void
set_data_member_offset(var_decl_sptr m, size_t o);
friend size_t
get_data_member_offset(const var_decl_sptr m);
friend size_t
get_data_member_offset(const var_decl& m);
friend void
set_data_member_is_laid_out(var_decl_sptr m, bool l);
friend bool
get_data_member_is_laid_out(const var_decl& m);
friend bool
get_data_member_is_laid_out(const var_decl_sptr m);
}; // end class var_decl
bool
equals(const function_decl&, const function_decl&, change_kind*);
/// Convenience typedef for a shared pointer on a @ref function_decl
typedef shared_ptr<function_decl> function_decl_sptr;
/// Abstraction for a function declaration.
class function_decl : public virtual decl_base
{
struct priv;
// This priv pointer is not handled by a shared_ptr because
// accessing the data members of the priv struct for this
// function_decl shows up on performance profiles when dealing with
// big binaries with a lot of types; dereferencing the shared_ptr
// involves locking of some sort and that is slower than just
// dereferencing a pointer likere here. There are other types for
// which the priv pointer is managed using shared_ptr just fine,
// because those didn't show up during our performance profiling.
priv* priv_;
public:
/// Hasher for function_decl
struct hash;
/// Equality functor to compare pointers to function_decl
struct ptr_equal;
class parameter;
/// Convenience typedef for a shared pointer on a @ref
/// function_decl::parameter
typedef shared_ptr<parameter> parameter_sptr;
/// Convenience typedef for a vector of @ref parameter_sptr
typedef std::vector<parameter_sptr> parameters;
/// Abtraction for the parameter of a function.
class parameter;
function_decl(const string& name,
function_type_sptr function_type,
bool declared_inline,
const location& locus,
const string& mangled_name,
visibility vis,
binding bind);
function_decl(const string& name,
type_base_sptr fn_type,
bool declared_inline,
const location& locus,
const string& mangled_name = "",
visibility vis = VISIBILITY_DEFAULT,
binding bind = BINDING_GLOBAL);
virtual string
get_pretty_representation(bool internal = false) const;
string
get_pretty_representation_of_declarator () const;
const std::vector<parameter_sptr >&
get_parameters() const;
void
append_parameter(parameter_sptr parm);
void
append_parameters(std::vector<parameter_sptr >& parms);
parameters::const_iterator
get_first_non_implicit_parm() const;
const function_type_sptr
get_type() const;
const function_type*
get_naked_type() const;
const type_base_sptr
get_return_type() const;
void
set_type(const function_type_sptr& fn_type);
void
set_symbol(const elf_symbol_sptr& sym);
const elf_symbol_sptr&
get_symbol() const;
bool
is_declared_inline() const;
binding
get_binding() const;
function_decl_sptr
clone() const;
virtual bool
operator==(const decl_base& o) const;
/// Return true iff the function takes a variable number of
/// parameters.
///
/// @return true if the function taks a variable number
/// of parameters.
bool
is_variadic() const;
virtual size_t
get_hash() const;
interned_string
get_id() const;
virtual bool
traverse(ir_node_visitor&);
virtual ~function_decl();
}; // end class function_decl
bool
function_decls_alias(const function_decl& f1, const function_decl& f2);
bool
equals(const function_decl::parameter&,
const function_decl::parameter&,
change_kind*);
/// Abstraction of a function parameter.
class function_decl::parameter : public decl_base
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
public:
/// Hasher for an instance of function::parameter
struct hash;
parameter(const type_base_sptr type,
unsigned index,
const string& name,
const location& loc,
bool variadic_marker = false);
parameter(const type_base_sptr type,
unsigned index,
const string& name,
const location& loc,
bool variadic_marker,
bool is_artificial);
parameter(const type_base_sptr type,
const string& name,
const location& loc,
bool variadic_marker = false,
bool is_artificial = false);
parameter(const type_base_sptr type,
unsigned index = 0,
bool variadic_marker = false);
const type_base_sptr
get_type()const;
interned_string
get_type_name() const;
const string
get_type_pretty_representation() const;
interned_string
get_name_id() const;
unsigned
get_index() const;
void
set_index(unsigned i);
bool
get_artificial() const;
void
set_artificial(bool f);
bool
get_variadic_marker() const;
bool
operator==(const parameter& o) const;
virtual bool
operator==(const decl_base&) const;
virtual bool
traverse(ir_node_visitor& v);
virtual size_t
get_hash() const;
virtual void
get_qualified_name(interned_string& qualified_name,
bool internal = false) const;
virtual string
get_pretty_representation(bool internal = false) const;
}; // end class function_decl::parameter
bool
operator==(const function_decl::parameter_sptr&,
const function_decl::parameter_sptr&);
/// A hashing functor for a function_decl::parameter.
struct function_decl::parameter::hash
{
size_t
operator()(const function_decl::parameter&) const;
size_t
operator()(const function_decl::parameter*) const;
size_t
operator()(const function_decl::parameter_sptr) const;
}; // end struct function_decl::parameter::hash
function_decl::parameter*
is_function_parameter(const type_or_decl_base*);
function_decl::parameter_sptr
is_function_parameter(const type_or_decl_base_sptr tod);
bool
equals(const function_type&, const function_type&, change_kind*);
/// Abstraction of a function type.
class function_type : public virtual type_base
{
struct priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
public:
/// Hasher for an instance of function_type
struct hash;
/// Convenience typedef for a shared pointer on a @ref
/// function_decl::parameter
typedef shared_ptr<function_decl::parameter> parameter_sptr;
/// Convenience typedef for a vector of @ref parameter_sptr
typedef std::vector<parameter_sptr> parameters;
private:
function_type();
public:
function_type(type_base_sptr return_type,
const parameters& parms,
size_t size_in_bits,
size_t alignment_in_bits);
function_type(type_base_sptr return_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;
void
set_return_type(type_base_sptr t);
const parameters&
get_parameters() const;
const parameter_sptr
get_parm_at_index_from_first_non_implicit_parm(size_t) const;
void
set_parameters(const parameters &p);
void
append_parameter(parameter_sptr parm);
bool
is_variadic() const;
parameters::const_iterator
get_first_non_implicit_parm() const;
virtual bool
operator==(const type_base&) const;
virtual string
get_pretty_representation(bool internal = false) const;
virtual bool
traverse(ir_node_visitor&);
virtual ~function_type();
friend bool
equals(const function_type&, const function_type&, change_kind*);
};//end class function_type
/// The hashing functor for @ref function_type.
struct function_type::hash
{
size_t
operator()(const function_type& t) const;
size_t
operator()(const function_type* t) const;
size_t
operator()(const function_type_sptr t) const;
};// end struct function_type::hash
/// Convenience typedef for shared pointer to @ref method_type.
typedef shared_ptr<method_type> method_type_sptr;
/// Abstracts the type of a class member function.
class method_type : public function_type
{
class_or_union_wptr class_type_;
method_type();
public:
/// Hasher for intances of method_type
struct hash;
method_type(type_base_sptr return_type,
class_or_union_sptr class_type,
const std::vector<function_decl::parameter_sptr>& parms,
size_t size_in_bits,
size_t alignment_in_bits);
method_type(type_base_sptr return_type,
type_base_sptr class_type,
const std::vector<function_decl::parameter_sptr>& parms,
size_t size_in_bits,
size_t alignment_in_bits);
method_type(class_or_union_sptr class_type,
size_t size_in_bits,
size_t alignment_in_bits);
method_type(const environment* env,
size_t size_in_bits,
size_t alignment_in_bits);
class_or_union_sptr
get_class_type() const
{return class_or_union_sptr(class_type_);}
void
set_class_type(const class_or_union_sptr& t);
virtual string
get_pretty_representation(bool internal = false) const;
virtual ~method_type();
};// end class method_type.
/// Convenience typedef for shared pointer to template parameter
typedef shared_ptr<template_parameter> template_parameter_sptr;
/// Convenience typedef for a shared pointer to @ref template_decl
typedef shared_ptr<template_decl> template_decl_sptr;
/// Convenience typedef for a weak pointer to template_decl
typedef weak_ptr<template_decl> template_decl_wptr;
/// The base class of templates.
class template_decl : public virtual decl_base
{
class priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
template_decl();
public:
/// Hasher.
struct hash;
template_decl(const environment* env,
const string& name,
const location& locus,
visibility vis = VISIBILITY_DEFAULT);
void
add_template_parameter(const template_parameter_sptr p);
const std::list<template_parameter_sptr>&
get_template_parameters() const;
virtual bool
operator==(const template_decl& o) const;
virtual ~template_decl();
};//end class template_decl
/// Convenience typedef for a shared_ptr to @ref template_parameter
typedef shared_ptr<template_parameter> template_parameter_sptr;
/// Base class for a template parameter. Client code should use the
/// more specialized type_template_parameter,
/// non_type_template_parameter and template_template_parameter below.
class template_parameter
{
class priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
// Forbidden
template_parameter();
public:
/// Hashers.
struct hash;
struct dynamic_hash;
struct shared_ptr_hash;
template_parameter(unsigned index,
template_decl_sptr enclosing_tdecl);
virtual bool
operator==(const template_parameter&) const;
bool
operator!=(const template_parameter&) const;
unsigned
get_index() const;
const template_decl_sptr
get_enclosing_template_decl() const;
bool
get_hashing_has_started() const;
void
set_hashing_has_started(bool f) const;
virtual ~template_parameter();
};//end class template_parameter
struct template_decl::hash
{
size_t
operator()(const template_decl& t) const;
};// end struct template_decl::hash
/// Convenience typedef for a shared pointer to @ref type_tparameter.
typedef shared_ptr<type_tparameter> type_tparameter_sptr;
/// Abstracts a type template parameter.
class type_tparameter : public template_parameter, public virtual type_decl
{
class priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
// Forbidden
type_tparameter();
public:
/// Hasher.
struct hash;
type_tparameter(unsigned index,
template_decl_sptr enclosing_tdecl,
const string& name,
const location& locus);
virtual bool
operator==(const type_base&) const;
virtual bool
operator==(const template_parameter&) const;
virtual bool
operator==(const type_tparameter&) const;
virtual ~type_tparameter();
};// end class type_tparameter.
/// Convenience typedef for shared pointer to @ref
/// non_type_template_parameter
typedef shared_ptr<non_type_tparameter> non_type_tparameter_sptr;
/// Abstracts non type template parameters.
class non_type_tparameter : public template_parameter, public virtual decl_base
{
class priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
type_base_wptr type_;
// Forbidden
non_type_tparameter();
public:
/// Hasher.
struct hash;
non_type_tparameter(unsigned index,
template_decl_sptr enclosing_tdecl,
const string& name,
type_base_sptr type,
const location& locus);
virtual size_t
get_hash() const;
virtual bool
operator==(const decl_base&) const;
virtual bool
operator==(const template_parameter&) const;
const type_base_sptr
get_type() const;
virtual ~non_type_tparameter();
};// end class non_type_tparameter
/// Hasher for the @ref non_type_tparameter type.
struct non_type_tparameter::hash
{
size_t
operator()(const non_type_tparameter& t) const;
size_t
operator()(const non_type_tparameter* t) const;
};
class template_tparameter;
/// Convenience typedef for a shared_ptr to @ref template_tparameter.
typedef shared_ptr<template_tparameter> template_tparameter_sptr;
/// Abstracts a template template parameter.
class template_tparameter : public type_tparameter, public template_decl
{
class priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
// Forbidden
template_tparameter();
public:
/// A hasher for instances of template_tparameter
struct hash;
template_tparameter(unsigned index,
template_decl_sptr enclosing_tdecl,
const string& name,
const location& locus);
virtual bool
operator==(const type_base&) const;
virtual bool
operator==(const template_parameter&) const;
virtual bool
operator==(const template_decl&) const;
virtual ~template_tparameter();
};
/// Convenience typedef for shared pointer to type_composition
typedef shared_ptr<type_composition> type_composition_sptr;
/// This abstracts a composition of types based on template type
/// parameters. The result of the composition is a type that can be
/// referred to by a template non-type parameter. Instances of this
/// type can appear at the same level as template parameters, in the
/// scope of a template_decl.
class type_composition : public template_parameter, public virtual decl_base
{
class priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
type_composition();
public:
struct hash;
type_composition(unsigned index,
template_decl_sptr tdecl,
type_base_sptr composed_type);
const type_base_sptr
get_composed_type() const;
void
set_composed_type(type_base_sptr t);
virtual size_t
get_hash() const;
virtual ~type_composition();
};
/// Hasher for the @ref type_composition type.
struct type_composition::hash
{
size_t
operator()(const type_composition& t) const;
size_t
operator()(const type_composition* t) const;
}; //struct type_composition::hash
/// Convenience typedef for a shared pointer on a @ref function_tdecl
typedef shared_ptr<function_tdecl> function_tdecl_sptr;
/// Abstract a function template declaration.
class function_tdecl : public template_decl, public scope_decl
{
class priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
// Forbidden
function_tdecl();
public:
/// Hash functor for function templates.
struct hash;
struct shared_ptr_hash;
function_tdecl(const environment* env,
const location& locus,
visibility vis = VISIBILITY_DEFAULT,
binding bind = BINDING_NONE);
function_tdecl(function_decl_sptr pattern,
const location& locus,
visibility vis = VISIBILITY_DEFAULT,
binding bind = BINDING_NONE);
virtual bool
operator==(const decl_base&) const;
virtual bool
operator==(const template_decl&) const;
virtual bool
operator==(const function_tdecl&) const;
void
set_pattern(shared_ptr<function_decl> p);
shared_ptr<function_decl>
get_pattern() const;
binding
get_binding() const;
virtual bool
traverse(ir_node_visitor& v);
virtual ~function_tdecl();
}; // end class function_tdecl.
/// Convenience typedef for a shared pointer on a @ref class_tdecl
typedef shared_ptr<class_tdecl> class_tdecl_sptr;
/// Abstract a class template.
class class_tdecl : public template_decl, public scope_decl
{
class priv;
typedef shared_ptr<priv> priv_sptr;
priv_sptr priv_;
// Forbidden
class_tdecl();
public:
/// Hashers.
struct hash;
struct shared_ptr_hash;
class_tdecl(const environment* env, const location& locus,
visibility vis = VISIBILITY_DEFAULT);
class_tdecl(class_decl_sptr pattern,
const location& locus,
visibility vis = VISIBILITY_DEFAULT);
virtual bool
operator==(const decl_base&) const;
virtual bool
operator==(const template_decl&) const;
virtual bool
operator==(const class_tdecl&) const;
void
set_pattern(class_decl_sptr p);
shared_ptr<class_decl>
get_pattern() const;
virtual bool
traverse(ir_node_visitor& v);
virtual ~class_tdecl();
};// end class class_tdecl
/// The base class for member types, data members and member
/// functions. Its purpose is mainly to carry the access specifier
/// (and possibly other properties that might be shared by all class
/// members) for the member.
class member_base
{
protected:
enum access_specifier access_;
bool is_static_;
private:
// Forbidden
member_base();
public:
/// Hasher.
struct hash;
member_base(access_specifier a, bool is_static = false)
: access_(a), is_static_(is_static)
{}
/// Getter for the access specifier of this member.
///
/// @return the access specifier for this member.
access_specifier
get_access_specifier() const
{return access_;}
/// Setter for the access specifier of this member.
///
/// @param a the new access specifier.
void
set_access_specifier(access_specifier a)
{access_ = a;}
/// @return true if the member is static, false otherwise.
bool
get_is_static() const
{return is_static_;}
/// Set a flag saying if the parameter is static or not.
///
/// @param f set to true if the member is static, false otherwise.
void
set_is_static(bool f)
{is_static_ = f;}
virtual bool
operator==(const member_base& o) const;
};// end class member_base
class method_decl;
typedef shared_ptr<method_decl> method_decl_sptr;
/// Abstraction of the declaration of a method.
class method_decl : public function_decl
{
method_decl();
virtual void
set_scope(scope_decl*);
public:
method_decl(const string& name, method_type_sptr type,
bool declared_inline, const location& locus,
const string& mangled_name = "",
visibility vis = VISIBILITY_DEFAULT,
binding bind = BINDING_GLOBAL);
method_decl(const string& name,
function_type_sptr type,
bool declared_inline,
const location& locus,
const string& mangled_name = "",
visibility vis = VISIBILITY_DEFAULT,
binding bind = BINDING_GLOBAL);
method_decl(const string& name, type_base_sptr type,
bool declared_inline, const location& locus,
const string& mangled_name = "",
visibility vis = VISIBILITY_DEFAULT,
binding bind = BINDING_GLOBAL);
virtual void
set_linkage_name(const string&);
/// @return the type of the current instance of the
/// method_decl.
const method_type_sptr
get_type() const;
void
set_type(const method_type_sptr fn_type)
{function_decl::set_type(fn_type);}
friend bool
get_member_function_is_ctor(const function_decl&);
friend void
set_member_function_is_ctor(function_decl&, bool);
friend void
set_member_function_is_ctor(const function_decl_sptr&, bool);
friend bool
get_member_function_is_dtor(const function_decl&);
friend void
set_member_function_is_dtor(function_decl&, bool);
friend void
set_member_function_is_dtor(const function_decl_sptr&, bool);
friend bool
get_member_function_is_static(const function_decl&);
friend void
set_member_function_is_static(const function_decl&, bool);
friend bool
get_member_function_is_const(const function_decl&);
friend void
set_member_function_is_const(function_decl&, bool);
friend void
set_member_function_is_const(const function_decl_sptr&, bool);
friend size_t
get_member_function_vtable_offset(const function_decl&);
friend void
set_member_function_vtable_offset(function_decl&, size_t);
friend void
set_member_function_vtable_offset(const function_decl_sptr&, size_t);
friend bool
get_member_function_is_virtual(const function_decl&);
friend void
set_member_function_is_virtual(function_decl&, bool);
virtual ~method_decl();
};// end class method_decl
class member_function_template;
typedef shared_ptr<member_function_template> member_function_template_sptr;
typedef vector<member_function_template_sptr> member_function_templates;
class member_class_template;
typedef shared_ptr<member_class_template> member_class_template_sptr;
typedef vector<member_class_template_sptr> member_class_templates;
/// The base type of @ref class_decl and @ref union_decl
class class_or_union : public scope_type_decl
{
struct priv;
priv *priv_;
// Forbidden
class_or_union();
protected:
virtual decl_base_sptr
add_member_decl(const decl_base_sptr&);
virtual decl_base_sptr
insert_member_decl(decl_base_sptr member, declarations::iterator before);
virtual void
remove_member_decl(decl_base_sptr);
public:
/// Hasher.
struct hash;
/// Convenience typedef
/// @{
typedef vector<type_base_sptr> member_types;
typedef vector<var_decl_sptr> data_members;
typedef vector<method_decl_sptr> member_functions;
typedef unordered_map<string, method_decl*> string_mem_fn_ptr_map_type;
/// @}
class_or_union(const environment* env, const string& name,
size_t size_in_bits, size_t align_in_bits,
const location& locus, visibility vis,
member_types& mbrs, data_members& data_mbrs,
member_functions& member_fns);
class_or_union(const environment* env, const string& name,
size_t size_in_bits, size_t align_in_bits,
const location& locus, visibility vis);
class_or_union(const environment* env, const string& name,
bool is_declaration_only = true);
virtual void
set_size_in_bits(size_t);
virtual size_t
get_size_in_bits() const;
virtual size_t
get_alignment_in_bits() const;
virtual void
set_alignment_in_bits(size_t);
bool
get_is_declaration_only() const;
void
set_is_declaration_only(bool f);
void
set_definition_of_declaration(class_or_union_sptr);
const class_or_union_sptr
get_definition_of_declaration() const;
decl_base_sptr
get_earlier_declaration() const;
void
set_earlier_declaration(decl_base_sptr declaration);
void
insert_member_type(type_base_sptr t,
declarations::iterator before);
void
add_member_type(type_base_sptr t);
type_base_sptr
add_member_type(type_base_sptr t, access_specifier a);
void
remove_member_type(type_base_sptr t);
const member_types&
get_member_types() const;
type_base_sptr
find_member_type(const string& name) const;
void
add_data_member(var_decl_sptr v, access_specifier a,
bool is_laid_out, bool is_static,
size_t offset_in_bits);
const data_members&
get_data_members() const;
const var_decl_sptr
find_data_member(const string&) const;
const data_members&
get_non_static_data_members() const;
void
add_member_function(method_decl_sptr f,
access_specifier a,
bool is_static, bool is_ctor,
bool is_dtor, bool is_const);
const member_functions&
get_member_functions() const;
const method_decl*
find_member_function(const string& mangled_name) const;
method_decl*
find_member_function(const string& mangled_name);
void
add_member_function_template(member_function_template_sptr);
const member_function_templates&
get_member_function_templates() const;
void
add_member_class_template(member_class_template_sptr m);
const member_class_templates&
get_member_class_templates() const;
bool
has_no_member() const;
virtual bool
operator==(const decl_base&) const;
virtual bool
operator==(const type_base&) const;
virtual bool
operator==(const class_or_union&) const;
virtual bool
traverse(ir_node_visitor& v);
virtual ~class_or_union();
friend method_decl_sptr
copy_member_function(class_or_union_sptr& t,
const method_decl*m);
friend method_decl_sptr
copy_member_function(class_or_union_sptr& t,
const method_decl_sptr& m);
friend void
fixup_virtual_member_function(method_decl_sptr method);
friend void
set_member_is_static(decl_base& d, bool s);
friend bool
equals(const class_or_union&, const class_or_union&, change_kind*);
friend bool
equals(const class_decl&, const class_decl&, change_kind*);
friend class method_decl;
friend class class_decl;
}; // end class class_or_union
method_decl_sptr
copy_member_function(const class_or_union_sptr& clazz,
const method_decl_sptr& f);
method_decl_sptr
copy_member_function(const class_or_union_sptr& clazz,
const method_decl* f);
/// Hasher for the @ref class_or_union type
struct class_or_union::hash
{
size_t
operator()(const class_or_union& t) const;
size_t
operator()(const class_or_union* t) const;
}; // end struct class_decl::hash
/// Abstracts a class declaration.
class class_decl : public class_or_union
{
// Forbidden
class_decl();
protected:
virtual decl_base_sptr
insert_member_decl(decl_base_sptr member, declarations::iterator before);
public:
/// Hasher.
struct hash;
/// Forward declarations.
class base_spec;
/// Convenience typedef
/// @{
typedef shared_ptr<base_spec> base_spec_sptr;
typedef vector<base_spec_sptr> base_specs;
/// @}
private:
struct priv;
// This priv it's not handled by a shared_ptr because accessing the
// data members of the priv struct for this class_decl shows up on
// performance profiles when dealing with big binaries with a lot of
// types; dereferencing the shared_ptr involves locking of some sort
// and that is slower than just dereferencing a pointer likere here.
// There are other types for which the priv pointer is managed using
// shared_ptr just fine, because those didn't show up during our
// performance profiling.
priv * priv_;
public:
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 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);
const class_decl_sptr
get_definition_of_declaration() const;
virtual string
get_pretty_representation(bool internal = false) const;
void
is_struct(bool f);
bool
is_struct() const;
void
add_base_specifier(shared_ptr<base_spec> b);
const base_specs&
get_base_specifiers() const;
class_decl_sptr
find_base_class(const string&) const;
void
add_member_function(method_decl_sptr f,
access_specifier a,
bool is_virtual,
size_t vtable_offset,
bool is_static, bool is_ctor,
bool is_dtor, bool is_const);
const member_functions&
get_virtual_mem_fns() const;
void
sort_virtual_mem_fns();
bool
has_no_base_nor_member() const;
bool
has_virtual_member_functions() const;
bool
has_virtual_bases() const;
bool
has_vtable() const;
virtual size_t
get_hash() const;
virtual bool
operator==(const decl_base&) const;
virtual bool
operator==(const type_base&) const;
virtual bool
operator==(const class_decl&) const;
virtual bool
traverse(ir_node_visitor& v);
virtual ~class_decl();
friend void
fixup_virtual_member_function(method_decl_sptr method);
friend void
set_member_is_static(decl_base& d, bool s);
friend bool
equals(const class_decl&, const class_decl&, change_kind*);
friend class method_decl;
};// end class class_decl
bool
equals(const class_decl&, const class_decl&, change_kind*);
method_decl_sptr
copy_member_function(const class_decl_sptr& clazz,
const method_decl_sptr& f);
method_decl_sptr
copy_member_function(const class_decl_sptr& clazz,
const method_decl* f);
void
fixup_virtual_member_function(method_decl_sptr method);
/// Hasher for the @ref class_decl type
struct class_decl::hash
{
size_t
operator()(const class_decl& t) const;
size_t
operator()(const class_decl* t) const;
}; // end struct class_decl::hash
enum access_specifier
get_member_access_specifier(const decl_base&);
enum access_specifier
get_member_access_specifier(const decl_base_sptr&);
void
set_member_access_specifier(decl_base&,
access_specifier);
void
set_member_access_specifier(const decl_base_sptr&,
access_specifier);
std::ostream&
operator<<(std::ostream&, access_specifier);
bool
operator==(const class_decl_sptr& l, const class_decl_sptr& r);
bool
operator!=(const class_decl_sptr& l, const class_decl_sptr& r);
bool
equals(const class_decl::base_spec&,
const class_decl::base_spec&,
change_kind*);
/// Abstraction of a base specifier in a class declaration.
class class_decl::base_spec : public member_base,
public virtual decl_base
{
struct priv;
typedef shared_ptr<priv>priv_sptr;
priv_sptr priv_;
// Forbidden
base_spec();
public:
/// Hasher.
struct hash;
base_spec(const class_decl_sptr& base, access_specifier a,
long offset_in_bits = -1, bool is_virtual = false);
base_spec(const type_base_sptr& base, access_specifier a,
long offset_in_bits = -1, bool is_virtual = false);
class_decl_sptr
get_base_class() const;
bool
get_is_virtual() const;
long
get_offset_in_bits() const;
virtual bool
operator==(const decl_base&) const;
virtual bool
operator==(const member_base&) const;
virtual size_t
get_hash() const;
virtual bool
traverse(ir_node_visitor&);
};// end class class_decl::base_spec
bool
operator==(const class_decl::base_spec_sptr& l,
const class_decl::base_spec_sptr& r);
bool
operator!=(const class_decl::base_spec_sptr& l,
const class_decl::base_spec_sptr& r);
class_decl::base_spec*
is_class_base_spec(type_or_decl_base*);
class_decl::base_spec_sptr
is_class_base_spec(type_or_decl_base_sptr);
typedef shared_ptr<union_decl> union_decl_sptr;
/// Abstracts a union type declaration.
class union_decl : public class_or_union
{
// Forbid
union_decl();
public:
union_decl(const environment* env, const string& name,
size_t size_in_bits, const location& locus,
visibility vis, member_types& mbrs,
data_members& data_mbrs, member_functions& member_fns);
union_decl(const environment* env, const string& name,
size_t size_in_bits, const location& locus,
visibility vis);
union_decl(const environment* env, const string& name,
bool is_declaration_only = true);
virtual string
get_pretty_representation(bool internal = false) const;
virtual bool
operator==(const decl_base&) const;
virtual bool
operator==(const type_base&) const;
virtual bool
operator==(const union_decl&) const;
virtual bool
traverse(ir_node_visitor& v);
virtual ~union_decl();
}; // union_decl
bool
equals(const union_decl&, const union_decl&, change_kind*);
method_decl_sptr
copy_member_function(const union_decl_sptr& union_type,
const method_decl_sptr& f);
method_decl_sptr
copy_member_function(const union_decl_sptr& union_type,
const method_decl* f);
class mem_fn_context_rel;
/// A convenience typedef for a shared pointer to @ref
/// mem_fn_context_rel.
typedef shared_ptr<mem_fn_context_rel> mem_fn_context_rel_sptr;
/// Abstraction of a member function context relationship. This
/// relates a member function to its parent class.
class mem_fn_context_rel : public context_rel
{
protected:
bool is_virtual_;
size_t vtable_offset_in_bits_;
bool is_constructor_;
bool is_destructor_;
bool is_const_;
public:
mem_fn_context_rel()
: context_rel(),
is_virtual_(false),
vtable_offset_in_bits_(0),
is_constructor_(false),
is_destructor_(false),
is_const_(false)
{}
mem_fn_context_rel(scope_decl* s)
: context_rel(s),
is_virtual_(false),
vtable_offset_in_bits_(0),
is_constructor_(false),
is_destructor_(false),
is_const_(false)
{}
mem_fn_context_rel(scope_decl* s,
bool is_constructor,
bool is_destructor,
bool is_const,
bool is_virtual,
size_t vtable_offset_in_bits,
access_specifier access,
bool is_static)
: context_rel(s, access, is_static),
is_virtual_(is_virtual),
vtable_offset_in_bits_(vtable_offset_in_bits),
is_constructor_(is_constructor),
is_destructor_(is_destructor),
is_const_(is_const)
{}
bool
is_virtual() const
{return is_virtual_;}
void
is_virtual(bool is_virtual)
{is_virtual_ = is_virtual;}
/// Getter for the vtable offset property.
///
/// This is the vtable offset of the member function of this
/// relation.
///
/// @return the vtable offset property of the relation.
size_t
vtable_offset() const
{return vtable_offset_in_bits_;}
/// Setter for the vtable offset property.
///
/// This is the vtable offset of the member function of this
/// relation.
///
/// @partam s the new vtable offset.
void
vtable_offset(size_t s)
{vtable_offset_in_bits_ = s;}
/// Getter for the 'is-constructor' property.
///
/// This tells if the member function of this relation is a
/// constructor.
///
/// @return the is-constructor property of the relation.
bool
is_constructor() const
{return is_constructor_;}
/// Setter for the 'is-constructor' property.
///
/// @param f the new value of the the property. Is true if this is
/// for a constructor, false otherwise.
void
is_constructor(bool f)
{is_constructor_ = f;}
/// Getter for the 'is-destructor' property.
///
/// Tells if the member function of this relation is a destructor.
///
/// @return the is-destructor property of the relation;
bool
is_destructor() const
{return is_destructor_;}
/// Setter for the 'is-destructor' property.
///
/// @param f the new value of the property. Is true if this is for
/// a destructor, false otherwise.
void
is_destructor(bool f)
{is_destructor_ = f;}
/// Getter for the 'is-const' property.
///
/// Tells if the member function of this relation is a const member
/// function.
///
/// @return the 'is-const' property of the relation.
bool
is_const() const
{return is_const_;}
/// Setter for the 'is-const' property.
///
/// @param f the new value of the property. Is true if this is for
/// a const entity, false otherwise.
void
is_const(bool f)
{is_const_ = f;}
virtual ~mem_fn_context_rel();
}; // end class mem_fn_context_rel
method_decl*
is_method_decl(const type_or_decl_base*);
method_decl*
is_method_decl(const type_or_decl_base&);
method_decl_sptr
is_method_decl(const type_or_decl_base_sptr&);
/// Abstract a member function template.
class member_function_template : public member_base, public virtual decl_base
{
bool is_constructor_;
bool is_const_;
shared_ptr<function_tdecl> fn_tmpl_;
// Forbiden
member_function_template();
public:
/// Hasher.
struct hash;
member_function_template(function_tdecl_sptr f,
access_specifier access, bool is_static,
bool is_constructor, bool is_const)
: 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)
{}
bool
is_constructor() const
{return is_constructor_;}
bool
is_const() const
{return is_const_;}
operator const function_tdecl& () const
{return *fn_tmpl_;}
function_tdecl_sptr
as_function_tdecl() const
{return fn_tmpl_;}
virtual bool
operator==(const member_base& o) const;
virtual bool
traverse(ir_node_visitor&);
};// end class member_function_template
bool
operator==(const member_function_template_sptr& l,
const member_function_template_sptr& r);
bool
operator!=(const member_function_template_sptr& l,
const member_function_template_sptr& r);
/// Abstracts a member class template template
class member_class_template
: public member_base,
public virtual decl_base
{
shared_ptr<class_tdecl> class_tmpl_;
// Forbidden
member_class_template();
public:
/// Hasher.
struct hash;
member_class_template(class_tdecl_sptr c,
access_specifier access, bool is_static)
: type_or_decl_base(c->get_environment()),
decl_base(c->get_environment(), c->get_name(), location()),
member_base(access, is_static),
class_tmpl_(c)
{}
operator const class_tdecl& () const
{ return *class_tmpl_; }
class_tdecl_sptr
as_class_tdecl() const
{return class_tmpl_;}
virtual bool
operator==(const member_base& o) const;
virtual bool
operator==(const member_class_template&) const;
virtual bool
traverse(ir_node_visitor& v);
};// end class member_class_template
bool
operator==(const member_class_template_sptr& l,
const member_class_template_sptr& r);
bool
operator!=(const member_class_template_sptr& l,
const member_class_template_sptr& r);
// Forward declarations for select nested hashers.
struct type_base::shared_ptr_hash
{
size_t
operator()(const shared_ptr<type_base> t) const;
};
struct type_base::dynamic_hash
{
size_t
operator()(const type_base* t) const;
};
/// A hashing functor for instances and pointers of @ref var_decl.
struct var_decl::hash
{
size_t
operator()(const var_decl& t) const;
size_t
operator()(const var_decl* t) const;
}; //end struct var_decl::hash
/// A comparison functor for pointers to @ref var_decl.
struct var_decl::ptr_equal
{
/// Return true if the two instances of @ref var_decl are equal.
///
/// @param l the first variable to compare.
///
/// @param r the second variable to compare.
///
/// @return true if @p l equals @p r.
bool
operator()(const var_decl* l, const var_decl* r) const
{
if (l == r)
return true;
if (!!l != !!r)
return false;
return (*l == *r);
}
};// end struct var_decl::ptr_equal
/// A hashing functor fo instances and pointers of @ref function_decl.
struct function_decl::hash
{
size_t
operator()(const function_decl& t) const;
size_t
operator()(const function_decl* t) const;
};//end struct function_decl::hash
/// Equality functor for instances of @ref function_decl
struct function_decl::ptr_equal
{
/// Tests if two pointers to @ref function_decl are equal.
///
/// @param l the first pointer to @ref function_decl to consider in
/// the comparison.
///
/// @param r the second pointer to @ref function_decl to consider in
/// the comparison.
///
/// @return true if the two functions @p l and @p r are equal, false
/// otherwise.
bool
operator()(const function_decl* l, const function_decl* r) const
{
if (l == r)
return true;
if (!!l != !!r)
return false;
return (*l == *r);
}
};// function_decl::ptr_equal
/// The hashing functor for class_decl::base_spec.
struct class_decl::base_spec::hash
{
size_t
operator()(const base_spec& t) const;
};
/// The hashing functor for member_base.
struct member_base::hash
{
size_t
operator()(const member_base& m) const;
};
/// The hashing functor for member_function_template.
struct member_function_template::hash
{
size_t
operator()(const member_function_template& t) const;
};
/// The hashing functor for member_class_template
struct member_class_template::hash
{
size_t
operator()(const member_class_template& t) const;
};
struct function_tdecl::hash
{
size_t
operator()(const function_tdecl& t) const;
};
struct function_tdecl::shared_ptr_hash
{
size_t
operator()(const shared_ptr<function_tdecl> f) const;
};
struct class_tdecl::hash
{
size_t
operator()(const class_tdecl& t) const;
};
struct class_tdecl::shared_ptr_hash
{
size_t
operator()(const shared_ptr<class_tdecl> t) const;
};
/// The base class for the visitor type hierarchy used for traversing
/// a translation unit.
///
/// Client code willing to get notified for a certain kind of node
/// during the IR traversal might want to define a visitor class that
/// inherit ir_node_visitor, overload the ir_node_visitor::visit_begin()
/// or ir_node_visitor::visit_end() method of its choice, and provide
/// and implementation for it. If either
/// ir_node_visitor::visit_begin() or ir_node_visitor::visit_end()
/// return false, it means the traversal has to stop immediately after
/// the methods' return. If the methods return true, it means the
/// traversal keeps going.
///
/// That new visitor class would then be passed to e.g,
/// translation_unit::traverse or to the traverse method of any type
/// where the traversal is supposed to start from.
struct ir_node_visitor : public node_visitor_base
{
virtual bool visit_begin(decl_base*);
virtual bool visit_end(decl_base*);
virtual bool visit_begin(scope_decl*);
virtual bool visit_end(scope_decl*);
virtual bool visit_begin(type_base*);
virtual bool visit_end(type_base*);
virtual bool visit_begin(scope_type_decl*);
virtual bool visit_end(scope_type_decl*);
virtual bool visit_begin(type_decl*);
virtual bool visit_end(type_decl*);
virtual bool visit_begin(namespace_decl*);
virtual bool visit_end(namespace_decl*);
virtual bool visit_begin(qualified_type_def*);
virtual bool visit_end(qualified_type_def*);
virtual bool visit_begin(pointer_type_def*);
virtual bool visit_end(pointer_type_def*);
virtual bool visit_begin(reference_type_def*);
virtual bool visit_end(reference_type_def*);
virtual bool visit_begin(array_type_def*);
virtual bool visit_end(array_type_def*);
virtual bool visit_begin(enum_type_decl*);
virtual bool visit_end(enum_type_decl*);
virtual bool visit_begin(typedef_decl*);
virtual bool visit_end(typedef_decl*);
virtual bool visit_begin(function_type*);
virtual bool visit_end(function_type*);
virtual bool visit_begin(var_decl*);
virtual bool visit_end(var_decl*);
virtual bool visit_begin(function_decl*);
virtual bool visit_end(function_decl*);
virtual bool visit_begin(function_decl::parameter*);
virtual bool visit_end(function_decl::parameter*);
virtual bool visit_begin(function_tdecl*);
virtual bool visit_end(function_tdecl*);
virtual bool visit_begin(class_tdecl*);
virtual bool visit_end(class_tdecl*);
virtual bool visit_begin(class_or_union *);
virtual bool visit_end(class_or_union *);
virtual bool visit_begin(class_decl*);
virtual bool visit_end(class_decl*);
virtual bool visit_begin(union_decl*);
virtual bool visit_end(union_decl*);
virtual bool visit_begin(class_decl::base_spec*);
virtual bool visit_end(class_decl::base_spec*);
virtual bool visit_begin(member_function_template*);
virtual bool visit_end(member_function_template*);
virtual bool visit_begin(member_class_template*);
virtual bool visit_end(member_class_template*);
}; // end struct ir_node_visitor
// Debugging facility
void
fns_to_str(vector<function_decl*>::const_iterator a_begin,
vector<function_decl*>::const_iterator a_end,
vector<function_decl*>::const_iterator b_begin,
vector<function_decl*>::const_iterator b_end,
std::ostream& o);
}// end namespace ir
} // end namespace abigail
#endif // __ABG_IR_H__