// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// -*- Mode: C++ -*-
//
// Copyright (C) 2013-2020 Red Hat, Inc.
//
// 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 <functional>
#include <set>
#include <unordered_map>
#include "abg-cxx-compat.h"
#include "abg-fwd.h"
#include "abg-hash.h"
#include "abg-traverse.h"
#include "abg-config.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::shared_ptr and std::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 types in here.
using std::unordered_map;

/// A convenience typedef for an unordered set of pointer values
typedef unordered_set<uintptr_t> pointer_set;

/// Functor to hash a canonical type by using its pointer value.
struct canonical_type_hash
{
  size_t operator()(const type_base_sptr& l) const;
  size_t operator()(const type_base *l) const;
}; //end struct canonical_type_hash

/// Helper typedef for an unordered set of type_base_sptr which uses
/// pointer value to tell its members appart, because the members are
/// canonical types.
typedef unordered_set<type_base_sptr,
		      canonical_type_hash> canonical_type_sptr_set_type;

/// Helper typedef for a vector of pointer to type_base.
typedef vector<type_base*> type_base_ptrs_type;

/// Helper typedef for a vector of shared pointer to a type_base.
typedef vector<type_base_sptr> type_base_sptrs_type;

/// 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:
  struct priv;
  std::unique_ptr<priv> priv_;

  /// 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::unordered_map<string, std::vector<type_base_sptr> >
      canonical_types_map_type;

  environment();

  virtual ~environment();

  canonical_types_map_type&
  get_canonical_types_map();

  const canonical_types_map_type&
  get_canonical_types_map() const;

  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
  do_on_the_fly_canonicalization() const;

  void
  do_on_the_fly_canonicalization(bool f);

  bool
  decl_only_class_equals_definition() const;

  void
  decl_only_class_equals_definition(bool f) const;

  bool
  is_void_type(const type_base_sptr&) const;

  bool
  is_void_type(const type_base*) 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;

  const config&
  get_config() const;

#ifdef WITH_DEBUG_SELF_COMPARISON
  void
  set_self_comparison_debug_input(const corpus_sptr& corpus);

  void
  get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
				   corpus_sptr& second_corpus);

  void
  self_comparison_debug_is_on(bool);

  bool
  self_comparison_debug_is_on() const;
#endif

#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
  void
  debug_type_canonicalization_is_on(bool flag);

  bool
  debug_type_canonicalization_is_on() const;
#endif

  vector<type_base_sptr>* get_canonical_types(const char* name);

  type_base* get_canonical_type(const char* name, unsigned index);

#ifdef WITH_DEBUG_SELF_COMPARISON
  unordered_map<string, uintptr_t>&
  get_type_id_canonical_type_map() const;

  unordered_map<uintptr_t, string>&
  get_pointer_type_id_map();

  string
  get_type_id_from_pointer(uintptr_t ptr);

  uintptr_t
  get_canonical_type_from_type_id(const char*);
#endif

  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_;
  // Whether the location is artificial.  Being artificial means that
  // the location wasn't generated by the original emitter of the
  // metadata (i.e, the compiler if the metadata is debug info).  For
  // instance, implicit location derived from the position of XML
  // elements in the abixml file is represented as artificial
  // locations.
  bool			is_artificial_;

  location(unsigned v, location_manager* m)
    : value_(v), loc_manager_(m), is_artificial_(false)
  {}

  /// 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:

  /// Test if the location is artificial.
  ///
  /// Being artificial means that the location wasn't generated by the
  /// original emitter of the metadata (i.e, the compiler if the
  /// metadata is debug info).  For instance, the implicit location
  /// derived from the position of a given XML element in the abixml
  /// file is represented as artificial locations.  The same XML
  /// element might carry a non-artificial (natural?) location that was
  /// originally emitted by the compiler that generated the original
  /// debug info the abixml file is derived from.
  ///
  /// @return true iff the location is artificial.
  bool
  get_is_artificial() const
  {return is_artificial_;}

  /// Set the artificial-ness of the location.
  ///
  /// Being artificial means that the location wasn't generated by the
  /// original emitter of the metadata (i.e, the compiler if the
  /// metadata is debug info).  For instance, the implicit location
  /// derived from the position of a given XML element in the abixml
  /// file is represented as artificial locations.  The same XML
  /// element might carry a non-artificial (natural?) location that
  /// was originally emitted by the compiler that generated the
  /// original debug info the abixml file is derived from.
  ///
  /// @param f the new artificial-ness state.
  void
  set_is_artificial(bool f)
  {is_artificial_ = f;}

  /// Copy constructor of the location.
  ///
  /// @param l the location to copy from.
  location(const location& l)
    : value_(l.value_),
      loc_manager_(l.loc_manager_),
      is_artificial_(l.is_artificial_)
  {}

  /// Assignment operator of the location.
  ///
  /// @param l the location to assign to the current one.
  location&
  operator=(const location& l)
  {
    value_ = l.value_;
    loc_manager_ = l.loc_manager_;
    is_artificial_ = l.is_artificial_;
    return *this;
  }

  /// Default constructor for the @ref location type.
  location()
    : value_(), loc_manager_(), is_artificial_()
  {}

  /// 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;

  string
  expand(void) 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;
  std::unique_ptr<priv> priv_;

public:

  location_manager();

  ~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;
};

/// 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

/// The hashing functor for using instances of @ref type_or_decl_base
/// as values in a hash map or set.
struct type_or_decl_hash
{

  /// Function-call Operator to hash the string representation of an
  /// ABI artifact.
  ///
  /// @param artifact the ABI artifact to hash.
  ///
  /// @return the hash value of the string representation of @p
  /// artifact.
  size_t
  operator()(const type_or_decl_base *artifact) const
  {
    string repr =  get_pretty_representation(artifact);
    std::hash<string> do_hash;
    return do_hash(repr);
  }

  /// Function-call Operator to hash the string representation of an
  /// ABI artifact.
  ///
  /// @param artifact the ABI artifact to hash.
  ///
  /// @return the hash value of the string representation of @p
  /// artifact.
  size_t
  operator()(const type_or_decl_base_sptr& artifact) const
  {return operator()(artifact.get());}
}; // end struct type_or_decl_hash

/// The comparison functor for using instances of @ref
/// type_or_decl_base as values in a hash map or set.
struct type_or_decl_equal
{

  /// The function-call operator to compare the string representations
  /// of two ABI artifacts.
  ///
  /// @param l the left hand side ABI artifact operand of the
  /// comparison.
  ///
  /// @param r the right hand side ABI artifact operand of the
  /// comparison.
  ///
  /// @return true iff the string representation of @p l equals the one
  /// of @p r.
  bool
  operator()(const type_or_decl_base *l, const type_or_decl_base *r) const
  {
    string repr1 = get_pretty_representation(l);
    string repr2 = get_pretty_representation(r);

    return repr1 == repr2;
  }

  /// The function-call operator to compare the string representations
  /// of two ABI artifacts.
  ///
  /// @param l the left hand side ABI artifact operand of the
  /// comparison.
  ///
  /// @param r the right hand side ABI artifact operand of the
  /// comparison.
  ///
  /// @return true iff the string representation of @p l equals the one
  /// of @p r.
  bool
  operator()(const type_or_decl_base_sptr &l,
	     const type_or_decl_base_sptr &r) const
  {return operator()(l.get(), r.get());}
}; // end type_or_decl_equal

/// A convenience typedef for a hash set of type_or_decl_base_sptr
typedef unordered_set<type_or_decl_base_sptr,
		      type_or_decl_hash,
		      type_or_decl_equal> artifact_sptr_set_type;

/// A convenience typedef for a hash set of const type_or_decl_base*
typedef unordered_set<const type_or_decl_base*,
		      type_or_decl_hash,
		      type_or_decl_equal> artifact_ptr_set_type;

/// 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;

/// A convenience typedef for a map which key is an @ref
/// interned_string and which value is a @ref type_base_wptr.
typedef unordered_map<interned_string, type_base_wptr, hash_interned_string>
istring_type_base_wptr_map_type;

/// A convenience typedef for a map which key is an @ref
/// interned_string and which value is a @ref type_base_wptr.
typedef unordered_map<interned_string,
		      type_or_decl_base_sptr,
		      hash_interned_string>
istring_type_or_decl_base_sptr_map_type;

/// This is a type that aggregates maps of all the kinds of types that
/// are supported by libabigail.
///
/// For instance, the type_maps contains a map of string to basic
/// type, a map of string to class type, a map of string to union
/// types, etc.  The key of a map entry is the pretty representation
/// of the type, and the value of the map entry is the type.
class type_maps
{
  struct priv;
  std::unique_ptr<priv> priv_;

public:

  type_maps();

  ~type_maps();

  bool
  empty() const;

  const istring_type_base_wptrs_map_type&
  basic_types() const;

  istring_type_base_wptrs_map_type&
  basic_types();

  const istring_type_base_wptrs_map_type&
  class_types() const;

  istring_type_base_wptrs_map_type&
  class_types();

  istring_type_base_wptrs_map_type&
  union_types();

  const istring_type_base_wptrs_map_type&
  union_types() const;

  istring_type_base_wptrs_map_type&
  enum_types();

  const istring_type_base_wptrs_map_type&
  enum_types() const;

  istring_type_base_wptrs_map_type&
  typedef_types();

  const istring_type_base_wptrs_map_type&
  typedef_types() const;

  istring_type_base_wptrs_map_type&
  qualified_types();

  const istring_type_base_wptrs_map_type&
  qualified_types() const;

  istring_type_base_wptrs_map_type&
  pointer_types();

  const istring_type_base_wptrs_map_type&
  pointer_types() const;

  istring_type_base_wptrs_map_type&
  reference_types();

  const istring_type_base_wptrs_map_type&
  reference_types() const;

  istring_type_base_wptrs_map_type&
  array_types();

  const istring_type_base_wptrs_map_type&
  array_types() const;

  const istring_type_base_wptrs_map_type&
  subrange_types() const;

  istring_type_base_wptrs_map_type&
  subrange_types();

  istring_type_base_wptrs_map_type&
  function_types();

  const istring_type_base_wptrs_map_type&
  function_types() const;

  const vector<type_base_wptr>&
  get_types_sorted_by_name() const;
}; // end class type_maps;

/// 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;
  std::unique_ptr<priv> priv_;

  // Forbidden
  translation_unit() = delete;

public:
  /// Convenience typedef for a shared pointer on a @ref global_scope.
  typedef shared_ptr<scope_decl> 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_03,
    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_PLI,
    LANG_UPC,
    LANG_D,
    LANG_Python,
    LANG_Go,
    LANG_Rust,
    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&);

  const std::string&
  get_compilation_dir_path() const;

  void
  set_compilation_dir_path(const std::string&);

  const std::string&
  get_absolute_path() const;

  void
  set_corpus(corpus*);

  const corpus*
  get_corpus() const;

  corpus*
  get_corpus();

  const scope_decl_sptr&
  get_global_scope() const;

  scope_decl_sptr&
  get_global_scope();

  const type_maps&
  get_types() const;

  type_maps&
  get_types();

  const vector<function_type_sptr>&
  get_live_fn_types() const;

  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

/// A comparison functor to compare translation units based on their
/// absolute paths.
struct shared_translation_unit_comp
{
  /// Compare two translations units based on their absolute paths.
  ///
  /// @param lhs the first translation unit to consider for the
  /// comparison.
  ///
  /// @param rhs the second translatin unit to consider for the
  /// comparison.
  bool
  operator()(const translation_unit_sptr& lhs,
	     const translation_unit_sptr& rhs) const
  {return lhs->get_absolute_path() < rhs->get_absolute_path();}
}; // end struct shared_translation_unit_comp

/// Convenience typedef for an ordered set of @ref
/// translation_unit_sptr.
typedef std::set<translation_unit_sptr,
		 shared_translation_unit_comp> translation_units;

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
is_java_language(translation_unit::language l);

bool
is_ada_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::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::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
  };

  /// The visibility of the symbol.
  enum visibility
  {
    DEFAULT_VISIBILITY,
    PROTECTED_VISIBILITY,
    HIDDEN_VISIBILITY,
    INTERNAL_VISIBILITY,
  };

  /// Inject the elf_symbol::version here.
  class version;

private:
  struct priv;
  std::unique_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&	ve,
	     visibility		vi,
	     bool		is_in_ksymtab = false,
	     const abg_compat::optional<uint64_t>&	crc = {},
	     const abg_compat::optional<std::string>&	ns = {},
	     bool		is_suppressed = false);

  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&	    ve,
	 visibility	    vi,
	 bool		    is_in_ksymtab = false,
	 const abg_compat::optional<uint64_t>&		crc = {},
	 const abg_compat::optional<std::string>&	ns = {},
	 bool		    is_suppressed = false);

  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);

  void
  set_visibility(visibility v);

  visibility
  get_visibility() const;

  bool
  is_defined() const;

  void
  is_defined(bool d);

  bool
  is_public() const;

  bool
  is_function() const;

  bool
  is_variable() const;

  bool
  is_in_ksymtab() const;

  void
  set_is_in_ksymtab(bool is_in_ksymtab);

  const abg_compat::optional<uint64_t>&
  get_crc() const;

  void
  set_crc(const abg_compat::optional<uint64_t>& crc);

  const abg_compat::optional<std::string>&
  get_namespace() const;

  void
  set_namespace(const abg_compat::optional<std::string>& ns);

  bool
  is_suppressed() const;

  void
  set_is_suppressed(bool is_suppressed);

  const elf_symbol_sptr
  get_main_symbol() const;

  elf_symbol_sptr
  get_main_symbol();

  bool
  is_main_symbol() const;

  elf_symbol_sptr
  update_main_symbol(const std::string&);

  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);

std::ostream&
operator<<(std::ostream& o, elf_symbol::visibility t);

bool
string_to_elf_symbol_type(const string&, elf_symbol::type&);

bool
string_to_elf_symbol_binding(const string&, elf_symbol::binding&);

bool
string_to_elf_symbol_visibility(const string&, elf_symbol::visibility&);

bool
elf_symbol_is_function(elf_symbol::type);

bool
elf_symbol_is_variable(elf_symbol::type);

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;
  std::unique_ptr<priv> priv_;

public:
  version();

  version(const string& v,
	  bool is_default);

  version(const version& v);

  ~version();

  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

/// 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 a local type change.
  LOCAL_TYPE_CHANGE_KIND = 1 << 0,

  /// This means that a given IR artifact has a local non-type change.
  /// That is a change that is carried by the artifact itself, not by
  /// its type.
  LOCAL_NON_TYPE_CHANGE_KIND = 1 << 1,

  /// Testing (anding) against this mask 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 (or its type), rather than by one off its sub-types.
  ALL_LOCAL_CHANGES_MASK = LOCAL_TYPE_CHANGE_KIND | LOCAL_NON_TYPE_CHANGE_KIND,

  /// 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 << 2,
};// end enum change_kind

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
maybe_compare_as_member_decls(const decl_base& l,
			      const decl_base& r,
			      change_kind* k);

bool
equals(const decl_base&, const decl_base&, change_kind*);

/// The base class of both types and declarations.
class type_or_decl_base : public ir_traversable_base
{
  struct priv;
  mutable std::unique_ptr<priv> priv_;

  type_or_decl_base();

protected:

  /// This is a bitmap type which instance is meant to contain the
  /// runtime type of a given ABI artifact.  Bits of the identifiers
  /// of the type of a given artifact as well as the types it inherits
  /// from are to be set to 1.
  enum type_or_decl_kind
  {
    ABSTRACT_TYPE_OR_DECL,
    ABSTRACT_DECL_BASE = 1,
    ABSTRACT_SCOPE_DECL = 1 << 1,
    GLOBAL_SCOPE_DECL = 1 << 2,
    NAMESPACE_DECL = 1 << 3,
    VAR_DECL = 1 << 4,
    FUNCTION_DECL = 1 << 5,
    FUNCTION_PARAMETER_DECL = 1 << 6,
    METHOD_DECL = 1 << 7,
    TEMPLATE_DECL = 1 << 8,
    ABSTRACT_TYPE_BASE = 1 << 9,
    ABSTRACT_SCOPE_TYPE_DECL = 1 << 10,
    BASIC_TYPE = 1 << 11,
    QUALIFIED_TYPE = 1 << 12,
    POINTER_TYPE = 1 << 13,
    REFERENCE_TYPE = 1 << 14,
    ARRAY_TYPE = 1 << 15,
    ENUM_TYPE = 1 << 16,
    TYPEDEF_TYPE = 1 << 17,
    CLASS_TYPE = 1 << 18,
    UNION_TYPE = 1 << 19,
    FUNCTION_TYPE = 1 << 20,
    METHOD_TYPE = 1 << 21,
  }; // end enum type_or_decl_kind

  enum type_or_decl_kind
  kind() const;

  void
  kind(enum type_or_decl_kind);

  const void*
  runtime_type_instance() const;

  void*
  runtime_type_instance();

  void
  runtime_type_instance(void*);

  const void*
  type_or_decl_base_pointer() const;

  void*
  type_or_decl_base_pointer();

  bool hashing_started() const;

  void hashing_started(bool) const;

public:

  type_or_decl_base(const environment*,
		    enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL);

  type_or_decl_base(const type_or_decl_base&);

  virtual ~type_or_decl_base();

  bool
  get_is_artificial() const;

  void
  set_is_artificial(bool);

  const environment*
  get_environment() const;

  environment*
  get_environment();

  void
  set_environment(const environment*);

  void
  set_artificial_location(const location &);

  location&
  get_artificial_location() const;

  bool
  has_artificial_location() const;

  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,
			    bool qualified_name = true) const = 0;

  friend type_or_decl_base::type_or_decl_kind
  operator|(type_or_decl_base::type_or_decl_kind,
	    type_or_decl_base::type_or_decl_kind);

  friend type_or_decl_base::type_or_decl_kind&
  operator|=(type_or_decl_base::type_or_decl_kind&,
	     type_or_decl_base::type_or_decl_kind);

  friend type_or_decl_base::type_or_decl_kind
  operator&(type_or_decl_base::type_or_decl_kind,
	    type_or_decl_base::type_or_decl_kind);

  friend type_or_decl_base::type_or_decl_kind&
  operator&=(type_or_decl_base::type_or_decl_kind&,
	     type_or_decl_base::type_or_decl_kind);

  friend class_decl*
  is_class_type(const type_or_decl_base*);

  friend pointer_type_def*
  is_pointer_type(type_or_decl_base*);

  friend type_base*
  is_type(const type_or_decl_base*);

  friend decl_base*
  is_decl(const type_or_decl_base* d);
}; // end class type_or_decl_base

type_or_decl_base::type_or_decl_kind
operator|(type_or_decl_base::type_or_decl_kind,
	  type_or_decl_base::type_or_decl_kind);

type_or_decl_base::type_or_decl_kind&
operator|=(type_or_decl_base::type_or_decl_kind&,
	   type_or_decl_base::type_or_decl_kind);

type_or_decl_base::type_or_decl_kind
operator&(type_or_decl_base::type_or_decl_kind,
	  type_or_decl_base::type_or_decl_kind);

type_or_decl_base::type_or_decl_kind&
operator&=(type_or_decl_base::type_or_decl_kind&,
	   type_or_decl_base::type_or_decl_kind);

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
  clear_qualified_name();

  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 *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,
			    bool qualified_name = true) 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 const interned_string&
  get_scoped_name() 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);

  bool
  get_has_anonymous_parent() const;

  bool
  get_is_anonymous_or_has_anonymous_parent() const;

  typedef_decl_sptr
  get_naming_typedef() const;

  void
  set_naming_typedef(const typedef_decl_sptr&);

  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);

  const decl_base_sptr
  get_earlier_declaration() const;

  void
  set_earlier_declaration(const decl_base_sptr&);

  const decl_base_sptr
  get_definition_of_declaration() const;

  void
  set_definition_of_declaration(const decl_base_sptr&);

  const decl_base*
  get_naked_definition_of_declaration() const;

  bool
  get_is_declaration_only() const;

  void
  set_is_declaration_only(bool f);

  friend type_base_sptr
  canonicalize(type_base_sptr);

  friend bool
  equals(const decl_base&, const decl_base&, change_kind*);

  friend bool
  equals(const var_decl&, const var_decl&, change_kind*);

  friend bool
  maybe_compare_as_member_decls(const decl_base& l,
				const decl_base& r,
				change_kind* k);

  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_or_union;
  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 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*);

/// A declaration that introduces a scope.
class scope_decl : public virtual decl_base
{
  struct priv;
  std::unique_ptr<priv> priv_;

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;

  scope_decl();

protected:
  virtual decl_base_sptr
  add_member_decl(const decl_base_sptr& member);

  virtual decl_base_sptr
  insert_member_decl(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 canonical_type_sptr_set_type&
  get_canonical_types() const;

  canonical_type_sptr_set_type&
  get_canonical_types();

  const type_base_sptrs_type&
  get_sorted_canonical_types() const;

  const declarations&
  get_member_decls() const;

  declarations&
  get_member_decls();

  const declarations&
  get_sorted_member_decls() const;

  virtual size_t
  get_num_anonymous_member_classes() const;

  virtual size_t
  get_num_anonymous_member_unions() const;

  virtual size_t
  get_num_anonymous_member_enums() const;

  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);

  friend type_base_sptr
  canonicalize(type_base_sptr);
};//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;
};

/// 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);

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;

public:
  // 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);

protected:
  virtual void
  on_canonical_type_set();

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;

  const interned_string&
  get_cached_pretty_representation(bool internal = false) 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,
			    bool qualified_name = true) 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();
};

/// 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,
			    bool qualified_name = true) 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*);

/// The abstraction of a qualified type.
class qualified_type_def : public virtual type_base, public virtual decl_base
{
  class priv;
  std::unique_ptr<priv> priv_;

  // Forbidden.
  qualified_type_def();

protected:
  string build_name(bool, bool internal = false) const;
  virtual void on_canonical_type_set();

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);

  qualified_type_def(environment* env, 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;

  void
  set_underlying_type(const type_base_sptr&);

  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, qualified_type_def::CV);

qualified_type_def::CV
operator~(qualified_type_def::CV);

std::ostream&
operator<<(std::ostream&, qualified_type_def::CV);

string
get_string_representation_of_cv_quals(const qualified_type_def::CV);

interned_string
get_name_of_qualified_type(const type_base_sptr& underlying_type,
			   qualified_type_def::CV quals,
			   bool qualified = true, bool internal = false);

qualified_type_def_sptr
lookup_qualified_type(const type_base_sptr&,
		      qualified_type_def::CV,
		      const translation_unit&);
bool
equals(const pointer_type_def&, const pointer_type_def&, change_kind*);

/// The abstraction of a pointer type.
class pointer_type_def : public virtual type_base, public virtual decl_base
{
  struct priv;
  std::unique_ptr<priv> priv_;

  // Forbidden.
  pointer_type_def();

protected:
  virtual void on_canonical_type_set();

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);

  pointer_type_def(environment* env, size_t size_in_bits,
		   size_t alignment_in_bits, const location& locus);


  void
  set_pointed_to_type(const type_base_sptr&);

  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*);


/// 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();

protected:
  virtual void on_canonical_type_set();

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);

  reference_type_def(const environment* env, bool lvalue, size_t size_in_bits,
		     size_t alignment_in_bits, const location& locus);

  void
  set_pointed_to_type(type_base_sptr& pointed_to_type);

  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*);

/// The abstraction of an array type.
class array_type_def : public virtual type_base, public virtual decl_base
{
  struct priv;
  std::unique_ptr<priv> priv_;

  // Forbidden.
  array_type_def();

  void update_size();

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;

  /// Abstraction for an array range type, like in Ada, or just for an
  /// array dimension like in C or C++.
  class subrange_type : public virtual type_base,  public virtual decl_base
  {
    struct priv;
    std::unique_ptr<priv> priv_;

    // Forbidden.
    subrange_type();
  public:

    virtual ~subrange_type();
    /// This class is to hold the value of the bound of a subrange.
    /// The value can be either signed or unsigned, at least when it
    /// comes from DWARF.  The class keeps the sign information, but
    /// allows users to access the value as signed or unsigned as they
    /// see fit.
    class bound_value
    {
    public:
      enum signedness
      {
	UNSIGNED_SIGNEDNESS,
	SIGNED_SIGNEDNESS
      };

    private:
      signedness s_;

    public:
      union
      {
	uint64_t unsigned_;
	int64_t signed_;
      } v_;
      bound_value();
      bound_value(uint64_t);
      bound_value(int64_t);
      enum signedness get_signedness() const;
      void set_signedness(enum signedness s);
      int64_t get_signed_value() const;
      uint64_t get_unsigned_value();
      void set_unsigned(uint64_t v);
      void set_signed(int64_t v);
      bool operator==(const bound_value&) const;
    }; //end class bound_value

    /// Hasher for an instance of array::subrange
    struct hash;

    subrange_type(const environment*	env,
		  const string&	name,
		  bound_value		lower_bound,
		  bound_value		upper_bound,
		  const type_base_sptr& underlying_type,
		  const location&	loc,
		  translation_unit::language l = translation_unit::LANG_C11);

    subrange_type(const environment* env,
		  const string& name,
		  bound_value lower_bound,
		  bound_value upper_bound,
		  const location& loc,
		  translation_unit::language l = translation_unit::LANG_C11);

    subrange_type(const environment* env,
		  const string& name,
		  bound_value upper_bound,
		  const location& loc,
		  translation_unit::language l = translation_unit::LANG_C11);

    type_base_sptr
    get_underlying_type() const;

    void
    set_underlying_type(const type_base_sptr &);

    int64_t
    get_upper_bound() const;

    int64_t
    get_lower_bound() const;

    void
    set_upper_bound(int64_t ub);

    void
    set_lower_bound(int64_t lb);

    uint64_t
    get_length() const;

    bool
    is_infinite() const;

    void
    is_infinite(bool);

    translation_unit::language
    get_language() const;

    virtual bool
    operator==(const decl_base&) const;

    virtual bool
    operator==(const type_base&) const;

    bool
    operator==(const subrange_type& o) const;

    bool
    operator!=(const subrange_type& o) const;

    string
    as_string() const;

    static string
    vector_as_string(const vector<subrange_sptr>&);

    virtual string
    get_pretty_representation(bool internal = false,
			      bool qualified_name = true) const;

    virtual bool
    traverse(ir_node_visitor&);
  }; // end class subrange_type

  array_type_def(const type_base_sptr type,
		 const std::vector<subrange_sptr>& subs,
		 const location& locus);

  array_type_def(environment* env,
		 const std::vector<subrange_sptr>& subs,
		 const location& locus);

  translation_unit::language
  get_language() const;

  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;

  void
  set_element_type(const type_base_sptr& element_type);

  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,
			    bool qualified_name = true) 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

array_type_def::subrange_type*
is_subrange_type(const type_or_decl_base *type);

array_type_def::subrange_sptr
is_subrange_type(const type_or_decl_base_sptr &type);

bool
equals(const enum_type_decl&, const enum_type_decl&, change_kind*);

/// Abstracts a declaration for an enum type.
class enum_type_decl : public virtual type_base, public virtual decl_base
{
  class priv;
  std::unique_ptr<priv> priv_;

  // Forbidden
  enum_type_decl();

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;

  /// 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,
			    bool qualified_name = true) 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();

  friend bool
  enum_has_non_name_change(const enum_type_decl& l,
			   const enum_type_decl& r,
			   change_kind* k);
}; // 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);

bool
enum_has_non_name_change(const enum_type_decl& l,
			 const enum_type_decl& r,
			 change_kind* k);

/// The abstraction of an enumerator
class enum_type_decl::enumerator
{
  class priv;
  std::unique_ptr<priv> priv_;

public:

  enumerator();

  ~enumerator();

  enumerator(const environment* env, const string& name, int64_t value);

  enumerator(const enumerator&);

  enumerator&
  operator=(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*);

/// The abstraction of a typedef declaration.
class typedef_decl : public virtual type_base, public virtual decl_base
{
  struct priv;
  std::unique_ptr<priv> 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);

  typedef_decl(const string& name,
	       environment* env,
	       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,
			    bool qualified_name = true) const;

  type_base_sptr
  get_underlying_type() const;

  void
  set_underlying_type(const type_base_sptr&);

  virtual bool
  traverse(ir_node_visitor&);

  virtual ~typedef_decl();
};// end class typedef_decl

/// 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:
  struct priv;
  std::unique_ptr<priv> priv_;

public:
  dm_context_rel();

  dm_context_rel(scope_decl* s,
		 bool is_laid_out,
		 size_t offset_in_bits,
		 access_specifier a,
		 bool is_static);

  dm_context_rel(scope_decl* s);

  bool
  get_is_laid_out() const;

  void
  set_is_laid_out(bool f);

  size_t
  get_offset_in_bits() const;

  void
  set_offset_in_bits(size_t o);

  const var_decl*
  get_anonymous_data_member() const;

  void
  set_anonymous_data_member(var_decl *);

  bool
  operator==(const dm_context_rel& o) const;

  bool
  operator!=(const dm_context_rel& o) const;

  virtual ~dm_context_rel();
};// end class class_decl::dm_context_rel

bool
equals(const var_decl&, const var_decl&, change_kind*);

bool
equals_modulo_cv_qualifier(const array_type_def*, const array_type_def*);

/// Abstracts a variable declaration.
class var_decl : public virtual decl_base
{
  struct priv;
  std::unique_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 const interned_string&
  get_qualified_name(bool internal = false) const;

  virtual size_t
  get_hash() const;

  virtual string
  get_pretty_representation(bool internal = false,
			    bool qualified_name = true) const;

  string
  get_anon_dm_reliable_name(bool qualified = true) const;

  virtual bool
  traverse(ir_node_visitor& v);

  virtual ~var_decl();

  friend void
  set_data_member_offset(var_decl_sptr m, uint64_t o);

  friend uint64_t
  get_data_member_offset(const var_decl_sptr m);

  friend uint64_t
  get_data_member_offset(const var_decl& m);

  friend uint64_t
  get_absolute_data_member_offset(const var_decl& m);

  friend uint64_t
  get_absolute_data_member_offset(const var_decl_sptr& 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*);

/// 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;

  /// Abstraction for the parameter of a function.
  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;

  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,
			    bool qualified_name = true) const;

  string
  get_pretty_representation_of_declarator (bool internal = false) 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
operator==(const function_decl_sptr& l, const function_decl_sptr& r);

bool
operator!=(const function_decl_sptr& l, const function_decl_sptr& r);

bool
function_decls_alias(const function_decl& f1, const function_decl& f2);

bool
equals(const function_decl::parameter&,
       const function_decl::parameter&,
       change_kind*);

/// A comparison functor to compare pointer to instances of @ref
/// type_or_decl_base.
struct type_or_decl_base_comp
{
  /// Comparison operator for ABI artifacts.
  ///
  /// @param f the first ABI artifact to consider for the comparison.
  ///
  /// @param s the second  ABI artifact to consider for the comparison.
  ///
  /// @return true iff @p f is lexicographically less than than @p s.
  bool
  operator()(const type_or_decl_base *f,
	     const type_or_decl_base *s)
  {
    function_decl *f_fn = is_function_decl(f), *s_fn = is_function_decl(s);
    if (f_fn && s_fn)
      return function_decl_is_less_than(*f_fn, *s_fn);

    var_decl *f_var = is_var_decl(f), *s_var = is_var_decl(s);
    if (f_var && s_var)
      return get_name(f_var) < get_name(s_var);

    string l_repr = get_pretty_representation(f),
      r_repr = get_pretty_representation(s);

    return l_repr < r_repr;
  }

  /// Comparison operator for ABI artifacts.
  ///
  /// @param f the first ABI artifact to consider for the comparison.
  ///
  /// @param s the second  ABI artifact to consider for the comparison.
  ///
  /// @return true iff @p f is lexicographically less than than @p s.
  bool
  operator()(const type_or_decl_base_sptr& f,
	     const type_or_decl_base_sptr& s)
  {return operator()(f.get(), s.get());}
}; // end struct type_or_decl_base_comp

/// Abstraction of a function parameter.
class function_decl::parameter : public decl_base
{
  struct priv;
  std::unique_ptr<priv> 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);

  virtual ~parameter();

  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_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,
			    bool qualified_name = true) 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
{
protected:
  virtual void on_canonical_type_set();

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;

  struct priv;
  std::unique_ptr<priv> priv_;

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;

  parameters::const_iterator
  get_first_parm() const;

  const interned_string&
  get_cached_name(bool internal = false) const;

  virtual bool
  operator==(const type_base&) const;

  virtual string
  get_pretty_representation(bool internal = false,
			    bool qualified_name = true) 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

/// Abstracts the type of a class member function.
class method_type : public function_type
{
  struct priv;
  std::unique_ptr<priv> priv_;

  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,
	      bool is_const,
	      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,
	      bool is_const,
	      size_t size_in_bits,
	      size_t alignment_in_bits);

  method_type(class_or_union_sptr class_type,
	      bool is_const,
	      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;

  void
  set_class_type(const class_or_union_sptr& t);

  void set_is_const(bool);

  bool get_is_const() const;

  virtual ~method_type();

  virtual string
  get_pretty_representation(bool internal = false,
			    bool qualified_name = true) const;

  friend interned_string
  get_method_type_name(const method_type& fn_type, bool internal);
};// end class method_type.

/// The base class of templates.
class template_decl : public virtual decl_base
{
  class priv;
  std::unique_ptr<priv> 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

/// 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;
  std::unique_ptr<priv> 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

/// Abstracts a type template parameter.
class type_tparameter : public template_parameter, public virtual type_decl
{
  class priv;
  std::unique_ptr<priv> 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.

/// Abstracts non type template parameters.
class non_type_tparameter : public template_parameter, public virtual decl_base
{
  class priv;
  std::unique_ptr<priv> 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;

/// Abstracts a template template parameter.
class template_tparameter : public type_tparameter, public template_decl
{
  class priv;
  std::unique_ptr<priv> 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();
};

/// 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;
  std::unique_ptr<priv> 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

/// Abstract a function template declaration.
class function_tdecl : public template_decl, public scope_decl
{
  class priv;
  std::unique_ptr<priv> 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.

/// Abstract a class template.
class class_tdecl : public template_decl, public scope_decl
{
  class priv;
  std::unique_ptr<priv> 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

/// 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 bool
  member_function_has_vtable_offset(const function_decl&);

  friend ssize_t
  get_member_function_vtable_offset(const function_decl&);

  friend void
  set_member_function_vtable_offset(function_decl&, ssize_t);

  friend void
  set_member_function_vtable_offset(const function_decl_sptr&, ssize_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

bool
operator==(const method_decl_sptr& l, const method_decl_sptr& r);

bool
operator!=(const method_decl_sptr& l, const method_decl_sptr& r);

/// The base type of @ref class_decl and @ref union_decl
class class_or_union : public scope_type_decl
{
public:
  struct priv;
  priv *priv_;

private:
  // 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);

  void
  maybe_fixup_members_of_anon_data_member(var_decl_sptr& anon_dm);

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<ssize_t, member_functions> virtual_mem_fn_map_type;
  typedef unordered_map<string, method_decl*> string_mem_fn_ptr_map_type;
  typedef unordered_map<string, method_decl_sptr> string_mem_fn_sptr_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);

 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;

  virtual size_t
  get_num_anonymous_member_classes() const;

  virtual size_t
  get_num_anonymous_member_unions() const;

  virtual size_t
  get_num_anonymous_member_enums() 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 var_decl_sptr
  find_data_member(const var_decl_sptr&) const;

  const var_decl_sptr
  find_anonymous_data_member(const var_decl_sptr&) 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);

  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_member_functions() const;

  const method_decl*
  find_member_function(const string& mangled_name) const;

  method_decl*
  find_member_function(const string& mangled_name);

  method_decl_sptr
  find_member_function_sptr(const string& mangled_name);

  const method_decl*
  find_member_function_from_signature(const string& s) const;

  method_decl*
  find_member_function_from_signature(const string& s);

  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);

bool
operator==(const class_or_union_sptr& l, const class_or_union_sptr& r);

bool
operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r);

/// 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;

  /// @}

protected:
  virtual void
  on_canonical_type_set();

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, base_specs& bases,
	     member_types& mbrs, data_members& data_mbrs,
	     member_functions& member_fns, bool is_anonymous);

  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,
	     size_t size_in_bits, size_t align_in_bits,
	     bool is_struct, const location& locus,
	     visibility vis, bool is_anonymous);

  class_decl(const environment* env, const string& name, bool is_struct,
	     bool is_declaration_only = true);

  virtual string
  get_pretty_representation(bool internal = false,
			    bool qualified_name = true) 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;

  const member_functions&
  get_virtual_mem_fns() const;

  const virtual_mem_fn_map_type&
  get_virtual_mem_fns_map() 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;

  ssize_t
  get_biggest_vtable_offset() 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;
  friend class class_or_union;
};// 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;
  std::unique_ptr<priv> 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);

  virtual ~base_spec();

  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);

/// 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, member_types& mbrs,
	     data_members& data_mbrs, member_functions& member_fns,
	     bool is_anonymous);

  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,
	     size_t size_in_bits, const location& locus,
	     visibility vis, bool is_anonymous);

  union_decl(const environment* env, const string& name,
	     bool is_declaration_only = true);

  virtual string
  get_pretty_representation(bool internal = false,
			    bool qualified_name = true) 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);

bool
operator==(const union_decl_sptr& l, const union_decl_sptr& r);

bool
operator!=(const union_decl_sptr& l, const union_decl_sptr& r);

/// 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_;
  ssize_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_(-1),
      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_(-1),
      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&);

const var_decl*
lookup_data_member(const type_base* type,
		   const char* dm_name);

const function_decl::parameter*
get_function_parameter(const decl_base* fun,
		       unsigned parm_num);

/// 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.
class ir_node_visitor : public node_visitor_base
{
  struct priv;
  std::unique_ptr<priv> priv_;

public:

  ir_node_visitor();

  virtual ~ir_node_visitor();

  void allow_visiting_already_visited_type_node(bool);
  bool allow_visiting_already_visited_type_node() const;
  void mark_type_node_as_visited(type_base *);
  void forget_visited_type_nodes();
  bool type_node_has_been_visited(type_base*) const;

  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(array_type_def::subrange_type*);
  virtual bool visit_end(array_type_def::subrange_type*);

  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__
