// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// -*- mode: C++ -*-
//
// Copyright (C) 2013-2020 Red Hat, Inc.
//
//Author: Dodji Seketeli

/// @file
///
/// Definitions for the Internal Representation artifacts of libabigail.

#include <cxxabi.h>
#include <algorithm>
#include <cstdint>
#include <functional>
#include <iterator>
#include <memory>
#include <sstream>
#include <typeinfo>
#include <unordered_map>
#include <tuple>
#include <utility>
#include <vector>

#include "abg-internal.h"
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS

#include "abg-interned-str.h"
#include "abg-ir.h"
#include "abg-corpus.h"
#include "abg-corpus-priv.h"

ABG_END_EXPORT_DECLARATIONS
// </headers defining libabigail's API>

#include "abg-cxx-compat.h"  // for abg_compat::optional
#include "abg-tools-utils.h"
#include "abg-comp-filter.h"
#include "abg-ir-priv.h"

namespace
{
/// This internal type is a tree walker that walks the sub-tree of a
/// type and sets the environment of the type (including its sub-type)
/// to a new environment.
class environment_setter : public abigail::ir::ir_node_visitor
{
  const abigail::ir::environment* env_;

public:
  environment_setter(const abigail::ir::environment* env)
    : env_(env)
  {}

  /// This function is called on each sub-tree node that is a
  /// declaration.  Note that it's also called on some types because
  /// most types that have a declarations also inherit the type @ref
  /// decl_base.
  ///
  /// @param d the declaration being visited.
  bool
  visit_begin(abigail::ir::decl_base* d)
  {
    if (const abigail::ir::environment* env = d->get_environment())
      {
	ABG_ASSERT(env == env_);
	return false;
      }
    else
      d->set_environment(env_);

    return true;

  }

  /// This function is called on each sub-tree node that is a type.
  ///
  /// @param t the type being visited.
  bool
  visit_begin(abigail::ir::type_base* t)
  {
    if (abigail::ir::environment* env = t->get_environment())
      {
	ABG_ASSERT(env == env_);
	return false;
      }
    else
      {
	ABG_ASSERT(!t->get_environment());
	t->set_environment(env_);
      }
    return true;
  }
};

/// This internal type is a tree walking that is used to set the
/// qualified name of a tree of decls and types.  It used by the
/// function update_qualified_name().
class qualified_name_setter : public abigail::ir::ir_node_visitor
{

public:
  bool
  do_update(abigail::ir::decl_base* d);

  bool
  visit_begin(abigail::ir::decl_base* d);

  bool
  visit_begin(abigail::ir::type_base* d);
}; // end class qualified_name_setter

}// end anon namespace

namespace abigail
{

// Inject.
using std::string;
using std::list;
using std::vector;
using std::unordered_map;
using std::dynamic_pointer_cast;
using std::static_pointer_cast;

/// Convenience typedef for a map of string -> string*.
typedef unordered_map<string, string*> pool_map_type;

/// The type of the private data structure of type @ref
/// intered_string_pool.
struct interned_string_pool::priv
{
  pool_map_type map;
}; //end struc struct interned_string_pool::priv

/// Default constructor.
interned_string_pool::interned_string_pool()
  : priv_(new priv)
{
  priv_->map[""] = 0;
}

/// Test if the interned string pool already contains a string with a
/// given value.
///
/// @param s the string to test for.
///
/// @return true if the pool contains a string with the value @p s.
bool
interned_string_pool::has_string(const char* s) const
{return priv_->map.find(s) != priv_->map.end();}

/// Get a pointer to the interned string which has a given value.
///
/// @param s the value of the interned string to look for.
///
/// @return a pointer to the raw string of characters which has the
/// value of @p s.  Or null if no string with value @p s was interned.
const char*
interned_string_pool::get_string(const char* s) const
{
  unordered_map<string, string*>::const_iterator i =
    priv_->map.find(s);
  if (i == priv_->map.end())
    return 0;
  if (i->second)
    return i->second->c_str();
  return "";
}

/// Create an interned string with a given value.
///
/// @param str_value the value of the interned string to create.
///
/// @return the new created instance of @ref interned_string created.
interned_string
interned_string_pool::create_string(const std::string& str_value)
{
  string*& result = priv_->map[str_value];
  if (!result && !str_value.empty())
    result = new string(str_value);
  return interned_string(result);
}

/// Destructor.
interned_string_pool::~interned_string_pool()
{
  for (pool_map_type::iterator i = priv_->map.begin();
       i != priv_->map.end();
       ++i)
    if (i->second)
      delete i->second;
}

/// Equality operator.
///
/// @param l the instance of std::string on the left-hand-side of the
/// equality operator.
///
/// @param r the instance of @ref interned_string on the
/// right-hand-side of the equality operator.
///
/// @return true iff the two string are equal.
bool
operator==(const std::string& l, const interned_string& r)
{return r.operator==(l);}

bool
operator!=(const std::string& l, const interned_string& r)
{return !(l == r);}

/// Streaming operator.
///
/// Streams an instance of @ref interned_string to an output stream.
///
/// @param o the destination output stream.
///
/// @param s the instance of @ref interned_string to stream out.
///
/// @return the output stream this function just streamed to.
std::ostream&
operator<<(std::ostream& o, const interned_string& s)
{
  o << static_cast<std::string>(s);
  return o;
}

/// Concatenation operator.
///
/// Concatenate two instances of @ref interned_string, builds an
/// instance of std::string with the resulting string and return it.
///
/// @param s1 the first string to consider.
///
/// @param s2 the second string to consider.
///
/// @return the resuting concatenated string.
std::string
operator+(const interned_string& s1,const std::string& s2)
{return static_cast<std::string>(s1) + s2;}

/// Concatenation operator.
///
/// Concatenate two instances of @ref interned_string, builds an
/// instance of std::string with the resulting string and return it.
///
/// @param s1 the first string to consider.
///
/// @param s2 the second string to consider.
///
/// @return the resuting concatenated string.
std::string
operator+(const std::string& s1, const interned_string& s2)
{return s1 + static_cast<std::string>(s2);}

namespace ir
{

static size_t
hash_as_canonical_type_or_constant(const type_base *t);

static bool
has_generic_anonymous_internal_type_name(const decl_base *d);

static interned_string
get_generic_anonymous_internal_type_name(const decl_base *d);

static void
update_qualified_name(decl_base * d);

static void
update_qualified_name(decl_base_sptr d);

void
push_composite_type_comparison_operands(const type_base& left,
					const type_base& right);

void
pop_composite_type_comparison_operands(const type_base& left,
				       const type_base& right);

bool
mark_dependant_types_compared_until(const type_base &r);

/// Push a pair of operands on the stack of operands of the current
/// type comparison, during type canonicalization.
///
/// For more information on this, please look at the description of
/// the environment::priv::right_type_comp_operands_ data member.
///
/// @param left the left-hand-side comparison operand to push.
///
/// @param right the right-hand-side comparison operand to push.
void
push_composite_type_comparison_operands(const type_base& left,
					const type_base& right)
{
  const environment * env = left.get_environment();
  env->priv_->push_composite_type_comparison_operands(&left, &right);
}

/// Pop a pair of operands from the stack of operands to the current
/// type comparison.
///
/// For more information on this, please look at the description of
/// the environment::privright_type_comp_operands_ data member.
///
/// @param left the left-hand-side comparison operand we expect to
/// pop from the top of the stack.  If this doesn't match the
/// operand found on the top of the stack, the function aborts.
///
/// @param right the right-hand-side comparison operand we expect to
/// pop from the bottom of the stack. If this doesn't match the
/// operand found on the top of the stack, the function aborts.
void
pop_composite_type_comparison_operands(const type_base& left,
				       const type_base& right)
{
  const environment * env = left.get_environment();
  env->priv_->pop_composite_type_comparison_operands(&left, &right);
}

/// In the stack of the current types being compared (as part of type
/// canonicalization), mark all the types that comes after a certain
/// one as NOT being eligible to the canonical type propagation
/// optimization.
///
/// For a starter, please read about the @ref
/// OnTheFlyCanonicalization, aka, "canonical type propagation
/// optimization".
///
/// To implement that optimization, we need, among other things to
/// maintain stack of the types (and their sub-types) being
/// currently compared as part of type canonicalization.
///
/// Note that we only consider the type that is the right-hand-side
/// operand of the comparison because it's that one that is being
/// canonicalized and thus, that is not yet canonicalized.
///
/// The reason why a type is deemed NON-eligible to the canonical
/// type propagation optimization is that it "depends" on
/// recursively present type.  Let me explain.
///
/// Suppose we have a type T that has sub-types named ST0 and ST1.
/// Suppose ST1 itself has a sub-type that is T itself.  In this
/// case, we say that T is a recursive type, because it has T
/// (itself) as one of its sub-types:
///
///   T
///   +-- ST0
///   |
///   +-- ST1
///        +
///        |
///        +-- T
///
/// ST1 is said to "depend" on T because it has T as a sub-type.
/// But because T is recursive, then ST1 is said to depend on a
/// recursive type.  Notice however that ST0 does not depend on any
/// recursive type.
///
/// When we are at the point of comparing the sub-type T of ST1
/// against its counterpart, the stack of the right-hand-side
/// operands of the type canonicalization is going to look like
/// this:
///
///    | T | ST1 |
///
/// We don't add the type T to the stack as we detect that T was
/// already in there (recursive cycle).
///
/// So, this function will basically mark ST1 as being NON-eligible
/// to being the target of canonical type propagation, by marking ST1
/// as being dependant on T.
///
/// @param right the right-hand-side operand of the type comparison.
///
/// @return true iff the operation was successful.
bool
mark_dependant_types_compared_until(const type_base &r)
{
  const environment * env = r.get_environment();
  return env->priv_->mark_dependant_types_compared_until(&r);
}

/// @brief the location of a token represented in its simplest form.
/// Instances of this type are to be stored in a sorted vector, so the
/// type must have proper relational operators.
class expanded_location
{
  string	path_;
  unsigned	line_;
  unsigned	column_;

  expanded_location();

public:

  friend class location_manager;

  expanded_location(const string& path, unsigned line, unsigned column)
  : path_(path), line_(line), column_(column)
  {}

  bool
  operator==(const expanded_location& l) const
  {
    return (path_ == l.path_
	    && line_ == l.line_
	    && column_ && l.column_);
  }

  bool
  operator<(const expanded_location& l) const
  {
    if (path_ < l.path_)
      return true;
    else if (path_ > l.path_)
      return false;

    if (line_ < l.line_)
      return true;
    else if (line_ > l.line_)
      return false;

    return column_ < l.column_;
  }
};

/// Expand the location into a tripplet path, line and column number.
///
/// @param path the output parameter where this function sets the
/// expanded path.
///
/// @param line the output parameter where this function sets the
/// expanded line.
///
/// @param column the ouptut parameter where this function sets the
/// expanded column.
void
location::expand(std::string& path, unsigned& line, unsigned& column) const
{
  if (!get_location_manager())
    {
      // We don't have a location manager maybe because this location
      // was just freshly instanciated.  We still want to be able to
      // expand to default values.
      path = "";
      line = 0;
      column = 0;
      return;
    }
  get_location_manager()->expand_location(*this, path, line, column);
}


/// Expand the location into a string.
///
/// @return the string representing the location.
string
location::expand(void) const
{
  string path, result;
  unsigned line = 0, column = 0;
  expand(path, line, column);

  std::ostringstream o;
  o << path << ":" << line << ":" << column;
  return o.str();
}

struct location_manager::priv
{
  /// This sorted vector contains the expanded locations of the tokens
  /// coming from a given ABI Corpus.  The index of a given expanded
  /// location in the table gives us an integer that is used to build
  /// instance of location types.
  std::vector<expanded_location> locs;
};

location_manager::location_manager()
  : priv_(new location_manager::priv)
{}

location_manager::~location_manager() = default;

/// Insert the triplet representing a source locus into our internal
/// vector of location triplet.  Return an instance of location type,
/// built from an integral type that represents the index of the
/// source locus triplet into our source locus table.
///
/// @param file_path the file path of the source locus
/// @param line the line number of the source location
/// @param col the column number of the source location
location
location_manager::create_new_location(const std::string&	file_path,
				      size_t			line,
				      size_t			col)
{
  expanded_location l(file_path, line, col);

  // Just append the new expanded location to the end of the vector
  // and return its index.  Note that indexes start at 1.
  priv_->locs.push_back(l);
  return location(priv_->locs.size(), this);
}

/// Given an instance of location type, return the triplet
/// {path,line,column} that represents the source locus.  Note that
/// the location must have been previously created from the function
/// location_manager::create_new_location, otherwise this function yields
/// unexpected results, including possibly a crash.
///
/// @param location the instance of location type to expand
/// @param path the resulting path of the source locus
/// @param line the resulting line of the source locus
/// @param column the resulting colum of the source locus
void
location_manager::expand_location(const location&	location,
				  std::string&		path,
				  unsigned&		line,
				  unsigned&		column) const
{
  if (location.value_ == 0)
    return;
  expanded_location &l = priv_->locs[location.value_ - 1];
  path = l.path_;
  line = l.line_;
  column = l.column_;
}

typedef unordered_map<function_type_sptr,
		      bool,
		      function_type::hash,
		      type_shared_ptr_equal> fn_type_ptr_map;

// <type_maps stuff>

struct type_maps::priv
{
  mutable istring_type_base_wptrs_map_type	basic_types_;
  mutable istring_type_base_wptrs_map_type	class_types_;
  mutable istring_type_base_wptrs_map_type	union_types_;
  mutable istring_type_base_wptrs_map_type	enum_types_;
  mutable istring_type_base_wptrs_map_type	typedef_types_;
  mutable istring_type_base_wptrs_map_type	qualified_types_;
  mutable istring_type_base_wptrs_map_type	pointer_types_;
  mutable istring_type_base_wptrs_map_type	reference_types_;
  mutable istring_type_base_wptrs_map_type	array_types_;
  mutable istring_type_base_wptrs_map_type	subrange_types_;
  mutable istring_type_base_wptrs_map_type	function_types_;
  mutable vector<type_base_wptr>		sorted_types_;
}; // end struct type_maps::priv

type_maps::type_maps()
  : priv_(new priv)
{}

type_maps::~type_maps() = default;

/// Test if the type_maps is empty.
///
/// @return true iff the type_maps is empty.
bool
type_maps::empty() const
{
  return (basic_types().empty()
	  && class_types().empty()
	  && union_types().empty()
	  && enum_types().empty()
	  && typedef_types().empty()
	  && qualified_types().empty()
	  && pointer_types().empty()
	  && reference_types().empty()
	  && array_types().empty()
	  && subrange_types().empty()
	  && function_types().empty());
}

/// Getter for the map that associates the name of a basic type to the
/// vector instances of type_decl_sptr that represents that type.
const istring_type_base_wptrs_map_type&
type_maps::basic_types() const
{return priv_->basic_types_;}

/// Getter for the map that associates the name of a basic type to the
/// vector of instances of @ref type_decl_sptr that represents that
/// type.
istring_type_base_wptrs_map_type&
type_maps::basic_types()
{return priv_->basic_types_;}

/// Getter for the map that associates the name of a class type to the
/// vector of instances of @ref class_decl_sptr that represents that
/// type.
const istring_type_base_wptrs_map_type&
type_maps::class_types() const
{return priv_->class_types_;}

/// Getter for the map that associates the name of a class type to the
/// vector of instances of @ref class_decl_sptr that represents that
/// type.
istring_type_base_wptrs_map_type&
type_maps::class_types()
{return priv_->class_types_;}

/// Getter for the map that associates the name of a union type to the
/// vector of instances of @ref union_decl_sptr that represents that
/// type.
istring_type_base_wptrs_map_type&
type_maps::union_types()
{return priv_->union_types_;}

/// Getter for the map that associates the name of a union type to the
/// vector of instances of @ref union_decl_sptr that represents that
/// type.
const istring_type_base_wptrs_map_type&
type_maps::union_types() const
{return priv_->union_types_;}

/// Getter for the map that associates the name of an enum type to the
/// vector of instances of @ref enum_type_decl_sptr that represents
/// that type.
istring_type_base_wptrs_map_type&
type_maps::enum_types()
{return priv_->enum_types_;}

/// Getter for the map that associates the name of an enum type to the
/// vector of instances of @ref enum_type_decl_sptr that represents
/// that type.
const istring_type_base_wptrs_map_type&
type_maps::enum_types() const
{return priv_->enum_types_;}

/// Getter for the map that associates the name of a typedef to the
/// vector of instances of @ref typedef_decl_sptr that represents tha
/// type.
istring_type_base_wptrs_map_type&
type_maps::typedef_types()
{return priv_->typedef_types_;}

/// Getter for the map that associates the name of a typedef to the
/// vector of instances of @ref typedef_decl_sptr that represents tha
/// type.
const istring_type_base_wptrs_map_type&
type_maps::typedef_types() const
{return priv_->typedef_types_;}

/// Getter for the map that associates the name of a qualified type to
/// the vector of instances of @ref qualified_type_def_sptr.
istring_type_base_wptrs_map_type&
type_maps::qualified_types()
{return priv_->qualified_types_;}

/// Getter for the map that associates the name of a qualified type to
/// the vector of instances of @ref qualified_type_def_sptr.
const istring_type_base_wptrs_map_type&
type_maps::qualified_types() const
{return priv_->qualified_types_;}

/// Getter for the map that associates the name of a pointer type to
/// the vector of instances of @ref pointer_type_def_sptr that
/// represents that type.
istring_type_base_wptrs_map_type&
type_maps::pointer_types()
{return priv_->pointer_types_;}

/// Getter for the map that associates the name of a pointer type to
/// the vector of instances of @ref pointer_type_def_sptr that
/// represents that type.
const istring_type_base_wptrs_map_type&
type_maps::pointer_types() const
{return priv_->pointer_types_;}

/// Getter for the map that associates the name of a reference type to
/// the vector of instances of @ref reference_type_def_sptr that
/// represents that type.
istring_type_base_wptrs_map_type&
type_maps::reference_types()
{return priv_->reference_types_;}

/// Getter for the map that associates the name of a reference type to
/// the vector of instances of @ref reference_type_def_sptr that
/// represents that type.
const istring_type_base_wptrs_map_type&
type_maps::reference_types() const
{return priv_->reference_types_;}

/// Getter for the map that associates the name of an array type to
/// the vector of instances of @ref array_type_def_sptr that
/// represents that type.
istring_type_base_wptrs_map_type&
type_maps::array_types()
{return priv_->array_types_;}

/// Getter for the map that associates the name of an array type to
/// the vector of instances of @ref array_type_def_sptr that
/// represents that type.
const istring_type_base_wptrs_map_type&
type_maps::array_types() const
{return priv_->array_types_;}

/// Getter for the map that associates the name of a subrange type to
/// the vector of instances of @ref array_type_def::subrange_sptr that
/// represents that type.
istring_type_base_wptrs_map_type&
type_maps::subrange_types()
{return priv_->subrange_types_;}

/// Getter for the map that associates the name of a subrange type to
/// the vector of instances of @ref array_type_def::subrange_sptr that
/// represents that type.
const istring_type_base_wptrs_map_type&
type_maps::subrange_types() const
{return priv_->subrange_types_;}

/// Getter for the map that associates the name of a function type to
/// the vector of instances of @ref function_type_sptr that represents
/// that type.
const istring_type_base_wptrs_map_type&
type_maps::function_types() const
{return priv_->function_types_;}

/// Getter for the map that associates the name of a function type to
/// the vector of instances of @ref function_type_sptr that represents
/// that type.
istring_type_base_wptrs_map_type&
type_maps::function_types()
{return priv_->function_types_;}

/// A comparison functor to compare/sort types based on their pretty
/// representations.
struct type_name_comp
{
  /// Comparison operator for two instances of @ref type_base.
  ///
  /// This compares the two types by lexicographically comparing their
  /// pretty representation.
  ///
  /// @param l the left-most type to compare.
  ///
  /// @param r the right-most type to compare.
  ///
  /// @return true iff @p l < @p r.
  bool
  operator()(type_base *l, type_base *r) const
  {
    if (l == 0 && r == 0)
      return false;

    string l_repr = get_pretty_representation(l);
    string r_repr = get_pretty_representation(r);
    return l_repr < r_repr;
  }

  /// Comparison operator for two instances of @ref type_base.
  ///
  /// This compares the two types by lexicographically comparing their
  /// pretty representation.
  ///
  /// @param l the left-most type to compare.
  ///
  /// @param r the right-most type to compare.
  ///
  /// @return true iff @p l < @p r.
  bool
  operator()(const type_base_sptr &l, const type_base_sptr &r) const
  {return operator()(l.get(), r.get());}

  /// Comparison operator for two instances of @ref type_base.
  ///
  /// This compares the two types by lexicographically comparing their
  /// pretty representation.
  ///
  /// @param l the left-most type to compare.
  ///
  /// @param r the right-most type to compare.
  ///
  /// @return true iff @p l < @p r.
  bool
  operator()(const type_base_wptr &l, const type_base_wptr &r) const
  {return operator()(type_base_sptr(l), type_base_sptr(r));}
}; // end struct type_name_comp

#ifdef WITH_DEBUG_SELF_COMPARISON

/// This is a function called when the ABG_RETURN* macros defined
/// below return false.
///
/// The purpose of this function is to ease debugging.  To know where
/// the equality functions first compare non-equal, we can just set a
/// breakpoint on this notify_equality_failed function and run the
/// equality functions.  Because all the equality functions use the
/// ABG_RETURN* macros to return their values, this function is always
/// called when any of those equality function return false.
///
/// @param l the first operand of the equality.
///
/// @param r the second operand of the equality.
static void
notify_equality_failed(const type_or_decl_base &l __attribute__((unused)),
		       const type_or_decl_base &r __attribute__((unused)))
{}

/// This is a function called when the ABG_RETURN* macros defined
/// below return false.
///
/// The purpose of this function is to ease debugging.  To know where
/// the equality functions first compare non-equal, we can just set a
/// breakpoint on this notify_equality_failed function and run the
/// equality functions.  Because all the equality functions use the
/// ABG_RETURN* macros to return their values, this function is always
/// called when any of those equality function return false.
///
/// @param l the first operand of the equality.
///
/// @param r the second operand of the equality.
static void
notify_equality_failed(const type_or_decl_base *l __attribute__((unused)),
		       const type_or_decl_base *r __attribute__((unused)))
{}

#define ABG_RETURN_EQUAL(l, r)			\
  do						\
    {						\
      if (l != r)				\
        notify_equality_failed(l, r);		\
      return (l == r);				\
    }						\
  while(false)


#define ABG_RETURN_FALSE	    \
  do				    \
    {				    \
      notify_equality_failed(l, r); \
      return false;		    \
    } while(false)

#define ABG_RETURN(value)			\
  do						\
    {						\
      if (value == false)			\
	notify_equality_failed(l, r);		\
      return value;				\
    } while (false)

#else // WITH_DEBUG_SELF_COMPARISON

#define ABG_RETURN_FALSE return false
#define ABG_RETURN(value) return (value)
#define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
#endif

/// Compare two types by comparing their canonical types if present.
///
/// If the canonical types are not present (because the types have not
/// yet been canonicalized, for instance) then the types are compared
/// structurally.
///
/// @param l the first type to take into account in the comparison.
///
/// @param r the second type to take into account in the comparison.
template<typename T>
bool
try_canonical_compare(const T *l, const T *r)
{
#if WITH_DEBUG_TYPE_CANONICALIZATION
  // We are debugging the canonicalization of a type down the stack.
  // 'l' is a subtype of a canonical type and 'r' is a subtype of the
  // type being canonicalized.  We are at a point where we can compare
  // 'l' and 'r' either using canonical comparison (if 'l' and 'r'
  // have canonical types) or structural comparison.
  //
  // Because we are debugging the process of type canonicalization, we
  // want to compare 'l' and 'r' canonically *AND* structurally.  Both
  // kinds of comparison should yield the same result, otherwise type
  // canonicalization just failed for the subtype 'r' of the type
  // being canonicalized.
  //
  // In concrete terms, this function is going to be called twice with
  // the same pair {'l', 'r'} to compare: The first time with
  // environment::priv_->use_canonical_type_comparison_ set to true,
  // instructing us to compare them canonically, and the second time
  // with that boolean set to false, instructing us to compare them
  // structurally.
  const environment *env = l->get_environment();
  if (env->priv_->use_canonical_type_comparison_)
    {
      if (const type_base *lc = l->get_naked_canonical_type())
	if (const type_base *rc = r->get_naked_canonical_type())
	  ABG_RETURN_EQUAL(lc, rc);
    }
  return equals(*l, *r, 0);
#else
  if (const type_base *lc = l->get_naked_canonical_type())
    if (const type_base *rc = r->get_naked_canonical_type())
      ABG_RETURN_EQUAL(lc, rc);
  return equals(*l, *r, 0);
#endif


}

/// Detect if a recursive comparison cycle is detected while
/// structurally comparing two types (a.k.a member-wise comparison).
///
/// @param l the left-hand-side operand of the current comparison.
///
/// @param r the right-hand-side operand of the current comparison.
///
/// @return true iff a comparison cycle is detected.
template<typename T>
bool
is_comparison_cycle_detected(T& l, T& r)
{
  bool result = (l.priv_->comparison_started(l)
		 || l.priv_->comparison_started(r));
  return result ;
}

/// This macro is to be used while comparing composite types that
/// might recursively refer to themselves.  Comparing two such types
/// might get us into a cyle.
///
/// Practically, if we detect that we are already into comparing 'l'
/// and 'r'; then, this is a cycle.
//
/// To break the cycle, we assume the result of the comparison is true
/// for now.  Comparing the other sub-types of l & r will tell us later
/// if l & r are actually different or not.
///
/// In the mean time, returning true from this macro should not be
/// used to propagate the canonical type of 'l' onto 'r' as we don't
/// know yet if l equals r.  All the types that depend on l and r
/// can't (and that are in the comparison stack currently) can't have
/// their canonical type propagated either.  So this macro disallows
/// canonical type propagation for those types that depend on a
/// recursively defined sub-type for now.
///
/// @param l the left-hand-side operand of the comparison.
#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r)			\
  do									\
    {									\
      if (is_comparison_cycle_detected(l, r))				\
	{								\
	  mark_dependant_types_compared_until(r);			\
	  return true;							\
	}								\
    }									\
  while(false)


/// Mark a pair of types as being compared.
///
/// This is helpful to later detect recursive cycles in the comparison
/// stack.
///
/// @param l the left-hand-side operand of the comparison.
///
/// @parm r the right-hand-side operand of the comparison.
template<typename T>
void
mark_types_as_being_compared(T& l, T&r)
{
  l.priv_->mark_as_being_compared(l);
  l.priv_->mark_as_being_compared(r);
  push_composite_type_comparison_operands(l, r);
}

/// Mark a pair of types as being not compared anymore.
///
/// This is helpful to later detect recursive cycles in the comparison
/// stack.
///
/// Note that the types must have been passed to
/// mark_types_as_being_compared prior to calling this function.
///
/// @param l the left-hand-side operand of the comparison.
///
/// @parm r the right-hand-side operand of the comparison.
template<typename T>
void
unmark_types_as_being_compared(T& l, T&r)
{
  l.priv_->unmark_as_being_compared(l);
  l.priv_->unmark_as_being_compared(r);
  pop_composite_type_comparison_operands(l, r);
}

/// Return the result of the comparison of two (sub) types.
///
/// The function does the necessary book keeping before returning the
/// result of the comparison of two (sub) types.
///
/// The book-keeping done is in the following
/// areas:
///
///   * Management of the Canonical Type Propagation optimization
///   * type comparison cycle detection
///
///   @param l the left-hand-side operand of the type comparison
///
///   @param r the right-hand-side operand of the type comparison
///
///   @param propagate_canonical_type if true, it means the function
///   performs the @ref OnTheFlyCanonicalization, aka, "canonical type
///   propagation optimization".
///
///   @param value the result of the comparison of @p l and @p r.
///
///   @return the value @p value.
template<typename T>
bool
return_comparison_result(T& l, T& r, bool value,
			 bool propagate_canonical_type = true)
{
  if (propagate_canonical_type && (value == true))
    maybe_propagate_canonical_type(l, r);

  unmark_types_as_being_compared(l, r);

  const environment* env = l.get_environment();
  if (propagate_canonical_type && env->do_on_the_fly_canonicalization())
    // We are instructed to perform the "canonical type propagation"
    // optimization, making 'r' to possibly get the canonical type of
    // 'l' if it has one.  This mostly means that we are currently
    // canonicalizing the type that contain the subtype provided in
    // the 'r' argument.
    {
      if (value == true
	  && is_type(&r)->priv_->depends_on_recursive_type()
	  && !env->priv_->right_type_comp_operands_.empty()
	  && is_type(&r)->priv_->canonical_type_propagated())
	{
	  // Track the object 'r' for which the propagated canonical
	  // type might be re-initialized if the current comparison
	  // eventually fails.
	  env->priv_->types_with_non_confirmed_propagated_ct_.insert
	    (reinterpret_cast<uintptr_t>(is_type(&r)));
	}
      else if (value == true && env->priv_->right_type_comp_operands_.empty())
	{
	  // The type provided in the 'r' argument is the type that is
	  // being canonicalized; 'r' is not a mere subtype being
	  // compared, it's the whole type being canonicalized.  And
	  // its canonicalization has just succeeded.  So let's
	  // confirm the "canonical type propagation" of all the
	  // sub-types that were compared during the comparison of
	  // 'r'.
	  env->priv_->confirm_ct_propagation(&r);
	  if (is_type(&r)->priv_->depends_on_recursive_type())
	    {
	      is_type(&r)->priv_->set_does_not_depend_on_recursive_type();
	      env->priv_->remove_from_types_with_non_confirmed_propagated_ct(&r);
	    }
	}
      else if (value == false)
	{
	  // The comparison of the current sub-type failed.  So all
	  // the types in
	  // env->prix_->types_with_non_confirmed_propagated_ct_
	  // should see their tentatively propagated canonical type
	  // cancelled.
	  env->priv_->cancel_ct_propagation(&r);
	  if (is_type(&r)->priv_->depends_on_recursive_type())
	    {
	      // The right-hand-side operand cannot carry any tentative
	      // canonical type at this point.
	      is_type(&r)->priv_->clear_propagated_canonical_type();
	      // Reset the marking of the right-hand-side operand as it no
	      // longer carries a tentative canonical type that might be
	      // later cancelled.
	      is_type(&r)->priv_->set_does_not_depend_on_recursive_type();
	      env->priv_->remove_from_types_with_non_confirmed_propagated_ct(&r);
	    }
	}
    }
  ABG_RETURN(value);
}

/// Getter of all types types sorted by their pretty representation.
///
/// @return a sorted vector of all types sorted by their pretty
/// representation.
const vector<type_base_wptr>&
type_maps::get_types_sorted_by_name() const
{
  if (priv_->sorted_types_.empty())
    {
      istring_type_base_wptrs_map_type::const_iterator i;
      vector<type_base_wptr>::const_iterator j;

      for (i = basic_types().begin(); i != basic_types().end(); ++i)
	for (j = i->second.begin(); j != i->second.end(); ++j)
	  priv_->sorted_types_.push_back(*j);

      for (i = class_types().begin(); i != class_types().end(); ++i)
	for (j = i->second.begin(); j != i->second.end(); ++j)
	  priv_->sorted_types_.push_back(*j);

      for (i = union_types().begin(); i != union_types().end(); ++i)
	for (j = i->second.begin(); j != i->second.end(); ++j)
	  priv_->sorted_types_.push_back(*j);

      for (i = enum_types().begin(); i != enum_types().end(); ++i)
	for (j = i->second.begin(); j != i->second.end(); ++j)
	  priv_->sorted_types_.push_back(*j);

      for (i = typedef_types().begin(); i != typedef_types().end(); ++i)
	for (j = i->second.begin(); j != i->second.end(); ++j)
	  priv_->sorted_types_.push_back(*j);

      type_name_comp comp;
      sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
    }

  return priv_->sorted_types_;
}

// </type_maps stuff>

// <translation_unit stuff>

/// Constructor of translation_unit.
///
/// @param env the environment of this translation unit.  Please note
/// that the life time of the environment must be greater than the
/// life time of the translation unit because the translation uses
/// resources that are allocated in the environment.
///
/// @param path the location of the translation unit.
///
/// @param address_size the size of addresses in the translation unit,
/// in bits.
translation_unit::translation_unit(const environment*	env,
				   const std::string&	path,
				   char		address_size)
  : priv_(new priv(env))
{
  priv_->path_ = path;
  priv_->address_size_ = address_size;
}

/// Getter of the the global scope of the translation unit.
///
/// @return the global scope of the current translation unit.  If
/// there is not global scope allocated yet, this function creates one
/// and returns it.
const scope_decl_sptr&
translation_unit::get_global_scope() const
{
  return const_cast<translation_unit*>(this)->get_global_scope();
}

/// Getter of the the global scope of the translation unit.
///
/// @return the global scope of the current translation unit.  If
/// there is not global scope allocated yet, this function creates one
/// and returns it.
scope_decl_sptr&
translation_unit::get_global_scope()
{
  if (!priv_->global_scope_)
    {
      priv_->global_scope_.reset
	(new global_scope(const_cast<translation_unit*>(this)));
      // The global scope must be out of the same environment as its
      // translation unit.
      priv_->global_scope_->
	set_environment(const_cast<environment*>(get_environment()));
      priv_->global_scope_->set_translation_unit
	(const_cast<translation_unit*>(this));
    }
  return priv_->global_scope_;
}

/// Getter of the types of the current @ref translation_unit.
///
/// @return the maps of the types of the translation unit.
const type_maps&
translation_unit::get_types() const
{return priv_->types_;}

/// Getter of the types of the current @ref translation_unit.
///
/// @return the maps of the types of the translation unit.
type_maps&
translation_unit::get_types()
{return priv_->types_;}

/// Get the vector of function types that are used in the current
/// translation unit.
///
/// @return the vector of function types that are used in the current
/// translation unit.
const vector<function_type_sptr>&
translation_unit::get_live_fn_types() const
{return priv_->live_fn_types_;}

/// Getter of the environment of the current @ref translation_unit.
///
/// @return the translation unit of the current translation unit.
const environment*
translation_unit::get_environment() const
{return priv_->env_;}

/// Getter of the environment of the current @ref translation_unit.
///
/// @return the translation unit of the current translation unit.
environment*
translation_unit::get_environment()
{return const_cast<environment*>(priv_->env_);}

/// Setter of the environment of the current @ref translation_unit.
///
/// @param env the environment.
void
translation_unit::set_environment(const environment* env)
{priv_->env_ = env;}

/// Getter of the language of the source code of the translation unit.
///
/// @return the language of the source code.
translation_unit::language
translation_unit::get_language() const
{return priv_->language_;}

/// Setter of the language of the source code of the translation unit.
///
/// @param l the new language.
void
translation_unit::set_language(language l)
{priv_->language_ = l;}


/// Get the path of the current translation unit.
///
/// This path is relative to the build directory of the translation
/// unit as returned by translation_unit::get_compilation_dir_path.
///
/// @return the relative path of the compilation unit associated to
/// the current instance of translation_unit.
//
const std::string&
translation_unit::get_path() const
{return priv_->path_;}

/// Set the path associated to the current instance of
/// translation_unit.
///
/// This path is relative to the build directory of the translation
/// unit as returned by translation_unit::get_compilation_dir_path.
///
/// @param a_path the new relative path to set.
void
translation_unit::set_path(const string& a_path)
{priv_->path_ = a_path;}


/// Get the path of the directory that was 'current' when the
/// translation unit was compiled.
///
/// Note that the path returned by translation_unit::get_path is
/// relative to the path returned by this function.
///
/// @return the compilation directory for the current translation
/// unit.
const std::string&
translation_unit::get_compilation_dir_path() const
{return priv_->comp_dir_path_;}

/// Set the path of the directory that was 'current' when the
/// translation unit was compiled.
///
/// Note that the path returned by translation_unit::get_path is
/// relative to the path returned by this function.
///
/// @param the compilation directory for the current translation unit.
void
translation_unit::set_compilation_dir_path(const std::string& d)
{priv_->comp_dir_path_ = d;}

/// Get the concatenation of the build directory and the relative path
/// of the translation unit.
///
/// @return the absolute path of the translation unit.
const std::string&
translation_unit::get_absolute_path() const
{
  if (priv_->abs_path_.empty())
    {
      string path;
      if (!priv_->path_.empty())
	{
	  if (!priv_->comp_dir_path_.empty())
	    {
	      path = priv_->comp_dir_path_;
	      path += "/";
	    }
	  path += priv_->path_;
	}
      priv_->abs_path_ = path;
    }

  return priv_->abs_path_;
}

/// Set the corpus this translation unit is a member of.
///
/// Note that adding a translation unit to a @ref corpus automatically
/// triggers a call to this member function.
///
/// @param corpus the corpus.
void
translation_unit::set_corpus(corpus* c)
{priv_->corp = c;}

/// Get the corpus this translation unit is a member of.
///
/// @return the parent corpus, or nil if this doesn't belong to any
/// corpus yet.
corpus*
translation_unit::get_corpus()
{return priv_->corp;}

/// Get the corpus this translation unit is a member of.
///
/// @return the parent corpus, or nil if this doesn't belong to any
/// corpus yet.
const corpus*
translation_unit::get_corpus() const
{return const_cast<translation_unit*>(this)->get_corpus();}

/// Getter of the location manager for the current translation unit.
///
/// @return a reference to the location manager for the current
/// translation unit.
location_manager&
translation_unit::get_loc_mgr()
{return priv_->loc_mgr_;}

/// const Getter of the location manager.
///
/// @return a const reference to the location manager for the current
/// translation unit.
const location_manager&
translation_unit::get_loc_mgr() const
{return priv_->loc_mgr_;}

/// Tests whether if the current translation unit contains ABI
/// artifacts or not.
///
/// @return true iff the current translation unit is empty.
bool
translation_unit::is_empty() const
{return get_global_scope()->is_empty();}

/// Getter of the address size in this translation unit.
///
/// @return the address size, in bits.
char
translation_unit::get_address_size() const
{return priv_->address_size_;}

/// Setter of the address size in this translation unit.
///
/// @param a the new address size in bits.
void
translation_unit::set_address_size(char a)
{priv_->address_size_= a;}

/// Getter of the 'is_constructed" flag.  It says if the translation
/// unit is fully constructed or not.
///
/// This flag is important for cases when comparison might depend on
/// if the translation unit is fully built or not.  For instance, when
/// reading types from DWARF, the virtual methods of a class are not
/// necessarily fully constructed until we have reached the end of the
/// translation unit.  In that case, before we've reached the end of
/// the translation unit, we might not take virtual functions into
/// account when comparing classes.
///
/// @return true if the translation unit is constructed.
bool
translation_unit::is_constructed() const
{return priv_->is_constructed_;}

/// Setter of the 'is_constructed" flag.  It says if the translation
/// unit is fully constructed or not.
///
/// This flag is important for cases when comparison might depend on
/// if the translation unit is fully built or not.  For instance, when
/// reading types from DWARF, the virtual methods of a class are not
/// necessarily fully constructed until we have reached the end of the
/// translation unit.  In that case, before we've reached the end of
/// the translation unit, we might not take virtual functions into
/// account when comparing classes.
///
/// @param f true if the translation unit is constructed.
void
translation_unit::set_is_constructed(bool f)
{priv_->is_constructed_ = f;}

/// Compare the current translation unit against another one.
///
/// @param other the other tu to compare against.
///
/// @return true if the two translation units are equal, false
/// otherwise.
bool
translation_unit::operator==(const translation_unit& other)const
{
  if (get_address_size() != other.get_address_size())
    return false;

  return *get_global_scope() == *other.get_global_scope();
}

/// Inequality operator.
///
/// @param o the instance of @ref translation_unit to compare the
/// current instance against.
///
/// @return true iff the current instance is different from @p o.
bool
translation_unit::operator!=(const translation_unit& o) const
{return ! operator==(o);}

/// Ensure that the life time of a function type is bound to the life
/// time of the current translation unit.
///
/// @param ftype the function time which life time to bind to the life
/// time of the current instance of @ref translation_unit.  That is,
/// it's onlyh when the translation unit is destroyed that the
/// function type can be destroyed to.
void
translation_unit::bind_function_type_life_time(function_type_sptr ftype) const
{
  const environment* env = get_environment();
  ABG_ASSERT(env);

  const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);

  interned_string repr = get_type_name(ftype);
  const_cast<translation_unit*>(this)->get_types().function_types()[repr].
    push_back(ftype);

  // The function type must be out of the same environment as its
  // translation unit.
  if (const environment* e = ftype->get_environment())
    ABG_ASSERT(env == e);
  ftype->set_environment(const_cast<environment*>(env));

  if (const translation_unit* existing_tu = ftype->get_translation_unit())
    ABG_ASSERT(existing_tu == this);
  else
    ftype->set_translation_unit(const_cast<translation_unit*>(this));
}

/// This implements the ir_traversable_base::traverse virtual
/// function.
///
/// @param v the visitor used on the member nodes of the translation
/// unit during the traversal.
///
/// @return true if the entire type IR tree got traversed, false
/// otherwise.
bool
translation_unit::traverse(ir_node_visitor& v)
{return get_global_scope()->traverse(v);}

translation_unit::~translation_unit()
{}

/// Converts a translation_unit::language enumerator into a string.
///
/// @param l the language enumerator to translate.
///
/// @return the resulting string.
string
translation_unit_language_to_string(translation_unit::language l)
{
  switch (l)
    {
    case translation_unit::LANG_UNKNOWN:
      return "LANG_UNKNOWN";
    case translation_unit::LANG_Cobol74:
      return "LANG_Cobol74";
    case translation_unit::LANG_Cobol85:
      return "LANG_Cobol85";
    case translation_unit::LANG_C89:
      return "LANG_C89";
    case translation_unit::LANG_C99:
      return "LANG_C99";
    case translation_unit::LANG_C11:
      return "LANG_C11";
    case translation_unit::LANG_C:
      return "LANG_C";
    case translation_unit::LANG_C_plus_plus_11:
      return "LANG_C_plus_plus_11";
    case translation_unit::LANG_C_plus_plus_14:
      return "LANG_C_plus_plus_14";
    case translation_unit::LANG_C_plus_plus:
      return "LANG_C_plus_plus";
    case translation_unit::LANG_ObjC:
      return "LANG_ObjC";
    case translation_unit::LANG_ObjC_plus_plus:
      return "LANG_ObjC_plus_plus";
    case translation_unit::LANG_Fortran77:
      return "LANG_Fortran77";
    case translation_unit::LANG_Fortran90:
      return "LANG_Fortran90";
    case translation_unit::LANG_Fortran95:
      return "LANG_Fortran95";
    case translation_unit::LANG_Ada83:
      return "LANG_Ada83";
    case translation_unit::LANG_Ada95:
      return "LANG_Ada95";
    case translation_unit::LANG_Pascal83:
      return "LANG_Pascal83";
    case translation_unit::LANG_Modula2:
      return "LANG_Modula2";
    case translation_unit::LANG_Java:
      return "LANG_Java";
    case translation_unit::LANG_PLI:
      return "LANG_PLI";
    case translation_unit::LANG_UPC:
      return "LANG_UPC";
    case translation_unit::LANG_D:
      return "LANG_D";
    case translation_unit::LANG_Python:
      return "LANG_Python";
    case translation_unit::LANG_Go:
      return "LANG_Go";
    case translation_unit::LANG_Mips_Assembler:
      return "LANG_Mips_Assembler";
    default:
      return "LANG_UNKNOWN";
    }

  return "LANG_UNKNOWN";
}

/// Parse a string representing a language into a
/// translation_unit::language enumerator into a string.
///
/// @param l the string representing the language.
///
/// @return the resulting translation_unit::language enumerator.
translation_unit::language
string_to_translation_unit_language(const string& l)
{
  if (l == "LANG_Cobol74")
    return translation_unit::LANG_Cobol74;
  else if (l == "LANG_Cobol85")
    return translation_unit::LANG_Cobol85;
  else if (l == "LANG_C89")
    return translation_unit::LANG_C89;
  else if (l == "LANG_C99")
    return translation_unit::LANG_C99;
  else if (l == "LANG_C11")
    return translation_unit::LANG_C11;
  else if (l == "LANG_C")
    return translation_unit::LANG_C;
  else if (l == "LANG_C_plus_plus_11")
    return translation_unit::LANG_C_plus_plus_11;
  else if (l == "LANG_C_plus_plus_14")
    return translation_unit::LANG_C_plus_plus_14;
  else if (l == "LANG_C_plus_plus")
    return translation_unit::LANG_C_plus_plus;
  else if (l == "LANG_ObjC")
    return translation_unit::LANG_ObjC;
  else if (l == "LANG_ObjC_plus_plus")
    return translation_unit::LANG_ObjC_plus_plus;
  else if (l == "LANG_Fortran77")
    return translation_unit::LANG_Fortran77;
  else if (l == "LANG_Fortran90")
    return translation_unit::LANG_Fortran90;
    else if (l == "LANG_Fortran95")
    return translation_unit::LANG_Fortran95;
  else if (l == "LANG_Ada83")
    return translation_unit::LANG_Ada83;
  else if (l == "LANG_Ada95")
    return translation_unit::LANG_Ada95;
  else if (l == "LANG_Pascal83")
    return translation_unit::LANG_Pascal83;
  else if (l == "LANG_Modula2")
    return translation_unit::LANG_Modula2;
  else if (l == "LANG_Java")
    return translation_unit::LANG_Java;
  else if (l == "LANG_PLI")
    return translation_unit::LANG_PLI;
  else if (l == "LANG_UPC")
    return translation_unit::LANG_UPC;
  else if (l == "LANG_D")
    return translation_unit::LANG_D;
  else if (l == "LANG_Python")
    return translation_unit::LANG_Python;
  else if (l == "LANG_Go")
    return translation_unit::LANG_Go;
  else if (l == "LANG_Mips_Assembler")
    return translation_unit::LANG_Mips_Assembler;

  return translation_unit::LANG_UNKNOWN;
}

/// Test if a language enumerator designates the C language.
///
/// @param l the language enumerator to consider.
///
/// @return true iff @p l designates the C language.
bool
is_c_language(translation_unit::language l)
{
  return (l == translation_unit::LANG_C89
	  || l == translation_unit::LANG_C99
	  || l == translation_unit::LANG_C11
	  || l == translation_unit::LANG_C);
}

/// Test if a language enumerator designates the C++ language.
///
/// @param l the language enumerator to consider.
///
/// @return true iff @p l designates the C++ language.
bool
is_cplus_plus_language(translation_unit::language l)
{
  return (l == translation_unit::LANG_C_plus_plus_03
	  || l == translation_unit::LANG_C_plus_plus_11
	  || l == translation_unit::LANG_C_plus_plus_14
	  || l == translation_unit::LANG_C_plus_plus);
}

/// Test if a language enumerator designates the Java language.
///
/// @param l the language enumerator to consider.
///
/// @return true iff @p l designates the Java language.
bool
is_java_language(translation_unit::language l)
{return l == translation_unit::LANG_Java;}

/// Test if a language enumerator designates the Ada language.
///
/// @param l the language enumerator to consider.
///
/// @return true iff @p l designates the Ada language.
bool
is_ada_language(translation_unit::language l)
{
  return (l == translation_unit::LANG_Ada83
	 || l == translation_unit::LANG_Ada95);
}

/// A deep comparison operator for pointers to translation units.
///
/// @param l the first translation unit to consider for the comparison.
///
/// @param r the second translation unit to consider for the comparison.
///
/// @return true if the two translation units are equal, false otherwise.
bool
operator==(const translation_unit_sptr& l, const translation_unit_sptr& r)
{
  if (l.get() == r.get())
    return true;

  if (!!l != !!r)
    return false;

  return *l == *r;
}

/// A deep inequality operator for pointers to translation units.
///
/// @param l the first translation unit to consider for the comparison.
///
/// @param r the second translation unit to consider for the comparison.
///
/// @return true iff the two translation units are different.
bool
operator!=(const translation_unit_sptr& l, const translation_unit_sptr& r)
{return !operator==(l, r);}

// </translation_unit stuff>

// <elf_symbol stuff>
struct elf_symbol::priv
{
  const environment*	env_;
  size_t		index_;
  size_t		size_;
  string		name_;
  elf_symbol::type	type_;
  elf_symbol::binding	binding_;
  elf_symbol::version	version_;
  elf_symbol::visibility visibility_;
  bool			is_defined_;
  // This flag below says if the symbol is a common elf symbol.  In
  // relocatable files, a common symbol is a symbol defined in a
  // section of kind SHN_COMMON.
  //
  // Note that a symbol of kind STT_COMMON is also considered a common
  // symbol.  Here is what the gABI says about STT_COMMON and
  // SHN_COMMON:
  //
  //     Symbols with type STT_COMMON label uninitialized common
  //     blocks. In relocatable objects, these symbols are not
  //     allocated and must have the special section index SHN_COMMON
  //     (see below). In shared objects and executables these symbols
  //     must be allocated to some section in the defining object.
  //
  //     In relocatable objects, symbols with type STT_COMMON are
  //     treated just as other symbols with index SHN_COMMON. If the
  //     link-editor allocates space for the SHN_COMMON symbol in an
  //     output section of the object it is producing, it must
  //     preserve the type of the output symbol as STT_COMMON.
  //
  //     When the dynamic linker encounters a reference to a symbol
  //     that resolves to a definition of type STT_COMMON, it may (but
  //     is not required to) change its symbol resolution rules as
  //     follows: instead of binding the reference to the first symbol
  //     found with the given name, the dynamic linker searches for
  //     the first symbol with that name with type other than
  //     STT_COMMON. If no such symbol is found, it looks for the
  //     STT_COMMON definition of that name that has the largest size.
  bool			is_common_;
  bool			is_in_ksymtab_;
  abg_compat::optional<uint64_t>	crc_;
  bool			is_suppressed_;
  elf_symbol_wptr	main_symbol_;
  elf_symbol_wptr	next_alias_;
  elf_symbol_wptr	next_common_instance_;
  string		id_string_;

  priv()
    : env_(),
      index_(),
      size_(),
      type_(elf_symbol::NOTYPE_TYPE),
      binding_(elf_symbol::GLOBAL_BINDING),
      visibility_(elf_symbol::DEFAULT_VISIBILITY),
      is_defined_(false),
      is_common_(false),
      is_in_ksymtab_(false),
      crc_(),
      is_suppressed_(false)
  {}

  priv(const environment*	  e,
       size_t			  i,
       size_t			  s,
       const string&		  n,
       elf_symbol::type		  t,
       elf_symbol::binding	  b,
       bool			  d,
       bool			  c,
       const elf_symbol::version& ve,
       elf_symbol::visibility	  vi,
       bool			  is_in_ksymtab,
       const abg_compat::optional<uint64_t>&	crc,
       bool			  is_suppressed)
    : env_(e),
      index_(i),
      size_(s),
      name_(n),
      type_(t),
      binding_(b),
      version_(ve),
      visibility_(vi),
      is_defined_(d),
      is_common_(c),
      is_in_ksymtab_(is_in_ksymtab),
      crc_(crc),
      is_suppressed_(is_suppressed)
  {
    if (!is_common_)
      is_common_ = type_ == COMMON_TYPE;
  }
}; // end struct elf_symbol::priv

/// Default constructor of the @ref elf_symbol type.
///
/// Note that this constructor is private, so client code cannot use
/// it to create instances of @ref elf_symbol.  Rather, client code
/// should use the @ref elf_symbol::create() function to create
/// instances of @ref elf_symbol instead.
elf_symbol::elf_symbol()
  : priv_(new priv)
{}

/// Constructor of the @ref elf_symbol type.
///
/// Note that this constructor is private, so client code cannot use
/// it to create instances of @ref elf_symbol.  Rather, client code
/// should use the @ref elf_symbol::create() function to create
/// instances of @ref elf_symbol instead.
///
/// @param e the environment we are operating from.
///
/// @param i the index of the symbol in the (ELF) symbol table.
///
/// @param s the size of the symbol.
///
/// @param n the name of the symbol.
///
/// @param t the type of the symbol.
///
/// @param b the binding of the symbol.
///
/// @param d true if the symbol is defined, false otherwise.
///
/// @param c true if the symbol is a common symbol, false otherwise.
///
/// @param ve the version of the symbol.
///
/// @param vi the visibility of the symbol.
///
/// @param crc the CRC (modversions) value of Linux Kernel symbols
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,
		       const abg_compat::optional<uint64_t>&	crc,
		       bool		  is_suppressed)
  : priv_(new priv(e,
		   i,
		   s,
		   n,
		   t,
		   b,
		   d,
		   c,
		   ve,
		   vi,
		   is_in_ksymtab,
		   crc,
		   is_suppressed))
{}

/// Factory of instances of @ref elf_symbol.
///
/// This is the function to use to create instances of @ref elf_symbol.
///
/// @return a (smart) pointer to a newly created instance of @ref
/// elf_symbol.
elf_symbol_sptr
elf_symbol::create()
{
  elf_symbol_sptr e(new elf_symbol());
  e->priv_->main_symbol_ = e;
  return e;
}

/// Factory of instances of @ref elf_symbol.
///
/// This is the function to use to create instances of @ref elf_symbol.
///
/// @param e the environment we are operating from.
///
/// @param i the index of the symbol in the (ELF) symbol table.
///
/// @param s the size of the symbol.
///
/// @param n the name of the symbol.
///
/// @param t the type of the symbol.
///
/// @param b the binding of the symbol.
///
/// @param d true if the symbol is defined, false otherwise.
///
/// @param c true if the symbol is a common symbol.
///
/// @param ve the version of the symbol.
///
/// @param vi the visibility of the symbol.
///
/// @param crc the CRC (modversions) value of Linux Kernel symbols
///
/// @return a (smart) pointer to a newly created instance of @ref
/// elf_symbol.
elf_symbol_sptr
elf_symbol::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,
		   const abg_compat::optional<uint64_t>&	crc,
		   bool		      is_suppressed)
{
  elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
				     is_in_ksymtab, crc, is_suppressed));
  sym->priv_->main_symbol_ = sym;
  return sym;
}

/// Test textual equality between two symbols.
///
/// Textual equality means that the aliases of the compared symbols
/// are not taken into account.  Only the name, type, and version of
/// the symbols are compared.
///
/// @return true iff the two symbols are textually equal.
static bool
textually_equals(const elf_symbol&l,
		 const elf_symbol&r)
{
  bool equals = (l.get_name() == r.get_name()
		 && l.get_type() == r.get_type()
		 && l.is_public() == r.is_public()
		 && l.is_defined() == r.is_defined()
		 && l.is_common_symbol() == r.is_common_symbol()
		 && l.get_version() == r.get_version()
		 && l.get_crc() == r.get_crc());

  if (equals && l.is_variable())
    // These are variable symbols.  Let's compare their symbol size.
    // The symbol size in this case is the size taken by the storage
    // of the variable.  If that size changes, then it's an ABI
    // change.
    equals = l.get_size() == r.get_size();

  return equals;
}

/// Getter of the environment used by the current instance of @ref
/// elf_symbol.
///
/// @return the enviroment used by the current instance of @ref elf_symbol.
const environment*
elf_symbol::get_environment() const
{return priv_->env_;}

/// Setter of the environment used by the current instance of @ref
/// elf_symbol.
///
/// @param The new enviroment used by the current instance of @ref
/// elf_symbol.
void
elf_symbol::set_environment(const environment* e) const
{priv_->env_ = e;}

/// Getter for the index
///
/// @return the index of the symbol.
size_t
elf_symbol::get_index() const
{return priv_->index_;}

/// Setter for the index.
///
/// @param s the new index.
void
elf_symbol::set_index(size_t s)
{priv_->index_ = s;}

/// Getter for the name of the @ref elf_symbol.
///
/// @return a reference to the name of the @ref symbol.
const string&
elf_symbol::get_name() const
{return priv_->name_;}

/// Setter for the name of the current intance of @ref elf_symbol.
///
/// @param n the new name.
void
elf_symbol::set_name(const string& n)
{
  priv_->name_ = n;
  priv_->id_string_.clear();
}

/// Getter for the type of the current instance of @ref elf_symbol.
///
/// @return the type of the elf symbol.
elf_symbol::type
elf_symbol::get_type() const
{return priv_->type_;}

/// Setter for the type of the current instance of @ref elf_symbol.
///
/// @param t the new symbol type.
void
elf_symbol::set_type(type t)
{priv_->type_ = t;}

/// Getter of the size of the symbol.
///
/// @return the size of the symbol, in bytes.
size_t
elf_symbol::get_size() const
{return priv_->size_;}

/// Setter of the size of the symbol.
///
/// @param size the new size of the symbol, in bytes.
void
elf_symbol::set_size(size_t size)
{priv_->size_ = size;}

/// Getter for the binding of the current instance of @ref elf_symbol.
///
/// @return the binding of the symbol.
elf_symbol::binding
elf_symbol::get_binding() const
{return priv_->binding_;}

/// Setter for the binding of the current instance of @ref elf_symbol.
///
/// @param b the new binding.
void
elf_symbol::set_binding(binding b)
{priv_->binding_ = b;}

/// Getter for the version of the current instanc of @ref elf_symbol.
///
/// @return the version of the elf symbol.
elf_symbol::version&
elf_symbol::get_version() const
{return priv_->version_;}

/// Setter for the version of the current instance of @ref elf_symbol.
///
/// @param v the new version of the elf symbol.
void
elf_symbol::set_version(const version& v)
{
  priv_->version_ = v;
  priv_->id_string_.clear();
}

/// Setter of the visibility of the current instance of @ref
/// elf_symbol.
///
/// @param v the new visibility of the elf symbol.
void
elf_symbol::set_visibility(visibility v)
{priv_->visibility_ = v;}

/// Getter of the visibility of the current instance of @ref
/// elf_symbol.
///
/// @return the visibility of the elf symbol.
elf_symbol::visibility
elf_symbol::get_visibility() const
{return priv_->visibility_;}

/// Test if the current instance of @ref elf_symbol is defined or not.
///
/// @return true if the current instance of @ref elf_symbol is
/// defined, false otherwise.
bool
elf_symbol::is_defined() const
{return priv_->is_defined_;}

/// Sets a flag saying if the current instance of @ref elf_symbol is
/// defined
///
/// @param b the new value of the flag.
void
elf_symbol::is_defined(bool d)
{priv_->is_defined_ = d;}

/// Test if the current instance of @ref elf_symbol is public or not.
///
/// This tests if the symbol is defined, has default or protected
///visibility, and either:
///		- has global binding
///		- has weak binding
///		- or has a GNU_UNIQUE binding.
///
/// return true if the current instance of @ref elf_symbol is public,
/// false otherwise.
bool
elf_symbol::is_public() const
{
  return (is_defined()
	  && (get_binding() == GLOBAL_BINDING
	      || get_binding() == WEAK_BINDING
	      || get_binding() == GNU_UNIQUE_BINDING)
	  && (get_visibility() == DEFAULT_VISIBILITY
	      || get_visibility() == PROTECTED_VISIBILITY));
}

/// Test if the current instance of @ref elf_symbol is a function
/// symbol or not.
///
/// @return true if the current instance of @ref elf_symbol is a
/// function symbol, false otherwise.
bool
elf_symbol::is_function() const
{return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}

/// Test if the current instance of @ref elf_symbol is a variable
/// symbol or not.
///
/// @return true if the current instance of @ref elf_symbol is a
/// variable symbol, false otherwise.
bool
elf_symbol::is_variable() const
{return get_type() == OBJECT_TYPE || get_type() == TLS_TYPE;}

/// Getter of the 'is-in-ksymtab' property.
///
/// @return true iff the current symbol is in the Linux Kernel
/// specific 'ksymtab' symbol table.
bool
elf_symbol::is_in_ksymtab() const
{return priv_->is_in_ksymtab_;}

/// Setter of the 'is-in-ksymtab' property.
///
/// @param is_in_ksymtab this is true iff the current symbol is in the
/// Linux Kernel specific 'ksymtab' symbol table.
void
elf_symbol::set_is_in_ksymtab(bool is_in_ksymtab)
{priv_->is_in_ksymtab_ = is_in_ksymtab;}

/// Getter of the 'crc' property.
///
/// @return the CRC (modversions) value for Linux Kernel symbols, if any
const abg_compat::optional<uint64_t>&
elf_symbol::get_crc() const
{return priv_->crc_;}

/// Setter of the 'crc' property.
///
/// @param crc the new CRC (modversions) value for Linux Kernel symbols
void
elf_symbol::set_crc(const abg_compat::optional<uint64_t>& crc)
{priv_->crc_ = crc;}

/// Getter for the 'is-suppressed' property.
///
/// @return true iff the current symbol has been suppressed by a
/// suppression specification that was provided in the context that
/// led to the creation of the corpus this ELF symbol belongs to.
bool
elf_symbol::is_suppressed() const
{return priv_->is_suppressed_;}

/// Setter for the 'is-suppressed' property.
///
/// @param true iff the current symbol has been suppressed by a
/// suppression specification that was provided in the context that
/// led to the creation of the corpus this ELF symbol belongs to.
void
elf_symbol::set_is_suppressed(bool is_suppressed)
{priv_->is_suppressed_ = is_suppressed;}

/// @name Elf symbol aliases
///
/// An alias A for an elf symbol S is a symbol that is defined at the
/// same address as S.  S is chained to A through the
/// elf_symbol::get_next_alias() method.
///
/// When there are several aliases to a symbol, the main symbol is the
/// the first symbol found in the symbol table for a given address.
///
/// The alias chain is circular.  That means if S is the main symbol
/// and A is the alias, S is chained to A and A
/// is chained back to the main symbol S.  The last alias in an alias
///chain is always chained to the main symbol.
///
/// Thus, when looping over the aliases of an elf_symbol A, detecting
/// an alias that is equal to the main symbol should logically be a
/// loop exit condition.
///
/// Accessing and adding aliases for instances of elf_symbol is done
/// through the member functions below.

/// @{

/// Get the main symbol of an alias chain.
///
///@return the main symbol.
const elf_symbol_sptr
elf_symbol::get_main_symbol() const
{return priv_->main_symbol_.lock();}

/// Get the main symbol of an alias chain.
///
///@return the main symbol.
elf_symbol_sptr
elf_symbol::get_main_symbol()
{return priv_->main_symbol_.lock();}

/// Tests whether this symbol is the main symbol.
///
/// @return true iff this symbol is the main symbol.
bool
elf_symbol::is_main_symbol() const
{return get_main_symbol().get() == this;}

/// Get the next alias of the current symbol.
///
///@return the alias, or NULL if there is no alias.
elf_symbol_sptr
elf_symbol::get_next_alias() const
{return priv_->next_alias_.lock();}


/// Check if the current elf_symbol has an alias.
///
///@return true iff the current elf_symbol has an alias.
bool
elf_symbol::has_aliases() const
{return bool(get_next_alias());}

/// Get the number of aliases to this elf symbol
///
/// @return the number of aliases to this elf symbol.
int
elf_symbol::get_number_of_aliases() const
{
  int result = 0;

  for (elf_symbol_sptr a = get_next_alias();
       a && a.get() != get_main_symbol().get();
       a = a->get_next_alias())
    ++result;

  return result;
}

/// Add an alias to the current elf symbol.
///
/// @param alias the new alias.  Note that this elf_symbol should *NOT*
/// have aliases prior to the invocation of this function.
void
elf_symbol::add_alias(const elf_symbol_sptr& alias)
{
  if (!alias)
    return;

  ABG_ASSERT(!alias->has_aliases());
  ABG_ASSERT(is_main_symbol());

  if (has_aliases())
    {
      elf_symbol_sptr last_alias;
      for (elf_symbol_sptr a = get_next_alias();
	   a && !a->is_main_symbol();
	   a = a->get_next_alias())
	{
	  if (a->get_next_alias()->is_main_symbol())
	    {
	      ABG_ASSERT(last_alias == 0);
	      last_alias = a;
	    }
	}
      ABG_ASSERT(last_alias);

      last_alias->priv_->next_alias_ = alias;
    }
  else
    priv_->next_alias_ = alias;

  alias->priv_->next_alias_ = get_main_symbol();
  alias->priv_->main_symbol_ = get_main_symbol();
}

/// Update the main symbol for a group of aliased symbols
///
/// If after the construction of the symbols (in order of discovery), the
/// actual main symbol can be identified (e.g. as the symbol that actually is
/// defined in the code), this method offers a way of updating the main symbol
/// through one of the aliased symbols.
///
/// For that, locate the new main symbol by name and update all references to
/// the main symbol among the group of aliased symbols.
///
/// @param name the name of the main symbol
///
/// @return the new main elf_symbol
elf_symbol_sptr
elf_symbol::update_main_symbol(const std::string& name)
{
  ABG_ASSERT(is_main_symbol());
  if (!has_aliases() || get_name() == name)
    return get_main_symbol();

  // find the new main symbol
  elf_symbol_sptr new_main;
  // we've already checked this; check the rest of the aliases
  for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
       a = a->get_next_alias())
    if (a->get_name() == name)
      {
	new_main = a;
	break;
      }

  if (!new_main)
    return get_main_symbol();

  // now update all main symbol references
  priv_->main_symbol_ = new_main;
  for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
       a = a->get_next_alias())
    a->priv_->main_symbol_ = new_main;

  return new_main;
}

/// Return true if the symbol is a common one.
///
/// @return true iff the symbol is common.
bool
elf_symbol::is_common_symbol() const
{return priv_->is_common_;}

/// Return true if this common common symbol has other common instances.
///
/// A common instance of a given common symbol is another common
/// symbol with the same name.  Those exist in relocatable files.  The
/// linker normally allocates all the instances into a common block in
/// the final output file.
///
/// Note that the current object must be a common symbol, otherwise,
/// this function aborts.
///
/// @return true iff the current common symbol has other common
/// instances.
bool
elf_symbol::has_other_common_instances() const
{
  ABG_ASSERT(is_common_symbol());
  return bool(get_next_common_instance());
}

/// Get the next common instance of the current common symbol.
///
/// A common instance of a given common symbol is another common
/// symbol with the same name.  Those exist in relocatable files.  The
/// linker normally allocates all the instances into a common block in
/// the final output file.
///
/// @return the next common instance, or nil if there is not any.
elf_symbol_sptr
elf_symbol::get_next_common_instance() const
{return priv_->next_common_instance_.lock();}

/// Add a common instance to the current common elf symbol.
///
/// Note that this symbol must be the main symbol.  Being the main
/// symbol means being the first common symbol to appear in the symbol
/// table.
///
/// @param common the other common instance to add.
void
elf_symbol::add_common_instance(const elf_symbol_sptr& common)
{
  if (!common)
    return;

  ABG_ASSERT(!common->has_other_common_instances());
  ABG_ASSERT(is_common_symbol());
  ABG_ASSERT(is_main_symbol());

  if (has_other_common_instances())
    {
      elf_symbol_sptr last_common_instance;
      for (elf_symbol_sptr c = get_next_common_instance();
	   c && (c.get() != get_main_symbol().get());
	   c = c->get_next_common_instance())
	{
	  if (c->get_next_common_instance().get() == get_main_symbol().get())
	    {
	      ABG_ASSERT(last_common_instance == 0);
	      last_common_instance = c;
	    }
	}
      ABG_ASSERT(last_common_instance);

      last_common_instance->priv_->next_common_instance_ = common;
    }
  else
    priv_->next_common_instance_ = common;

  common->priv_->next_common_instance_ = get_main_symbol();
  common->priv_->main_symbol_ = get_main_symbol();
}

/// Get a string that is representative of a given elf_symbol.
///
/// If the symbol has a version, then the ID string is the
/// concatenation of the name of the symbol, the '@' character, and
/// the version of the symbol.  If the version is the default version
/// of the symbol then the '@' character is replaced by a "@@" string.
///
/// Otherwise, if the symbol does not have any version, this function
/// returns the name of the symbol.
///
/// @return a the ID string.
const string&
elf_symbol::get_id_string() const
{
  if (priv_->id_string_.empty())
    {
      string s = get_name ();

      if (!get_version().is_empty())
	{
	  if (get_version().is_default())
	    s += "@@";
	  else
	    s += "@";
	  s += get_version().str();
	}
      priv_->id_string_ = s;
    }

  return priv_->id_string_;
}

/// From the aliases of the current symbol, lookup one with a given name.
///
/// @param name the name of symbol alias we are looking for.
///
/// @return the symbol alias that has the name @p name, or nil if none
/// has been found.
elf_symbol_sptr
elf_symbol::get_alias_from_name(const string& name) const
{
  if (name == get_name())
    return elf_symbol_sptr(priv_->main_symbol_);

   for (elf_symbol_sptr a = get_next_alias();
	a && a.get() != get_main_symbol().get();
	a = a->get_next_alias())
     if (a->get_name() == name)
       return a;

   return elf_symbol_sptr();
}

/// In the list of aliases of a given elf symbol, get the alias that
/// equals this current symbol.
///
/// @param other the elf symbol to get the potential aliases from.
///
/// @return the alias of @p other that texually equals the current
/// symbol, or nil if no alias textually equals the current symbol.
elf_symbol_sptr
elf_symbol::get_alias_which_equals(const elf_symbol& other) const
{
  for (elf_symbol_sptr a = other.get_next_alias();
       a && a.get() != a->get_main_symbol().get();
       a = a->get_next_alias())
    if (textually_equals(*this, *a))
      return a;
  return elf_symbol_sptr();
}

/// Return a comma separated list of the id of the current symbol as
/// well as the id string of its aliases.
///
/// @param syms a map of all the symbols of the corpus the current
/// symbol belongs to.
///
/// @param include_symbol_itself if set to true, then the name of the
/// current symbol is included in the list of alias names that is emitted.
///
/// @return the string.
string
elf_symbol::get_aliases_id_string(const string_elf_symbols_map_type& syms,
				  bool include_symbol_itself) const
{
  string result;

  if (include_symbol_itself)
      result = get_id_string();

  vector<elf_symbol_sptr> aliases;
  compute_aliases_for_elf_symbol(*this, syms, aliases);
  if (!aliases.empty() && include_symbol_itself)
    result += ", ";

  for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
       i != aliases.end();
       ++i)
    {
      if (i != aliases.begin())
	result += ", ";
      result += (*i)->get_id_string();
    }
  return result;
}

/// Return a comma separated list of the id of the current symbol as
/// well as the id string of its aliases.
///
/// @param include_symbol_itself if set to true, then the name of the
/// current symbol is included in the list of alias names that is emitted.
///
/// @return the string.
string
elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
{
  vector<elf_symbol_sptr> aliases;
  if (include_symbol_itself)
    aliases.push_back(get_main_symbol());

  for (elf_symbol_sptr a = get_next_alias();
       a && a.get() != get_main_symbol().get();
       a = a->get_next_alias())
    aliases.push_back(a);

  string result;
  for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
       i != aliases.end();
       ++i)
    {
      if (i != aliases.begin())
	result += ", ";
      result += (*i)->get_id_string();
    }

  return result;
}

/// Given the ID of a symbol, get the name and the version of said
/// symbol.
///
/// @param id the symbol ID to consider.
///
/// @param name the symbol name extracted from the ID.  This is set
/// only if the function returned true.
///
/// @param ver the symbol version extracted from the ID.
bool
elf_symbol::get_name_and_version_from_id(const string&	id,
					 string&	name,
					 string&	ver)
{
  name.clear(), ver.clear();

  string::size_type i = id.find('@');
  if (i == string::npos)
    {
      name = id;
      return true;
    }

  name = id.substr(0, i);
  ++i;

  if (i >= id.size())
    return true;

  string::size_type j = id.find('@', i);
  if (j == string::npos)
    j = i;
  else
    ++j;

  if (j >= id.size())
    {
      ver = "";
      return true;
    }

  ver = id.substr(j);
  return true;
}

///@}

/// Test if two main symbols are textually equal, or, if they have
/// aliases that are textually equal.
///
/// @param other the symbol to compare against.
///
/// @return true iff the current instance of elf symbol equals the @p
/// other.
bool
elf_symbol::operator==(const elf_symbol& other) const
{
  bool are_equal = textually_equals(*this, other);
  if (!are_equal)
    are_equal = bool(get_alias_which_equals(other));
  return are_equal;
}

/// Test if the current symbol aliases another one.
///
/// @param o the other symbol to test against.
///
/// @return true iff the current symbol aliases @p o.
bool
elf_symbol::does_alias(const elf_symbol& o) const
{
  if (*this == o)
    return true;

  if (get_main_symbol() == o.get_main_symbol())
    return true;

  for (elf_symbol_sptr a = get_next_alias();
       a && !a->is_main_symbol();
       a = a->get_next_alias())
    {
      if (o == *a)
	return true;
    }
  return false;
}

/// Equality operator for smart pointers to elf_symbol.
///
/// @param lhs the first elf symbol to consider.
///
/// @param rhs the second elf symbol to consider.
///
/// @return true iff @p lhs equals @p rhs.
bool
operator==(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs)
{
  if (!!lhs != !!rhs)
    return false;

  if (!lhs)
    return true;

  return *lhs == *rhs;
}

/// Inequality operator for smart pointers to elf_symbol.
///
/// @param lhs the first elf symbol to consider.
///
/// @param rhs the second elf symbol to consider.
///
/// @return true iff @p lhs is different from @p rhs.
bool
operator!=(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs)
{return !operator==(lhs, rhs);}

/// Test if two symbols alias.
///
/// @param s1 the first symbol to consider.
///
/// @param s2 the second symbol to consider.
///
/// @return true if @p s1 aliases @p s2.
bool
elf_symbols_alias(const elf_symbol& s1, const elf_symbol& s2)
{return s1.does_alias(s2) || s2.does_alias(s1);}

void
compute_aliases_for_elf_symbol(const elf_symbol& sym,
			       const string_elf_symbols_map_type& symtab,
			       vector<elf_symbol_sptr>& aliases)
{

  if (elf_symbol_sptr a = sym.get_next_alias())
    for (; a && !a->is_main_symbol(); a = a->get_next_alias())
      aliases.push_back(a);
  else
    for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
	 i != symtab.end();
	 ++i)
      for (elf_symbols::const_iterator j = i->second.begin();
	   j != i->second.end();
	   ++j)
	{
	  if (**j == sym)
	    for (elf_symbol_sptr s = (*j)->get_next_alias();
		 s && !s->is_main_symbol();
		 s = s->get_next_alias())
	      aliases.push_back(s);
	  else
	    for (elf_symbol_sptr s = (*j)->get_next_alias();
		 s && !s->is_main_symbol();
		 s = s->get_next_alias())
	      if (*s == sym)
		aliases.push_back(*j);
	}
}

/// Test if two symbols alias.
///
/// @param s1 the first symbol to consider.
///
/// @param s2 the second symbol to consider.
///
/// @return true if @p s1 aliases @p s2.
bool
elf_symbols_alias(const elf_symbol* s1, const elf_symbol* s2)
{
  if (!!s1 != !!s2)
    return false;
  if (s1 == s2)
    return true;
  return elf_symbols_alias(*s1, *s2);
}

/// Test if two symbols alias.
///
/// @param s1 the first symbol to consider.
///
/// @param s2 the second symbol to consider.
///
/// @return true if @p s1 aliases @p s2.
bool
elf_symbols_alias(const elf_symbol_sptr s1, const elf_symbol_sptr s2)
{return elf_symbols_alias(s1.get(), s2.get());}

/// Serialize an instance of @ref symbol_type and stream it to a given
/// output stream.
///
/// @param o the output stream to serialize the symbole type to.
///
/// @param t the symbol type to serialize.
std::ostream&
operator<<(std::ostream& o, elf_symbol::type t)
{
  string repr;

  switch (t)
    {
    case elf_symbol::NOTYPE_TYPE:
      repr = "unspecified symbol type";
      break;
    case elf_symbol::OBJECT_TYPE:
      repr = "variable symbol type";
      break;
    case elf_symbol::FUNC_TYPE:
      repr = "function symbol type";
      break;
    case elf_symbol::SECTION_TYPE:
      repr = "section symbol type";
      break;
    case elf_symbol::FILE_TYPE:
      repr = "file symbol type";
      break;
    case elf_symbol::COMMON_TYPE:
      repr = "common data object symbol type";
      break;
    case elf_symbol::TLS_TYPE:
      repr = "thread local data object symbol type";
      break;
    case elf_symbol::GNU_IFUNC_TYPE:
      repr = "indirect function symbol type";
      break;
    default:
      {
	std::ostringstream s;
	s << "unknown symbol type (" << (char)t << ')';
	repr = s.str();
      }
      break;
    }

  o << repr;
  return o;
}

/// Serialize an instance of @ref symbol_binding and stream it to a
/// given output stream.
///
/// @param o the output stream to serialize the symbole type to.
///
/// @param b the symbol binding to serialize.
std::ostream&
operator<<(std::ostream& o, elf_symbol::binding b)
{
  string repr;

  switch (b)
    {
    case elf_symbol::LOCAL_BINDING:
      repr = "local binding";
      break;
    case elf_symbol::GLOBAL_BINDING:
      repr = "global binding";
      break;
    case elf_symbol::WEAK_BINDING:
      repr = "weak binding";
      break;
    case elf_symbol::GNU_UNIQUE_BINDING:
      repr = "GNU unique binding";
      break;
    default:
      {
	std::ostringstream s;
	s << "unknown binding (" << (unsigned char) b << ")";
	repr = s.str();
      }
      break;
    }

  o << repr;
  return o;
}

/// Serialize an instance of @ref elf_symbol::visibility and stream it
/// to a given output stream.
///
/// @param o the output stream to serialize the symbole type to.
///
/// @param v the symbol visibility to serialize.
std::ostream&
operator<<(std::ostream& o, elf_symbol::visibility v)
{
  string repr;

  switch (v)
    {
    case elf_symbol::DEFAULT_VISIBILITY:
      repr = "default visibility";
      break;
    case elf_symbol::PROTECTED_VISIBILITY:
      repr = "protected visibility";
      break;
    case elf_symbol::HIDDEN_VISIBILITY:
      repr = "hidden visibility";
      break;
    case elf_symbol::INTERNAL_VISIBILITY:
      repr = "internal visibility";
      break;
    default:
      {
	std::ostringstream s;
	s << "unknown visibility (" << (unsigned char) v << ")";
	repr = s.str();
      }
      break;
    }

  o << repr;
  return o;
}

/// Convert a string representing a symbol type into an
/// elf_symbol::type.
///
///@param s the string to convert.
///
///@param t the resulting elf_symbol::type.
///
/// @return true iff the conversion completed successfully.
bool
string_to_elf_symbol_type(const string& s, elf_symbol::type& t)
{
  if (s == "no-type")
    t = elf_symbol::NOTYPE_TYPE;
  else if (s == "object-type")
    t = elf_symbol::OBJECT_TYPE;
  else if (s == "func-type")
    t = elf_symbol::FUNC_TYPE;
  else if (s == "section-type")
    t = elf_symbol::SECTION_TYPE;
  else if (s == "file-type")
    t = elf_symbol::FILE_TYPE;
  else if (s == "common-type")
    t = elf_symbol::COMMON_TYPE;
  else if (s == "tls-type")
    t = elf_symbol::TLS_TYPE;
  else if (s == "gnu-ifunc-type")
    t = elf_symbol::GNU_IFUNC_TYPE;
  else
    return false;

  return true;
}

/// Convert a string representing a an elf symbol binding into an
/// elf_symbol::binding.
///
/// @param s the string to convert.
///
/// @param b the resulting elf_symbol::binding.
///
/// @return true iff the conversion completed successfully.
bool
string_to_elf_symbol_binding(const string& s, elf_symbol::binding& b)
{
    if (s == "local-binding")
      b = elf_symbol::LOCAL_BINDING;
    else if (s == "global-binding")
      b = elf_symbol::GLOBAL_BINDING;
    else if (s == "weak-binding")
      b = elf_symbol::WEAK_BINDING;
    else if (s == "gnu-unique-binding")
      b = elf_symbol::GNU_UNIQUE_BINDING;
    else
      return false;

    return true;
}

/// Convert a string representing a an elf symbol visibility into an
/// elf_symbol::visibility.
///
/// @param s the string to convert.
///
/// @param b the resulting elf_symbol::visibility.
///
/// @return true iff the conversion completed successfully.
bool
string_to_elf_symbol_visibility(const string& s, elf_symbol::visibility& v)
{
  if (s == "default-visibility")
    v = elf_symbol::DEFAULT_VISIBILITY;
  else if (s == "protected-visibility")
    v = elf_symbol::PROTECTED_VISIBILITY;
  else if (s == "hidden-visibility")
    v = elf_symbol::HIDDEN_VISIBILITY;
  else if (s == "internal-visibility")
    v = elf_symbol::INTERNAL_VISIBILITY;
  else
    return false;

  return true;
}

/// Test if the type of an ELF symbol denotes a function symbol.
///
/// @param t the type of the ELF symbol.
///
/// @return true iff elf symbol type @p t denotes a function symbol
/// type.
bool
elf_symbol_is_function(elf_symbol::type t)
{return t == elf_symbol::FUNC_TYPE;}

/// Test if the type of an ELF symbol denotes a function symbol.
///
/// @param t the type of the ELF symbol.
///
/// @return true iff elf symbol type @p t denotes a function symbol
/// type.
bool
elf_symbol_is_variable(elf_symbol::type t)
{return t == elf_symbol::OBJECT_TYPE;}

// <elf_symbol::version stuff>

struct elf_symbol::version::priv
{
  string	version_;
  bool		is_default_;

  priv()
    : is_default_(false)
  {}

  priv(const string& v,
       bool d)
    : version_(v),
      is_default_(d)
  {}
}; // end struct elf_symbol::version::priv

elf_symbol::version::version()
  : priv_(new priv)
{}

/// @param v the name of the version.
///
/// @param is_default true if this is a default version.
elf_symbol::version::version(const string& v,
			     bool is_default)
  : priv_(new priv(v, is_default))
{}

elf_symbol::version::version(const elf_symbol::version& v)
  : priv_(new priv(v.str(), v.is_default()))
{
}

elf_symbol::version::~version() = default;

/// Cast the version_type into a string that is its name.
///
/// @return the name of the version.
elf_symbol::version::operator const string&() const
{return priv_->version_;}

/// Getter for the version name.
///
/// @return the version name.
const string&
elf_symbol::version::str() const
{return priv_->version_;}

/// Setter for the version name.
///
/// @param s the version name.
void
elf_symbol::version::str(const string& s)
{priv_->version_ = s;}

/// Getter for the 'is_default' property of the version.
///
/// @return true iff this is a default version.
bool
elf_symbol::version::is_default() const
{return priv_->is_default_;}

/// Setter for the 'is_default' property of the version.
///
/// @param f true if this is the default version.
void
elf_symbol::version::is_default(bool f)
{priv_->is_default_ = f;}

bool
elf_symbol::version::is_empty() const
{return str().empty();}

/// Compares the current version against another one.
///
/// @param o the other version to compare the current one to.
///
/// @return true iff the current version equals @p o.
bool
elf_symbol::version::operator==(const elf_symbol::version& o) const
{return str() == o.str();}

/// Inequality operator.
///
/// @param o the version to compare against the current one.
///
/// @return true iff both versions are different.
bool
elf_symbol::version::operator!=(const version& o) const
{return !operator==(o);}

/// Assign a version to the current one.
///
/// @param o the other version to assign to this one.
///
/// @return a reference to the assigned version.
elf_symbol::version&
elf_symbol::version::operator=(const elf_symbol::version& o)
{
  str(o.str());
  is_default(o.is_default());
  return *this;
}

// </elf_symbol::version stuff>

// </elf_symbol stuff>

// <class dm_context_rel stuff>
struct dm_context_rel::priv
{
  bool is_laid_out_;
  size_t offset_in_bits_;
  var_decl* anonymous_data_member_;

  priv(bool is_static = false)
    : is_laid_out_(!is_static),
      offset_in_bits_(0),
      anonymous_data_member_()
  {}

  priv(bool is_laid_out, size_t offset_in_bits)
    : is_laid_out_(is_laid_out),
      offset_in_bits_(offset_in_bits),
      anonymous_data_member_()
  {}
}; //end struct dm_context_rel::priv

dm_context_rel::dm_context_rel()
  : context_rel(),
    priv_(new priv)
{}

dm_context_rel::dm_context_rel(scope_decl* s,
			       bool is_laid_out,
			       size_t offset_in_bits,
			       access_specifier a,
			       bool is_static)
  : context_rel(s, a, is_static),
    priv_(new priv(is_laid_out, offset_in_bits))
{}

dm_context_rel::dm_context_rel(scope_decl* s)
  : context_rel(s),
    priv_(new priv())
{}

bool
dm_context_rel::get_is_laid_out() const
{return priv_->is_laid_out_;}

void
dm_context_rel::set_is_laid_out(bool f)
{priv_->is_laid_out_ = f;}

size_t
dm_context_rel::get_offset_in_bits() const
{return priv_->offset_in_bits_;}

void
dm_context_rel::set_offset_in_bits(size_t o)
{priv_->offset_in_bits_ = o;}

bool
dm_context_rel::operator==(const dm_context_rel& o) const
{
  if (!context_rel::operator==(o))
    return false;

  return (priv_->is_laid_out_ == o.priv_->is_laid_out_
	    && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
}

bool
dm_context_rel::operator!=(const dm_context_rel& o) const
{return !operator==(o);}

/// Return a non-nil value if this data member context relationship
/// has an anonymous data member.  That means, if the data member this
/// relation belongs to is part of an anonymous data member.
///
/// @return the containing anonymous data member of this data member
/// relationship.  Nil if there is none.
const var_decl*
dm_context_rel::get_anonymous_data_member() const
{return priv_->anonymous_data_member_;}

/// Set the containing anonymous data member of this data member
/// context relationship. That means that the data member this
/// relation belongs to is part of an anonymous data member.
///
/// @param anon_dm the containing anonymous data member of this data
/// member relationship.  Nil if there is none.
void
dm_context_rel::set_anonymous_data_member(var_decl* anon_dm)
{priv_->anonymous_data_member_ = anon_dm;}

dm_context_rel::~dm_context_rel()
{}
// </class dm_context_rel stuff>

// <environment stuff>

/// Convenience typedef for a map of interned_string -> bool.
typedef unordered_map<interned_string,
		      bool, hash_interned_string> interned_string_bool_map_type;


/// Default constructor of the @ref environment type.
environment::environment()
  :priv_(new priv)
{}

/// Destructor for the @ref environment type.
environment::~environment()
{}

/// Getter the map of canonical types.
///
/// @return the map of canonical types.  The key of the map is the
/// hash of the canonical type and its value if the canonical type.
environment::canonical_types_map_type&
environment::get_canonical_types_map()
{return priv_->canonical_types_;}

/// Getter the map of canonical types.
///
/// @return the map of canonical types.  The key of the map is the
/// hash of the canonical type and its value if the canonical type.
const environment::canonical_types_map_type&
environment::get_canonical_types_map() const
{return const_cast<environment*>(this)->get_canonical_types_map();}

/// Helper to detect if a type is either a reference, a pointer, or a
/// qualified type.
static bool
is_ptr_ref_or_qual_type(const type_base *t)
{
  if (is_pointer_type(t)
      || is_reference_type(t)
      || is_qualified_type(t))
    return true;
  return false;
}

/// A functor to sort decls somewhat topologically.  That is, types
/// are sorted in a way that makes the ones that are defined "first"
/// to come first.
///
/// The topological criteria is a lexicographic sort of the definition
/// location of the type.  For types that have no location (or the
/// same location), it's their qualified name that is used for the
/// lexicographic sort.
struct decl_topo_comp
{

  /// The "Less Than" comparison operator of this functor.
  ///
  /// @param f the first decl to be considered for the comparison.
  ///
  /// @param s the second decl to be considered for the comparison.
  ///
  /// @return true iff @p f is less than @p s.
  bool
  operator()(const decl_base *f,
	     const decl_base *s)
  {
    if (!!f != !!s)
      return f && !s;

    if (!f)
      return false;

    // If a decl has artificial location, then use that one over the
    // natural one.
    location fl = get_artificial_or_natural_location(f);
    location sl = get_artificial_or_natural_location(s);

    if (fl.get_value() && sl.get_value())
      {
	if (fl.get_is_artificial() == sl.get_is_artificial())
	  {
	    // The locations of the two artfifacts have the same
	    // artificial-ness so they can be compared.
	    string p1, p2;
	    unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
	    fl.expand(p1, l1, c1);
	    sl.expand(p2, l2, c2);
	    if (p1 != p2)
	      return p1 < p2;
	    if (l1 != l2)
	      return l1 < l2;
	    if (c1 != c2)
	      return c1 < c2;
	  }
      }
    else if (!!fl != !!sl)
      // So one of the decls doesn't have location data.
      // The first decl is less than the second if it's the one not
      // having location data.
      return !fl && sl;

    // We reach this point if location data is useless.
    return (get_pretty_representation(f, true)
	    < get_pretty_representation(s, true));
  }

  /// The "Less Than" comparison operator of this functor.
  ///
  /// @param f the first decl to be considered for the comparison.
  ///
  /// @param s the second decl to be considered for the comparison.
  ///
  /// @return true iff @p f is less than @p s.
  bool
  operator()(const decl_base_sptr &f,
	     const decl_base_sptr &s)
  {return operator()(f.get(), s.get());}

}; // end struct decl_topo_comp

/// A functor to sort types somewhat topologically.  That is, types
/// are sorted in a way that makes the ones that are defined "first"
/// to come first.
///
/// The topological criteria is a lexicographic sort of the definition
/// location of the type.  For types that have no location, it's their
/// qualified name that is used for the lexicographic sort.
struct type_topo_comp
{
  /// The "Less Than" comparison operator of this functor.
  ///
  /// @param f the first type to be considered for the comparison.
  ///
  /// @param s the second type to be considered for the comparison.
  ///
  /// @return true iff @p f is less than @p s.
  bool
  operator()(const type_base_sptr &f,
	     const type_base_sptr &s)
  {return operator()(f.get(), s.get());}

  /// The "Less Than" comparison operator of this functor.
  ///
  /// @param f the first type to be considered for the comparison.
  ///
  /// @param s the second type to be considered for the comparison.
  ///
  /// @return true iff @p f is less than @p s.
  bool
  operator()(const type_base *f,
	     const type_base *s)
  {
    bool f_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(f);
    bool s_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(s);

    if (f_is_ptr_ref_or_qual != s_is_ptr_ref_or_qual)
      return !f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual;

    if (f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual
	&& !is_decl(f)->get_location() && !is_decl(s)->get_location())
      {
	string s1 = get_pretty_representation(f, true);
	string s2 = get_pretty_representation(s, true);
	if (s1 == s2)
	  if (qualified_type_def * q = is_qualified_type(f))
	    if (q->get_cv_quals() == qualified_type_def::CV_NONE)
	      if (!is_qualified_type(s))
		// We are looking at two types that are the result of
		// an optimization that happens during the IR
		// construction.  Namely, type f is a cv-qualified
		// type with no qualifier (no const, no volatile, no
		// nothing, we call it an empty-qualified type).
		// These are the result of an optimization which
		// removes "redundant qualifiers" from some types.
		// For instance, consider a "const reference".  The
		// const there is redundant because a reference is
		// always const.  So as a result of the optimizaton
		// that type is going to be transformed into an
		// empty-qualified reference. If we don't make that
		// optimization, then we risk having spurious change
		// reports down the road.  But then, as a consequence
		// of that optimization, we need to sort the
		// empty-qualified type and its non-qualified variant
		// e.g, to ensure stability in the abixml output; both
		// types are logically equal, but here, we decide that
		// the empty-qualified one is topologically "less
		// than" the non-qualified counterpart.
		//
		// So here, type f is an empty-qualified type and type
		// s is its non-qualified variant.  We decide that f
		// is topologically less than s.
		return true;
	return (s1 < s2);
      }

    decl_base *fd = is_decl(f);
    decl_base *sd = is_decl(s);

    if (!!fd != !!sd)
      return fd && !sd;

    if (!fd)
      {
	type_base *peeled_f = peel_pointer_or_reference_type(f);
	type_base *peeled_s = peel_pointer_or_reference_type(s);

	fd = is_decl(peeled_f);
	sd = is_decl(peeled_s);

	if (!!fd != !!sd)
	  return fd && !sd;

	if (!fd)
	  return (get_pretty_representation(f, true)
		  < get_pretty_representation(s, true));
      }

    // From this point, fd and sd should be non-nil
    decl_topo_comp decl_comp;
    return decl_comp(fd, sd);
  }
}; //end struct type_topo_comp

/// Get a @ref type_decl that represents a "void" type for the current
/// environment.
///
/// @return the @ref type_decl that represents a "void" type.
const type_base_sptr&
environment::get_void_type() const
{
  if (!priv_->void_type_)
    priv_->void_type_.reset(new type_decl(const_cast<environment*>(this),
					  intern("void"),
					  0, 0, location()));
  return priv_->void_type_;
}

/// Get a @ref type_decl instance that represents a the type of a
/// variadic function parameter.
///
/// @return the Get a @ref type_decl instance that represents a the
/// type of a variadic function parameter.
const type_base_sptr&
environment::get_variadic_parameter_type() const
{
  if (!priv_->variadic_marker_type_)
    priv_->variadic_marker_type_.
      reset(new type_decl(const_cast<environment*>(this),
			  intern("variadic parameter type"),
			  0, 0, location()));
  return priv_->variadic_marker_type_;
}

/// Test if the canonicalization of types created out of the current
/// environment is done.
///
/// @return true iff the canonicalization of types created out of the current
/// environment is done.
bool
environment::canonicalization_is_done() const
{return priv_->canonicalization_is_done_;}

/// Set a flag saying if the canonicalization of types created out of
/// the current environment is done or not.
///
/// Note that this function must only be called by internal code of
/// the library that creates ABI artifacts (e.g, read an abi corpus
/// from elf or from our own xml format and creates representations of
/// types out of it) and thus needs to canonicalize types to speed-up
/// further type comparison.
///
/// @param f the new value of the flag.
void
environment::canonicalization_is_done(bool f)
{priv_->canonicalization_is_done_ = f;}

/// Getter for the "on-the-fly-canonicalization" flag.
///
/// @return true iff @ref OnTheFlyCanonicalization
/// "on-the-fly-canonicalization" is to be performed during
/// comparison.
bool
environment::do_on_the_fly_canonicalization() const
{return priv_->do_on_the_fly_canonicalization_;}

/// Setter for the "on-the-fly-canonicalization" flag.
///
/// @param f If this is true then @ref OnTheFlyCanonicalization
/// "on-the-fly-canonicalization" is to be performed during
/// comparison.
void
environment::do_on_the_fly_canonicalization(bool f)
{priv_->do_on_the_fly_canonicalization_ = f;}

/// Getter of the "decl-only-class-equals-definition" flag.
///
/// Usually, a declaration-only class named 'struct foo' compares
/// equal to any class definition named "struct foo'.  This is at
/// least true for C++.
///
/// In C, though, because there can be multiple definitions of 'struct
/// foo' in the binary, a declaration-only "struct foo" might be
/// considered to *NOT* resolve to any of the struct foo defined.  In
/// that case, the declaration-only "struct foo" is considered
/// different from the definitions.
///
/// This flag controls the behaviour of the comparison of an
/// unresolved decl-only class against a definition of the same name.
///
/// If set to false, the the declaration equals the definition.  If
/// set to false, then the decalration is considered different from
/// the declaration.
///
/// @return the value of the "decl-only-class-equals-definition" flag.
bool
environment::decl_only_class_equals_definition() const
{return priv_->decl_only_class_equals_definition_;}

/// Setter of the "decl-only-class-equals-definition" flag.
///
/// Usually, a declaration-only class named 'struct foo' compares
/// equal to any class definition named "struct foo'.  This is at
/// least true for C++.
///
/// In C, though, because there can be multiple definitions of 'struct
/// foo' in the binary, a declaration-only "struct foo" might be
/// considered to *NOT* resolve to any of the struct foo defined.  In
/// that case, the declaration-only "struct foo" is considered
/// different from the definitions.
///
/// This flag controls the behaviour of the comparison of an
/// unresolved decl-only class against a definition of the same name.
///
/// If set to false, the the declaration equals the definition.  If
/// set to false, then the decalration is considered different from
/// the declaration.
///
/// @param the new value of the "decl-only-class-equals-definition"
/// flag.
void
environment::decl_only_class_equals_definition(bool f) const
{priv_->decl_only_class_equals_definition_ = f;}

/// Test if a given type is a void type as defined in the current
/// environment.
///
/// @param t the type to consider.
///
/// @return true iff @p t is a void type as defined in the current
/// environment.
bool
environment::is_void_type(const type_base_sptr& t) const
{
  if (!t)
    return false;
  return t.get() == get_void_type().get();
}

/// Test if a given type is a void type as defined in the current
/// environment.
///
/// @param t the type to consider.
///
/// @return true iff @p t is a void type as defined in the current
/// environment.
bool
environment::is_void_type(const type_base* t) const
{
  if (!t)
    return false;
  return t == get_void_type().get();
}

/// Test if a type is a variadic parameter type as defined in the
/// current environment.
///
/// @param t the type to consider.
///
/// @return true iff @p t is a variadic parameter type as defined in
/// the current environment.
bool
environment::is_variadic_parameter_type(const type_base* t) const
{
  if (!t)
    return false;
  return t == get_variadic_parameter_type().get();
}

/// Test if a type is a variadic parameter type as defined in the
/// current environment.
///
/// @param t the type to consider.
///
/// @return true iff @p t is a variadic parameter type as defined in
/// the current environment.
bool
environment::is_variadic_parameter_type(const type_base_sptr& t) const
{return is_variadic_parameter_type(t.get());}

/// Do intern a string.
///
/// If a value of this string already exists in the interned string
/// pool of the current environment, then this function returns a new
/// interned_string pointing to that already existing string.
/// Otherwise, a new string is created, stored in the interned string
/// pool and a new interned_string instance is created to point to
/// that new intrerned string, and it's return.
///
/// @param s the value of the string to intern.
///
/// @return the interned string.
interned_string
environment::intern(const string& s) const
{return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}

/// Getter of the general configuration object.
///
/// @return the configuration object.
const config&
environment::get_config() const
{return priv_->config_;}

#ifdef WITH_DEBUG_SELF_COMPARISON
/// Setter of the corpus of the input corpus of the self comparison
/// that takes place when doing "abidw --debug-abidiff <binary>".
///
/// The first invocation of this function sets the first corpus of the
/// self comparison.  The second invocation of this very same function
/// sets the second corpus of the self comparison.  That second corpus
/// is supposed to come from the abixml serialization of the first
/// corpus.
///
/// @param c the corpus of the input binary or the corpus of the
/// abixml serialization of the initial binary input.
void
environment::set_self_comparison_debug_input(const corpus_sptr& c)
{
  self_comparison_debug_is_on(true);
  if (priv_->first_self_comparison_corpus_.expired())
    priv_->first_self_comparison_corpus_ = c;
  else if (priv_->second_self_comparison_corpus_.expired()
	   && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
    priv_->second_self_comparison_corpus_ = c;
}

/// Getter for the corpora of the input binary and the intermediate
/// abixml of the self comparison that takes place when doing
///   'abidw --debug-abidiff <binary>'.
///
/// @param first_corpus output parameter that is set to the corpus of
/// the input corpus.
///
/// @param second_corpus output parameter that is set to the corpus of
/// the second corpus.
void
environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
					      corpus_sptr& second_corpus)
{
    first_corpus = priv_->first_self_comparison_corpus_.lock();
    second_corpus = priv_->second_self_comparison_corpus_.lock();
}

/// Turn on/off the self comparison debug mode.
///
/// @param f true iff the self comparison debug mode is turned on.
void
environment::self_comparison_debug_is_on(bool f)
{priv_->self_comparison_debug_on_ = f;}

/// Test if we are in the process of the 'self-comparison
/// debugging' as triggered by 'abidw --debug-abidiff' command.
///
/// @return true if self comparison debug is on.
bool
environment::self_comparison_debug_is_on() const
{return priv_->self_comparison_debug_on_;}
#endif

#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
/// Set the "type canonicalization debugging" mode, triggered by using
/// the command: "abidw --debug-tc".
///
/// @param flag if true then the type canonicalization debugging mode
/// is enabled.
void
environment::debug_type_canonicalization_is_on(bool flag)
{priv_->debug_type_canonicalization_ = flag;}

/// Getter of the "type canonicalization debugging" mode, triggered by
/// using the command: "abidw --debug-tc".
///
/// @return true iff the type canonicalization debugging mode is
/// enabled.
bool
environment::debug_type_canonicalization_is_on() const
{return priv_->debug_type_canonicalization_;}
#endif // WITH_DEBUG_TYPE_CANONICALIZATION

/// Get the vector of canonical types which have a given "string
/// representation".
///
/// @param 'name', the textual representation of the type as returned
/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
///                                                 /*qualified=*/true)
///
/// This is useful to for debugging purposes as it's handy to use from
/// inside a debugger like GDB.
///
/// @return a pointer to the vector of canonical types having the
/// representation @p name, or nullptr if no type with that
/// representation exists.
vector<type_base_sptr>*
environment::get_canonical_types(const char* name)
{
  auto ti = get_canonical_types_map().find(name);
  if (ti == get_canonical_types_map().end())
    return nullptr;
  return &ti->second;
}

/// Get a given canonical type which has a given "string
/// representation".
///
/// @param 'name', the textual representation of the type as returned
/// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
///                                                 /*qualified=*/true).
///
/// @param index, the index of the type in the vector of types that
/// all have the same textual representation @p 'name'.  That vector
/// is returned by the function environment::get_canonical_types().
///
/// @return the canonical type which has the representation @p name,
/// and which is at index @p index in the vector of canonical types
/// having that same textual representation.
type_base*
environment::get_canonical_type(const char* name, unsigned index)
{
  vector<type_base_sptr> *types = get_canonical_types(name);
  if (!types ||index >= types->size())
    return nullptr;
  return (*types)[index].get();
}

#ifdef WITH_DEBUG_SELF_COMPARISON
/// Get the set of abixml type-id and the pointer value of the
/// (canonical) type it's associated to.
///
/// This is useful for debugging purposes, especially in the context
/// of the use of the command:
///   'abidw --debug-abidiff <binary>'.
///
/// @return the set of abixml type-id and the pointer value of the
/// (canonical) type it's associated to.
unordered_map<string, uintptr_t>&
environment::get_type_id_canonical_type_map() const
{return priv_->type_id_canonical_type_map_;}

/// Getter of the map that associates the values of type pointers to
/// their type-id strings.
///
/// Note that this map is populated at abixml reading time, (by
/// build_type()) when a given XML element representing a type is
/// read into a corresponding abigail::ir::type_base.
///
/// This is used only for the purpose of debugging the
/// self-comparison process.  That is, when invoking "abidw
/// --debug-abidiff".
///
/// @return the map that associates the values of type pointers to
/// their type-id strings.
unordered_map<uintptr_t, string>&
environment::get_pointer_type_id_map()
{return priv_->pointer_type_id_map_;}

/// Getter of the type-id that corresponds to the value of a pointer
/// to abigail::ir::type_base that was created from the abixml reader.
///
/// That value is retrieved from the map returned from
/// environment::get_pointer_type_id_map().
///
/// That map is populated at abixml reading time, (by build_type())
/// when a given XML element representing a type is read into a
/// corresponding abigail::ir::type_base.
///
/// This is used only for the purpose of debugging the
/// self-comparison process.  That is, when invoking "abidw
/// --debug-abidiff".
///
/// @return the type-id strings that corresponds
string
environment::get_type_id_from_pointer(uintptr_t ptr)
{
  auto it = get_pointer_type_id_map().find(ptr);
  if (it != get_pointer_type_id_map().end())
    return it->second;
  return "";
}

/// Getter of the canonical type of the artifact designated by a
/// type-id.
///
/// That type-id was generated by the abixml writer at the emitting
/// time of the abixml file.  The corresponding canonical type was
/// stored in the map returned by
/// environment::get_type_id_canonical_type_map().
///
/// This is useful for debugging purposes, especially in the context
/// of the use of the command:
///   'abidw --debug-abidiff <binary>'.
///
/// @return the set of abixml type-id and the pointer value of the
/// (canonical) type it's associated to.
uintptr_t
environment::get_canonical_type_from_type_id(const char* type_id)
{
  if (!type_id)
    return 0;
  auto it = get_type_id_canonical_type_map().find(type_id);
  if (it != get_type_id_canonical_type_map().end())
    return it->second;
  return 0;
}
#endif
// </environment stuff>

// <type_or_decl_base stuff>

/// The private data of @ref type_or_decl_base.
struct type_or_decl_base::priv
{
  // This holds the kind of dynamic type of particular instance.
  // Yes, this is part of the implementation of a "poor man" runtime
  // type identification.  We are doing this because profiling shows
  // that using dynamic_cast in some places is really to slow and is
  // constituting a hotspot.  This poor man's implementation made
  // things be much faster.
  enum type_or_decl_kind	kind_;
  // This holds the runtime type instance pointer of particular
  // instance.  In other words, this is the "this pointer" of the
  // dynamic type of a particular instance.
  void*			rtti_;
  // This holds a pointer to either the type_base sub-object (if the
  // current instance is a type) or the decl_base sub-object (if the
  // current instance is a decl).  This is used by the is_decl() and
  // is_type() functions, which also show up during profiling as
  // hotspots, due to their use of dynamic_cast.
  void*			type_or_decl_ptr_;
  bool				hashing_started_;
  const environment*		env_;
  translation_unit*		translation_unit_;
  // The location of an artifact as seen from its input by the
  // artifact reader.  This might be different from the source
  // location advertised by the original emitter of the artifact
  // emitter.
  location			artificial_location_;
  // Flags if the current ABI artifact is artificial (i.e, *NOT*
  // generated from the initial source code, but rather either
  // artificially by the compiler or by libabigail itself).
  bool				is_artificial_;

  /// Constructor of the type_or_decl_base::priv private type.
  ///
  /// @param e the environment in which the ABI artifact was created.
  ///
  /// @param k the identifier of the runtime type of the current
  /// instance of ABI artifact.
  priv(const environment* e = 0,
       enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL)
    : kind_(k),
      rtti_(),
      type_or_decl_ptr_(),
      hashing_started_(),
      env_(e),
      translation_unit_(),
      is_artificial_()
  {}

  enum type_or_decl_kind
  kind() const
  {return kind_;}

  void
  kind (enum type_or_decl_kind k)
  {kind_ |= k;}
}; // end struct type_or_decl_base::priv

/// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
/// bitmap type.
type_or_decl_base::type_or_decl_kind
operator|(type_or_decl_base::type_or_decl_kind l,
	  type_or_decl_base::type_or_decl_kind r)
{
  return static_cast<type_or_decl_base::type_or_decl_kind>
    (static_cast<unsigned>(l) | static_cast<unsigned>(r));
}

/// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
/// bitmap type.
type_or_decl_base::type_or_decl_kind&
operator|=(type_or_decl_base::type_or_decl_kind& l,
	   type_or_decl_base::type_or_decl_kind r)
{
  l = l | r;
  return l;
}

/// bitwise "AND" operator for the
/// type_or_decl_base::type_or_decl_kind bitmap type.
type_or_decl_base::type_or_decl_kind
operator&(type_or_decl_base::type_or_decl_kind l,
	  type_or_decl_base::type_or_decl_kind r)
{
  return static_cast<type_or_decl_base::type_or_decl_kind>
    (static_cast<unsigned>(l) & static_cast<unsigned>(r));
}

/// bitwise "A&=" operator for the
/// type_or_decl_base::type_or_decl_kind bitmap type.
type_or_decl_base::type_or_decl_kind&
operator&=(type_or_decl_base::type_or_decl_kind& l,
	  type_or_decl_base::type_or_decl_kind r)
{
  l = l & r;
  return l;
}

/// Default constructor of @ref type_or_decl_base.
type_or_decl_base::type_or_decl_base()
  :priv_(new priv)
{}

/// Constructor of @ref type_or_decl_base.
///
/// @param the environment the current ABI artifact is constructed
/// from.
///
/// @param k the runtime identifier bitmap of the type being built.
type_or_decl_base::type_or_decl_base(const environment* e,
				     enum type_or_decl_kind k)
  :priv_(new priv(e, k))
{}

/// Copy constructor of @ref type_or_decl_base.
type_or_decl_base::type_or_decl_base(const type_or_decl_base& o)
{*priv_ = *o.priv_;}

/// The destructor of the @ref type_or_decl_base type.
type_or_decl_base::~type_or_decl_base()
{}

/// Getter of the flag that says if the artefact is artificial.
///
/// Being artificial means it was not explicitely mentionned in the
/// source code, but was rather artificially created by the compiler
/// or libabigail.
///
/// @return true iff the declaration is artificial.
bool
type_or_decl_base::get_is_artificial() const
{return priv_->is_artificial_;}

/// Setter of the flag that says if the artefact is artificial.
///
/// Being artificial means the artefact was not explicitely
/// mentionned in the source code, but was rather artificially created
/// by the compiler or by libabigail.
///
/// @param f the new value of the flag that says if the artefact is
/// artificial.
void
type_or_decl_base::set_is_artificial(bool f)
{priv_->is_artificial_ = f;}

/// Getter for the "kind" property of @ref type_or_decl_base type.
///
/// This property holds the identifier bitmap of the runtime type of
/// an ABI artifact.
///
/// @return the runtime type identifier bitmap of the current ABI
/// artifact.
enum type_or_decl_base::type_or_decl_kind
type_or_decl_base::kind() const
{return priv_->kind();}

/// Setter for the "kind" property of @ref type_or_decl_base type.
///
/// This property holds the identifier bitmap of the runtime type of
/// an ABI artifact.
///
/// @param the runtime type identifier bitmap of the current ABI
/// artifact.
void
type_or_decl_base::kind(enum type_or_decl_kind k)
{priv_->kind(k);}

/// Getter of the pointer to the runtime type sub-object of the
/// current instance.
///
/// @return the pointer to the runtime type sub-object of the current
/// instance.
const void*
type_or_decl_base::runtime_type_instance() const
{return priv_->rtti_;}

/// Getter of the pointer to the runtime type sub-object of the
/// current instance.
///
/// @return the pointer to the runtime type sub-object of the current
/// instance.
void*
type_or_decl_base::runtime_type_instance()
{return priv_->rtti_;}

/// Setter of the pointer to the runtime type sub-object of the
/// current instance.
///
/// @param i the new pointer to the runtime type sub-object of the
/// current instance.
void
type_or_decl_base::runtime_type_instance(void* i)
{
  priv_->rtti_ = i;
  if (type_base* t = dynamic_cast<type_base*>(this))
    priv_->type_or_decl_ptr_ = t;
  else if (decl_base *d = dynamic_cast<decl_base*>(this))
    priv_->type_or_decl_ptr_ = d;
}

/// Getter of the pointer to either the type_base sub-object of the
/// current instance if it's a type, or to the decl_base sub-object of
/// the current instance if it's a decl.
///
/// @return the pointer to either the type_base sub-object of the
/// current instance if it's a type, or to the decl_base sub-object of
/// the current instance if it's a decl.
const void*
type_or_decl_base::type_or_decl_base_pointer() const
{return const_cast<type_or_decl_base*>(this)->type_or_decl_base_pointer();}

/// Getter of the pointer to either the type_base sub-object of the
/// current instance if it's a type, or to the decl_base sub-object of
/// the current instance if it's a decl.
///
/// @return the pointer to either the type_base sub-object of the
/// current instance if it's a type, or to the decl_base sub-object of
/// the current instance if it's a decl.
void*
type_or_decl_base::type_or_decl_base_pointer()
{return priv_->type_or_decl_ptr_;}

/// Getter for the 'hashing_started' property.
///
/// @return the 'hashing_started' property.
bool
type_or_decl_base::hashing_started() const
{return priv_->hashing_started_;}

/// Setter for the 'hashing_started' property.
///
/// @param b the value to set the 'hashing_property' to.
void
type_or_decl_base::hashing_started(bool b) const
{priv_->hashing_started_ = b;}

/// Setter of the environment of the current ABI artifact.
///
/// This just sets the environment artifact of the current ABI
/// artifact, not on its sub-trees.  If you want to set the
/// environment of an ABI artifact including its sub-tree, use the
/// abigail::ir::set_environment_for_artifact() function.
///
/// @param env the new environment.
void
type_or_decl_base::set_environment(const environment* env)
{priv_->env_ = env;}

/// Getter of the environment of the current ABI artifact.
///
/// @return the environment of the artifact.
const environment*
type_or_decl_base::get_environment() const
{return priv_->env_;}

/// Setter of the artificial location of the artificat.
///
/// The artificial location is a location that was artificially
/// generated by libabigail, not generated by the original emitter of
/// the ABI meta-data.  For instance, when reading an XML element from
/// an abixml file, the artificial location is the source location of
/// the XML element within the file, not the value of the
/// 'location'property that might be carried by the element.
///
/// Artificial locations might be useful to ensure that abixml emitted
/// by the abixml writer are sorted the same way as the input abixml
/// read by the reader.
///
/// @param l the new artificial location.
void
type_or_decl_base::set_artificial_location(const location &l)
{priv_->artificial_location_ = l;}

/// Getter of the artificial location of the artifact.
///
/// The artificial location is a location that was artificially
/// generated by libabigail, not generated by the original emitter of
/// the ABI meta-data.  For instance, when reading an XML element from
/// an abixml file, the artificial location is the source location of
/// the XML element within the file, not the value of the
/// 'location'property that might be carried by the element.
///
/// Artificial locations might be useful to ensure that the abixml
/// emitted by the abixml writer is sorted the same way as the input
/// abixml read by the reader.
///
/// @return the new artificial location.
location&
type_or_decl_base::get_artificial_location() const
{return priv_->artificial_location_;}

/// Test if the current ABI artifact carries an artificial location.
///
/// @return true iff the current ABI artifact carries an artificial location.
bool
type_or_decl_base::has_artificial_location() const
{
  return (priv_->artificial_location_
	  && priv_->artificial_location_.get_is_artificial());
}

/// Getter of the environment of the current ABI artifact.
///
/// @return the environment of the artifact.
environment*
type_or_decl_base::get_environment()
{return const_cast<environment*>(priv_->env_);}

/// Get the @ref corpus this ABI artifact belongs to.
///
/// @return the corpus this ABI artifact belongs to, or nil if it
/// belongs to none for now.
corpus*
type_or_decl_base::get_corpus()
{
  translation_unit* tu = get_translation_unit();
  if (!tu)
    return 0;
  return tu->get_corpus();
}


/// Get the @ref corpus this ABI artifact belongs to.
///
/// @return the corpus this ABI artifact belongs to, or nil if it
/// belongs to none for now.
const corpus*
type_or_decl_base::get_corpus() const
{return const_cast<type_or_decl_base*>(this)->get_corpus();}

/// Set the @ref translation_unit this ABI artifact belongs to.
///
/// Note that adding an ABI artifact to a containining on should
/// invoke this member function.
void
type_or_decl_base::set_translation_unit(translation_unit* tu)
{priv_->translation_unit_ = tu;}


/// Get the @ref translation_unit this ABI artifact belongs to.
///
/// @return the translation unit this ABI artifact belongs to, or nil
/// if belongs to none for now.
translation_unit*
type_or_decl_base::get_translation_unit()
{return priv_->translation_unit_;}

/// Get the @ref translation_unit this ABI artifact belongs to.
///
/// @return the translation unit this ABI artifact belongs to, or nil
/// if belongs to none for now.
const translation_unit*
type_or_decl_base::get_translation_unit() const
{return const_cast<type_or_decl_base*>(this)->get_translation_unit();}

/// Assignment operator for @ref type_or_decl_base.
///
/// @param o the other instance to assign the current instance to.
///
/// return a reference to the assigned instance of @ref
/// type_or_decl_base.
type_or_decl_base&
type_or_decl_base::operator=(const type_or_decl_base& o)
{
  *priv_ = *o.priv_;
  return *this;
}

/// Traverse the the ABI artifact.
///
/// @param v the visitor used to traverse the sub-tree nodes of the
/// artifact.
bool
type_or_decl_base::traverse(ir_node_visitor&)
{return true;}

/// Set the environment of a given ABI artifact, including recursively
/// setting the environment on the sub-trees of the artifact.
///
/// @param artifact the artifact to set the environment for.
///
/// @param env the new environment.
void
set_environment_for_artifact(type_or_decl_base* artifact,
			     const environment* env)
{
  ABG_ASSERT(artifact && env);

  ::environment_setter s(env);
  artifact->traverse(s);
}

/// Set the environment of a given ABI artifact, including recursively
/// setting the environment on the sub-trees of the artifact.
///
/// @param artifact the artifact to set the environment for.
///
/// @param env the new environment.
void
set_environment_for_artifact(type_or_decl_base_sptr artifact,
			     const environment* env)
{set_environment_for_artifact(artifact.get(), env);}

/// Non-member equality operator for the @type_or_decl_base type.
///
/// @param lr the left-hand operand of the equality.
///
/// @param rr the right-hand operatnr of the equality.
///
/// @return true iff @p lr equals @p rr.
bool
operator==(const type_or_decl_base& lr, const type_or_decl_base& rr)
{
  const type_or_decl_base* l = &lr;
  const type_or_decl_base* r = &rr;

  const decl_base* dl = dynamic_cast<const decl_base*>(l),
    *dr = dynamic_cast<const decl_base*>(r);

  if (!!dl != !!dr)
    return false;

  if (dl && dr)
    return *dl == *dr;

  const type_base* tl = dynamic_cast<const type_base*>(l),
    *tr = dynamic_cast<const type_base*>(r);

  if (!!tl != !!tr)
    return false;

  if (tl && tr)
    return *tl == *tr;

  return false;
}

/// Non-member equality operator for the @type_or_decl_base type.
///
/// @param l the left-hand operand of the equality.
///
/// @param r the right-hand operatnr of the equality.
///
/// @return true iff @p l equals @p r.
bool
operator==(const type_or_decl_base_sptr& l, const type_or_decl_base_sptr& r)
{
  if (!! l != !!r)
    return false;

  if (!l)
    return true;

  return *r == *l;
}

/// Non-member inequality operator for the @type_or_decl_base type.
///
/// @param l the left-hand operand of the equality.
///
/// @param r the right-hand operator of the equality.
///
/// @return true iff @p l is different from @p r.
bool
operator!=(const type_or_decl_base_sptr& l, const type_or_decl_base_sptr& r)
{return !operator==(l, r);}

// </type_or_decl_base stuff>

// <Decl definition>

struct decl_base::priv
{
  bool			in_pub_sym_tab_;
  bool			is_anonymous_;
  location		location_;
  context_rel		*context_;
  interned_string	name_;
  interned_string	qualified_parent_name_;
  // This temporary qualified name is the cache used for the qualified
  // name before the type associated to this decl (if applicable) is
  // canonicalized.  Once the type is canonicalized, the cached use is
  // the data member qualified_parent_name_ above.
  interned_string	temporary_qualified_name_;
  // This is the fully qualified name of the decl.  It contains the
  // name of the decl and the qualified name of its scope.  So if in
  // the parent scopes of the decl, there is one anonymous struct,
  // somewhere in the name, there is going to by an
  // __anonymous_struct__ string, even if the anonymous struct is not
  // the direct containing scope of this decl.
  interned_string	qualified_name_;
  // Unline qualified_name_, scoped_name_ contains the name of the
  // decl and the name of its scope; not the qualified name of the
  // scope.
  interned_string	scoped_name_;
  interned_string	linkage_name_;
  visibility		visibility_;
  decl_base_sptr	declaration_;
  decl_base_wptr	definition_of_declaration_;
  decl_base*		naked_definition_of_declaration_;
  bool			is_declaration_only_;
  typedef_decl_sptr	naming_typedef_;

  priv()
    : in_pub_sym_tab_(false),
      is_anonymous_(true),
      context_(),
      visibility_(VISIBILITY_DEFAULT),
      naked_definition_of_declaration_(),
      is_declaration_only_(false)
  {}

  priv(interned_string name, interned_string linkage_name, visibility vis)
    : in_pub_sym_tab_(false),
      context_(),
      name_(name),
      qualified_name_(name),
      linkage_name_(linkage_name),
      visibility_(vis),
      naked_definition_of_declaration_(),
      is_declaration_only_(false)
  {
    is_anonymous_ = name_.empty();
  }

  ~priv()
  {
    delete context_;
  }
};// end struct decl_base::priv

/// Constructor for the @ref decl_base type.
///
/// @param e the environment the current @ref decl_base is being
/// created in.
///
/// @param name the name of the declaration.
///
/// @param locus the location where to find the declaration in the
/// source code.
///
/// @param linkage_name the linkage name of the declaration.
///
/// @param vis the visibility of the declaration.
decl_base::decl_base(const environment* e,
		     const string&	name,
		     const location&	locus,
		     const string&	linkage_name,
		     visibility	vis)
  : type_or_decl_base(e, ABSTRACT_DECL_BASE),
    priv_(new priv(e->intern(name), e->intern(linkage_name), vis))
{
  set_location(locus);
}

/// Constructor.
///
/// @param e the environment this instance of @ref decl_base is
/// created in.
///
/// @param name the name of the declaration being constructed.
///
/// @param locus the source location of the declaration being constructed.
///
/// @param linkage_name the linkage name of the declaration being
/// constructed.
///
/// @param vis the visibility of the declaration being constructed.
decl_base::decl_base(const environment* e,
		     const interned_string& name,
		     const location& locus,
		     const interned_string& linkage_name,
		     visibility vis)
  : type_or_decl_base(e, ABSTRACT_DECL_BASE),
    priv_(new priv(name, linkage_name, vis))
{
  set_location(locus);
}

/// Constructor for the @ref decl_base type.
///
///@param environment the environment this instance of @ref decl_base
/// is being constructed in.
///
/// @param l the location where to find the declaration in the source
/// code.
decl_base::decl_base(const environment* e, const location& l)
  : type_or_decl_base(e, ABSTRACT_DECL_BASE),
    priv_(new priv())
{
  set_location(l);
}

decl_base::decl_base(const decl_base& d)
  : type_or_decl_base(d)
{
  priv_->in_pub_sym_tab_ = d.priv_->in_pub_sym_tab_;
  priv_->location_ = d.priv_->location_;
  priv_->name_ = d.priv_->name_;
  priv_->qualified_parent_name_ = d.priv_->qualified_parent_name_;
  priv_->qualified_name_ = d.priv_->qualified_name_;
  priv_->linkage_name_ = d.priv_->linkage_name_;
  priv_->context_ = d.priv_->context_;
  priv_->visibility_ = d.priv_->visibility_;
}

/// Getter for the qualified name.
///
/// Unlike decl_base::get_qualified_name() this doesn't try to update
/// the qualified name.
///
/// @return the qualified name.
const interned_string&
decl_base::peek_qualified_name() const
{return priv_->qualified_name_;}

/// Clear the qualified name of this decl.
///
/// This is useful to ensure that the cache for the qualified name of
/// the decl is refreshed right after type canonicalization, for
/// instance.
void
decl_base::clear_qualified_name()
{priv_->qualified_name_.clear();}

/// Setter for the qualified name.
///
/// @param n the new qualified name.
void
decl_base::set_qualified_name(const interned_string& n) const
{priv_->qualified_name_ = n;}

/// Getter of the temporary qualified name of the current declaration.
///
/// This temporary qualified name is used as a qualified name cache by
/// the type for which this is the declaration (when applicable)
/// before the type is canonicalized.  Once the type is canonicalized,
/// it's the result of decl_base::peek_qualified_name() that becomes
/// the qualified name cached.
///
/// @return the temporary qualified name.
const interned_string&
decl_base::peek_temporary_qualified_name() const
{return priv_->temporary_qualified_name_;}

/// Setter for the temporary qualified name of the current
/// declaration.
///
///@param n the new temporary qualified name.
///
/// This temporary qualified name is used as a qualified name cache by
/// the type for which this is the declaration (when applicable)
/// before the type is canonicalized.  Once the type is canonicalized,
/// it's the result of decl_base::peek_qualified_name() that becomes
/// the qualified name cached.
void
decl_base::set_temporary_qualified_name(const interned_string& n) const
{priv_->temporary_qualified_name_ = n;}

///Getter for the context relationship.
///
///@return the context relationship for the current decl_base.
const context_rel*
decl_base::get_context_rel() const
{return priv_->context_;}

///Getter for the context relationship.
///
///@return the context relationship for the current decl_base.
context_rel*
decl_base::get_context_rel()
{return priv_->context_;}

void
decl_base::set_context_rel(context_rel *c)
{priv_->context_ = c;}

/// Get the hash of a decl.  If the hash hasn't been computed yet,
/// compute it ans store its value; otherwise, just return the hash.
///
/// @return the hash of the decl.
size_t
decl_base::get_hash() const
{
  size_t result = 0;

  if (const type_base* t = dynamic_cast<const type_base*>(this))
    {
      type_base::dynamic_hash hash;
      result = hash(t);
    }
  else
    // If we reach this point, it mean we are missing a virtual
    // overload for decl_base::get_hash.  Add it!
    abort();

  return result;
}

/// Test if the decl is defined in a ELF symbol table as a public
/// symbol.
///
/// @return true iff the decl is defined in a ELF symbol table as a
/// public symbol.
bool
decl_base::get_is_in_public_symbol_table() const
{return priv_->in_pub_sym_tab_;}

/// Set the flag saying if this decl is from a symbol that is in
/// a public symbols table, defined as public (global or weak).
///
/// @param f the new flag value.
void
decl_base::set_is_in_public_symbol_table(bool f)
{priv_->in_pub_sym_tab_ = f;}

/// Get the location of a given declaration.
///
/// The location is an abstraction for the tripplet {file path,
/// line, column} that defines where the declaration appeared in the
/// source code.
///
/// To get the value of the tripplet {file path, line, column} from
/// the @ref location, you need to use the
/// location_manager::expand_location() method.
///
/// The instance of @ref location_manager that you want is
/// accessible from the instance of @ref translation_unit that the
/// current instance of @ref decl_base belongs to, via a call to
/// translation_unit::get_loc_mgr().
///
/// @return the location of the current instance of @ref decl_base.
const location&
decl_base::get_location() const
{return priv_->location_;}

/// Set the location for a given declaration.
///
/// The location is an abstraction for the tripplet {file path,
/// line, column} that defines where the declaration appeared in the
/// source code.
///
/// To create a location from a tripplet {file path, line, column},
/// you need to use the method @ref
/// location_manager::create_new_location().
///
/// Note that there can be two kinds of location.  An artificial
/// location and a non-artificial one.  The non-artificial location is
/// the one emitted by the original emitter of the ABI artifact, for
/// instance, if the ABI artifact comes from debug info, then the
/// source location that is present in the debug info represent a
/// non-artificial location.  When looking at an abixml file on the
/// other hand, the value of the 'location' attribute of an XML
/// element describing an artifact is the non-artificial location.
/// The artificial location is the location (line number from the
/// beginning of the file) of the XML element within the abixml file.
///
/// So, if the location that is being set is artificial, note that the
/// type_or_decl_base::has_artificial_location() method of this decl will
/// subsequently return true and that artificial location will have to
/// be retrieved using type_or_decl_base::get_artificial_location().
/// If the location is non-artificial however,
/// type_or_decl_base::has_artificial_location() will subsequently
/// return false and the non-artificial location will have to be
/// retrieved using decl_base::get_location().
///
/// The instance of @ref location_manager that you want is
/// accessible from the instance of @ref translation_unit that the
/// current instance of @ref decl_base belongs to, via a call to
/// translation_unit::get_loc_mgr().
void
decl_base::set_location(const location& l)
{
  if (l.get_is_artificial())
    set_artificial_location(l);
  else
    priv_->location_ = l;
}

/// Setter for the name of the decl.
///
/// @param n the new name to set.
void
decl_base::set_name(const string& n)
{
  priv_->name_ = get_environment()->intern(n);
  priv_->is_anonymous_ = n.empty();
}

/// Test if the current declaration is anonymous.
///
/// Being anonymous means that the declaration was created without a
/// name.  This can usually happen for enum or struct types.
///
/// @return true iff the type is anonymous.
bool
decl_base::get_is_anonymous() const
{return priv_->is_anonymous_;}

/// Set the "is_anonymous" flag of the current declaration.
///
/// Being anonymous means that the declaration was created without a
/// name.  This can usually happen for enum or struct types.
///
/// @param f the new value of the flag.
void
decl_base::set_is_anonymous(bool f)
{priv_->is_anonymous_ = f;}


/// Get the "has_anonymous_parent" flag of the current declaration.
///
/// Having an anoymous parent means having a anonymous parent scope
/// (containing type or namespace) which is either direct or indirect.
///
/// @return true iff the current decl has a direct or indirect scope
/// which is anonymous.
bool
decl_base::get_has_anonymous_parent() const
{
  scope_decl *scope = get_scope();
  if (!scope)
    return false;
  return scope->get_is_anonymous();
}

/// @return the logical "OR" of decl_base::get_is_anonymous() and
/// decl_base::get_has_anonymous_parent().
bool
decl_base::get_is_anonymous_or_has_anonymous_parent() const
{return get_is_anonymous() || get_has_anonymous_parent();}

/// Getter for the naming typedef of the current decl.
///
/// Consider the C idiom:
///
///    typedef struct {int member;} foo_type;
///
/// In that idiom, foo_type is the naming typedef of the anonymous
/// struct that is declared.
///
/// @return the naming typedef, if any.  Otherwise, returns nil.
typedef_decl_sptr
decl_base::get_naming_typedef() const
{return priv_->naming_typedef_;}

/// Set the naming typedef of the current instance of @ref decl_base.
///
/// Consider the C idiom:
///
///    typedef struct {int member;} foo_type;
///
/// In that idiom, foo_type is the naming typedef of the anonymous
/// struct that is declared.
///
/// After completion of this function, the decl will not be considered
/// anonymous anymore.  It's name is going to be the name of the
/// naming typedef.
///
/// @param typedef_type the new naming typedef.
void
decl_base::set_naming_typedef(const typedef_decl_sptr& t)
{
  // A naming typedef is usually for an anonymous type.
  ABG_ASSERT(get_is_anonymous()
	     // Whe the typedef-named decl is saved into abixml, it's
	     // not anonymous anymore.  Its name is the typedef name.
	     // So when we read it back, we must still be able to
	     // apply the naming typedef to the decl.
	     || t->get_name() == get_name());
  // Only non canonicalized types can be edited this way.
  ABG_ASSERT(is_type(this)
	     && is_type(this)->get_naked_canonical_type() == nullptr);

  priv_->naming_typedef_ = t;
  set_name(t->get_name());
  set_qualified_name(t->get_qualified_name());
  set_is_anonymous(false);
  // Now that the qualified type of the decl has changed, let's update
  // the qualified names of the member types of this decls.
  update_qualified_name(this);
}

/// Getter for the mangled name.
///
/// @return the new mangled name.
const interned_string&
decl_base::get_linkage_name() const
{return priv_->linkage_name_;}

/// Setter for the linkage name.
///
/// @param m the new linkage name.
void
decl_base::set_linkage_name(const string& m)
{
  const environment* env = get_environment();
  ABG_ASSERT(env);
  priv_->linkage_name_ = env->intern(m);
}

/// Getter for the visibility of the decl.
///
/// @return the new visibility.
decl_base::visibility
decl_base::get_visibility() const
{return priv_->visibility_;}

/// Setter for the visibility of the decl.
///
/// @param v the new visibility.
void
decl_base::set_visibility(visibility v)
{priv_->visibility_ = v;}

/// Return the type containing the current decl, if any.
///
/// @return the type that contains the current decl, or NULL if there
/// is none.
scope_decl*
decl_base::get_scope() const
{
  if (priv_->context_)
    return priv_->context_->get_scope();
  return 0;
}

/// Return a copy of the qualified name of the parent of the current
/// decl.
///
/// @return the newly-built qualified name of the of the current decl.
const interned_string&
decl_base::get_qualified_parent_name() const
{return priv_->qualified_parent_name_;}

/// Getter for the name of the current decl.
///
/// @return the name of the current decl.
const interned_string&
decl_base::get_name() const
{return priv_->name_;}

/// Compute the qualified name of the decl.
///
/// @param qn the resulting qualified name.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
void
decl_base::get_qualified_name(interned_string& qn, bool internal) const
{qn = get_qualified_name(internal);}

/// Get the pretty representatin of the current declaration.
///
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.
///
/// @param qualified_name if true, names emitted in the pretty
/// representation are fully qualified.
///
/// @return the default pretty representation for a decl.  This is
/// basically the fully qualified name of the decl optionally prefixed
/// with a meaningful string to add context for the user.
string
decl_base::get_pretty_representation(bool internal,
				     bool qualified_name) const
{
  if (internal
      && get_is_anonymous()
      && has_generic_anonymous_internal_type_name(this))
    {
      // We are looking at an anonymous enum, union or class and we
      // want an *internal* pretty representation for it.  All
      // anonymous types of this kind in the same namespace must have
      // the same internal representation for type canonicalization to
      // work properly.
      //
      // OK, in practise, we are certainly looking at an enum because
      // classes and unions should have their own overloaded virtual
      // member function for this.
      string name = get_generic_anonymous_internal_type_name(this);
      if (qualified_name && !get_qualified_parent_name().empty())
	name = get_qualified_parent_name() + "::" + name;
      return name;
    }

  if (qualified_name)
    return get_qualified_name(internal);
  return get_name();
}

/// Return the qualified name of the decl.
///
/// This is the fully qualified name of the decl.  It's made of the
/// concatenation of the name of the decl with the qualified name of
/// its scope.
///
/// Note that the value returned by this function is computed by @ref
/// update_qualified_name when the decl is added to its scope.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the resulting qualified name.
const interned_string&
decl_base::get_qualified_name(bool /*internal*/) const
{return priv_->qualified_name_;}

/// Return the scoped name of the decl.
///
/// This is made of the concatenation of the name of the decl with the
/// name of its scope.  It doesn't contain the qualified name of its
/// scope, unlike what is returned by decl_base::get_qualified_name.
///
/// Note that the value returned by this function is computed by @ref
/// update_qualified_name when the decl is added to its scope.
///
/// @return the scoped name of the decl.
const interned_string&
decl_base::get_scoped_name() const
{return priv_->scoped_name_;}

/// If this @ref decl_base is a definition, get its earlier
/// declaration.
///
/// @return the earlier declaration of the class, if any.
const decl_base_sptr
decl_base::get_earlier_declaration() const
{return priv_->declaration_;}

/// set the earlier declaration of this @ref decl_base definition.
///
/// @param d the earlier declaration to set.  Note that it's set only
/// if it's a pure declaration.
void
decl_base::set_earlier_declaration(const decl_base_sptr& d)
{
  if (d && d->get_is_declaration_only())
    priv_->declaration_ = d;
}


/// If this @ref decl_base is declaration-only, get its definition, if
/// any.
///
/// @return the definition of this decl-only @ref decl_base.
const decl_base_sptr
decl_base::get_definition_of_declaration() const
{return priv_->definition_of_declaration_.lock();}

///  If this @ref decl_base is declaration-only, get its definition,
///  if any.
///
/// Note that this function doesn't return a smart pointer, but rather
/// the underlying pointer managed by the smart pointer.  So it's as
/// fast as possible.  This getter is to be used in code paths that
/// are proven to be performance hot spots; especially, when comparing
/// sensitive types like enums, classes or unions.  Those are compared
/// extremely frequently and thus, their access to the definition of
/// declaration must be fast.
///
/// @return the definition of the declaration.
const decl_base*
decl_base::get_naked_definition_of_declaration() const
{return priv_->naked_definition_of_declaration_;}

/// Test if a @ref decl_base is a declaration-only decl.
///
/// @return true iff the current @ref decl_base is declaration-only.
bool
decl_base::get_is_declaration_only() const
{return priv_->is_declaration_only_;}

/// Set a flag saying if the @ref enum_type_decl is a declaration-only
/// @ref enum_type_decl.
///
/// @param f true if the @ref enum_type_decl is a declaration-only
/// @ref enum_type_decl.
void
decl_base::set_is_declaration_only(bool f)
{
  bool update_types_lookup_map = !f && priv_->is_declaration_only_;

  priv_->is_declaration_only_ = f;

  if (update_types_lookup_map)
    if (scope_decl* s = get_scope())
      {
	scope_decl::declarations::iterator i;
	if (s->find_iterator_for_member(this, i))
	  maybe_update_types_lookup_map(*i);
	else
	  ABG_ASSERT_NOT_REACHED;
      }
}

change_kind
operator|(change_kind l, change_kind r)
{
  return static_cast<change_kind>(static_cast<unsigned>(l)
				  | static_cast<unsigned>(r));
}

change_kind
operator&(change_kind l, change_kind r)
{
  return static_cast<change_kind>(static_cast<unsigned>(l)
				  & static_cast<unsigned>(r));
}

change_kind&
operator|=(change_kind& l, change_kind r)
{
  l = l | r;
  return l;
}

change_kind&
operator&=(change_kind& l, change_kind r)
{
  l = l & r;
  return l;
}

/// Compare the properties that belong to the "is-a-member-relation"
/// of a decl.
///
/// For instance, access specifiers are part of the
/// "is-a-member-relation" of a decl.
///
/// This comparison however doesn't take decl names into account.  So
/// typedefs for instance are decls that we want to compare with this
/// function.
///
/// This function is a sub-routine of the more general 'equals'
/// overload for instances of decl_base.
///
/// @param l the left-hand side operand of the comparison.
///
/// @param r the right-hand side operand of the comparison.
///
/// @return true iff @p l compare equals, as a member decl, to @p r.
bool
maybe_compare_as_member_decls(const decl_base& l,
			      const decl_base& r,
			      change_kind* k)
{
  bool result = true;
  if (is_member_decl(l) && is_member_decl(r))
    {
      context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
      context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());

      access_specifier la = no_access, ra = no_access;
      bool member_types_or_functions =
	((is_type(l) && is_type(r))
	 || (is_function_decl(l) && is_function_decl(r)));

      if (member_types_or_functions)
	{
	  // Access specifiers on member types in DWARF is not
	  // reliable; in the same DSO, the same struct can be either
	  // a class or a struct, and the access specifiers of its
	  // member types are not necessarily given, so they
	  // effectively can be considered differently, again, in the
	  // same DSO.  So, here, let's avoid considering those!
	  // during comparison.
	  la = r1->get_access_specifier();
	  ra = r2->get_access_specifier();
	  r1->set_access_specifier(no_access);
	  r2->set_access_specifier(no_access);
	}

      bool rels_are_different = *r1 != *r2;

      if (member_types_or_functions)
	{
	  // restore the access specifiers.
	  r1->set_access_specifier(la);
	  r2->set_access_specifier(ra);
	}

      if (rels_are_different)
	{
	  result = false;
	  if (k)
	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	}
    }
  ABG_RETURN(result);
}

/// Get the name of a decl for the purpose of comparing two decl
/// names.
///
/// This is a sub-routine of the 'equal' overload for decl_base.
///
/// This function takes into account the fact that all anonymous names
/// shall have the same name for the purpose of comparison.
///
/// For decls that are part of an anonymous scope, only the
/// non-qualified name should be taken into account.
static interned_string
get_decl_name_for_comparison(const decl_base &d)
{
  if (has_generic_anonymous_internal_type_name(&d)
      && d.get_is_anonymous())
    {
      // The decl is anonymous.   It should have the same name ass the
      // other anymous types of the same kind.
      string r;
      r += get_generic_anonymous_internal_type_name(&d);
      return d.get_environment()->intern(r);
    }

  interned_string n = (is_anonymous_or_typedef_named(d)
		       || scope_anonymous_or_typedef_named(d))
    ? d.get_name()
    : d.get_qualified_name(/*internal=*/true);
  return n;
}

/// Compares two instances of @ref decl_base.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff it's non-null and if the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const decl_base& l, const decl_base& r, change_kind* k)
{
  bool result = true;
  const interned_string &l_linkage_name = l.get_linkage_name();
  const interned_string &r_linkage_name = r.get_linkage_name();
  if (!l_linkage_name.empty() && !r_linkage_name.empty())
    {
      if (l_linkage_name != r_linkage_name)
	{
	  // Linkage names are different.  That usually means the two
	  // decls are different, unless we are looking at two
	  // function declarations which have two different symbols
	  // that are aliases of each other.
	  const function_decl *f1 = is_function_decl(&l),
	    *f2 = is_function_decl(&r);
	  if (f1 && f2 && function_decls_alias(*f1, *f2))
	    ;// The two functions are aliases, so they are not
	     // different.
	  else
	    {
	      result = false;
	      if (k)
		*k |= LOCAL_NON_TYPE_CHANGE_KIND;
	      else
		ABG_RETURN_FALSE;
	    }
	}
    }

  // This is the qualified name of the decls that we want to compare.
  // We want to use the "internal" version of the qualified name as
  // that one is stable even for anonymous decls.
  interned_string ln = get_decl_name_for_comparison(l);
  interned_string rn = get_decl_name_for_comparison(r);

  /// If both of the current decls have an anonymous scope then let's
  /// compare their name component by component by properly handling
  /// anonymous scopes. That's the slow path.
  ///
  /// Otherwise, let's just compare their name, the obvious way.
  /// That's the fast path because in that case the names are
  /// interned_string and comparing them is much faster.
  bool decls_are_same = (ln == rn);
  if (!decls_are_same
      && l.get_is_anonymous()
      && !l.get_has_anonymous_parent()
      && r.get_is_anonymous()
      && !r.get_has_anonymous_parent())
    // Both decls are anonymous and their scope are *NOT* anonymous.
    // So we consider the decls to have equivalent names (both
    // anonymous, remember).  We are still in the fast path here.
    decls_are_same = true;

  if (!decls_are_same
      && l.get_has_anonymous_parent()
      && r.get_has_anonymous_parent())
    // This is the slow path as we are comparing the decl qualified
    // names component by component, properly handling anonymous
    // scopes.
    decls_are_same = tools_utils::decl_names_equal(ln, rn);

  if (!decls_are_same)
    {
      result = false;
      if (k)
	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }

  result &= maybe_compare_as_member_decls(l, r, k);

  ABG_RETURN(result);
}

/// Return true iff the two decls have the same name.
///
/// This function doesn't test if the scopes of the the two decls are
/// equal.
///
/// Note that this virtual function is to be implemented by classes
/// that extend the \p decl_base class.
bool
decl_base::operator==(const decl_base& other) const
{return equals(*this, other, 0);}

/// Inequality operator.
///
/// @param other to other instance of @ref decl_base to compare the
/// current instance to.
///
/// @return true iff the current instance of @ref decl_base is
/// different from @p other.
bool
decl_base::operator!=(const decl_base& other) const
{return !operator==(other);}

/// Destructor of the @ref decl_base type.
decl_base::~decl_base()
{delete priv_;}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the member nodes of the translation
/// unit during the traversal.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
decl_base::traverse(ir_node_visitor&)
{
  // Do nothing in the base class.
  return true;
}

/// Setter of the scope of the current decl.
///
/// Note that the decl won't hold a reference on the scope.  It's
/// rather the scope that holds a reference on its members.
void
decl_base::set_scope(scope_decl* scope)
{
  if (!priv_->context_)
    priv_->context_ = new context_rel(scope);
  else
    priv_->context_->set_scope(scope);
}

// </decl_base definition>

/// Streaming operator for the decl_base::visibility.
///
/// @param o the output stream to serialize the visibility to.
///
/// @param v the visibility to serialize.
///
/// @return the output stream.
std::ostream&
operator<<(std::ostream& o, decl_base::visibility v)
{
  string r;
  switch (v)
    {
    case decl_base::VISIBILITY_NONE:
      r = "none";
      break;
    case decl_base::VISIBILITY_DEFAULT:
      r = "default";
      break;
    case decl_base::VISIBILITY_PROTECTED:
      r = "protected";
      break;
    case decl_base::VISIBILITY_HIDDEN:
      r = "hidden";
      break;
    case decl_base::VISIBILITY_INTERNAL:
      r = "internal";
      break;
    }
  return o;
}

/// Streaming operator for decl_base::binding.
///
/// @param o the output stream to serialize the visibility to.
///
/// @param b the binding to serialize.
///
/// @return the output stream.
std::ostream&
operator<<(std::ostream& o, decl_base::binding b)
{
  string r;
  switch (b)
    {
    case decl_base::BINDING_NONE:
      r = "none";
      break;
    case decl_base::BINDING_LOCAL:
      r = "local";
      break;
    case decl_base::BINDING_GLOBAL:
      r = "global";
      break;
    case decl_base::BINDING_WEAK:
      r = "weak";
      break;
    }
  o << r;
  return o;
}

/// Turn equality of shared_ptr of decl_base into a deep equality;
/// that is, make it compare the pointed to objects, not just the
/// pointers.
///
/// @param l the shared_ptr of decl_base on left-hand-side of the
/// equality.
///
/// @param r the shared_ptr of decl_base on right-hand-side of the
/// equality.
///
/// @return true if the decl_base pointed to by the shared_ptrs are
/// equal, false otherwise.
bool
operator==(const decl_base_sptr& l, const decl_base_sptr& r)
{
  if (l.get() == r.get())
    return true;
  if (!!l != !!r)
    return false;

  return *l == *r;
}

/// Inequality operator of shared_ptr of @ref decl_base.
///
/// This is a deep equality operator, that is, it compares the
/// pointed-to objects, rather than just the pointers.
///
/// @param l the left-hand-side operand.
///
/// @param r the right-hand-side operand.
///
/// @return true iff @p l is different from @p r.
bool
operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
{return !operator==(l, r);}

/// Turn equality of shared_ptr of type_base into a deep equality;
/// that is, make it compare the pointed to objects too.
///
/// @param l the shared_ptr of type_base on left-hand-side of the
/// equality.
///
/// @param r the shared_ptr of type_base on right-hand-side of the
/// equality.
///
/// @return true if the type_base pointed to by the shared_ptrs are
/// equal, false otherwise.
bool
operator==(const type_base_sptr& l, const type_base_sptr& r)
{
    if (l.get() == r.get())
    return true;
  if (!!l != !!r)
    return false;

  return *l == *r;
}

/// Turn inequality of shared_ptr of type_base into a deep equality;
/// that is, make it compare the pointed to objects..
///
/// @param l the shared_ptr of type_base on left-hand-side of the
/// equality.
///
/// @param r the shared_ptr of type_base on right-hand-side of the
/// equality.
///
/// @return true iff the type_base pointed to by the shared_ptrs are
/// different.
bool
operator!=(const type_base_sptr& l, const type_base_sptr& r)
{return !operator==(l, r);}

/// Tests if a declaration has got a scope.
///
/// @param d the declaration to consider.
///
/// @return true if the declaration has got a scope, false otherwise.
bool
has_scope(const decl_base& d)
{return (d.get_scope());}

/// Tests if a declaration has got a scope.
///
/// @param d the declaration to consider.
///
/// @return true if the declaration has got a scope, false otherwise.
bool
has_scope(const decl_base_sptr d)
{return has_scope(*d.get());}

/// Tests if a declaration is a class member.
///
/// @param d the declaration to consider.
///
/// @return true if @p d is a class member, false otherwise.
bool
is_member_decl(const decl_base_sptr d)
{return is_at_class_scope(d) || is_method_decl(d);}

/// Tests if a declaration is a class member.
///
/// @param d the declaration to consider.
///
/// @return true if @p d is a class member, false otherwise.
bool
is_member_decl(const decl_base* d)
{return is_at_class_scope(d) || is_method_decl(d);}

/// Tests if a declaration is a class member.
///
/// @param d the declaration to consider.
///
/// @return true if @p d is a class member, false otherwise.
bool
is_member_decl(const decl_base& d)
{return is_at_class_scope(d) || is_method_decl(d);}

/// Test if a declaration is a @ref scope_decl.
///
/// @param d the declaration to take in account.
///
/// @return the a pointer to the @ref scope_decl sub-object of @p d,
/// if d is a @ref scope_decl.
scope_decl*
is_scope_decl(decl_base* d)
{return dynamic_cast<scope_decl*>(d);}

/// Test if a declaration is a @ref scope_decl.
///
/// @param d the declaration to take in account.
///
/// @return the a pointer to the @ref scope_decl sub-object of @p d,
/// if d is a @ref scope_decl.
scope_decl_sptr
is_scope_decl(const decl_base_sptr& d)
{return dynamic_pointer_cast<scope_decl>(d);}

/// Tests if a type is a class member.
///
/// @param t the type to consider.
///
/// @return true if @p t is a class member type, false otherwise.
bool
is_member_type(const type_base_sptr& t)
{
  decl_base_sptr d = get_type_declaration(t);
  return is_member_decl(d);
}

/// Test if a type is user-defined.
///
/// A type is considered user-defined if it's a
/// struct/class/union/enum that is *NOT* artificial.
///
/// @param t the type to consider.
///
/// @return true iff the type @p t is user-defined.
bool
is_user_defined_type(const type_base* t)
{
  if (t == 0)
    return false;

  t = peel_qualified_or_typedef_type(t);
  decl_base *d = is_decl(t);

  if ((is_class_or_union_type(t) || is_enum_type(t))
      && d && !d->get_is_artificial())
    return true;

  return false;
}

/// Test if a type is user-defined.
///
/// A type is considered user-defined if it's a
/// struct/class/union/enum.
///
///
/// @param t the type to consider.
///
/// @return true iff the type @p t is user-defined.
bool
is_user_defined_type(const type_base_sptr& t)
{return is_user_defined_type(t.get());}

/// Gets the access specifier for a class member.
///
/// @param d the declaration of the class member to consider.  Note
/// that this must be a class member otherwise the function aborts the
/// current process.
///
/// @return the access specifier for the class member @p d.
access_specifier
get_member_access_specifier(const decl_base& d)
{
  ABG_ASSERT(is_member_decl(d));

  const context_rel* c = d.get_context_rel();
  ABG_ASSERT(c);

  return c->get_access_specifier();
}

/// Gets the access specifier for a class member.
///
/// @param d the declaration of the class member to consider.  Note
/// that this must be a class member otherwise the function aborts the
/// current process.
///
/// @return the access specifier for the class member @p d.
access_specifier
get_member_access_specifier(const decl_base_sptr& d)
{return get_member_access_specifier(*d);}

/// Sets the access specifier for a class member.
///
/// @param d the class member to set the access specifier for.  Note
/// that this must be a class member otherwise the function aborts the
/// current process.
///
/// @param a the new access specifier to set the class member to.
void
set_member_access_specifier(decl_base& d,
			    access_specifier a)
{
  ABG_ASSERT(is_member_decl(d));

  context_rel* c = d.get_context_rel();
  ABG_ASSERT(c);

  c->set_access_specifier(a);
}

/// Sets the access specifier for a class member.
///
/// @param d the class member to set the access specifier for.  Note
/// that this must be a class member otherwise the function aborts the
/// current process.
///
/// @param a the new access specifier to set the class member to.
void
set_member_access_specifier(const decl_base_sptr& d,
			    access_specifier a)
{set_member_access_specifier(*d, a);}

/// Gets a flag saying if a class member is static or not.
///
/// @param d the declaration for the class member to consider. Note
/// that this must be a class member otherwise the function aborts the
/// current process.
///
/// @return true if the class member @p d is static, false otherwise.
bool
get_member_is_static(const decl_base&d)
{
  ABG_ASSERT(is_member_decl(d));

  const context_rel* c = d.get_context_rel();
  ABG_ASSERT(c);

  return c->get_is_static();
}

/// Gets a flag saying if a class member is static or not.
///
/// @param d the declaration for the class member to consider. Note
/// that this must be a class member otherwise the function aborts the
/// current process.
///
/// @return true if the class member @p d is static, false otherwise.
bool
get_member_is_static(const decl_base* d)
{return get_member_is_static(*d);}

/// Gets a flag saying if a class member is static or not.
///
/// @param d the declaration for the class member to consider.  Note
/// that this must be a class member otherwise the function aborts the
/// current process.
///
/// @return true if the class member @p d is static, false otherwise.
bool
get_member_is_static(const decl_base_sptr& d)
{return get_member_is_static(*d);}

/// Test if a var_decl is a data member.
///
/// @param v the var_decl to consider.
///
/// @return true if @p v is data member, false otherwise.
bool
is_data_member(const var_decl& v)
{return is_at_class_scope(v);}

/// Test if a var_decl is a data member.
///
/// @param v the var_decl to consider.
///
/// @return true if @p v is data member, false otherwise.
bool
is_data_member(const var_decl* v)
{return is_data_member(*v);}

/// Test if a var_decl is a data member.
///
/// @param v the var_decl to consider.
///
/// @return true if @p v is data member, false otherwise.
bool
is_data_member(const var_decl_sptr d)
{return is_at_class_scope(d);}

/// Test if a decl is a data member.
///
/// @param d the decl to consider.
///
/// @return a pointer to the data member iff @p d is a data member, or
/// a null pointer.
var_decl_sptr
is_data_member(const decl_base_sptr& d)
{
  if (var_decl_sptr v = is_var_decl(d))
    {
      if (is_data_member(v))
	return v;
    }
  return var_decl_sptr();
}

/// Test if a decl is a data member.
///
/// @param d the decl to consider.
///
/// @return a pointer to the data member iff @p d is a data member, or
/// a null pointer.
var_decl_sptr
is_data_member(const type_or_decl_base_sptr& d)
{
  if (var_decl_sptr v = is_var_decl(d))
    {
      if (is_data_member(v))
	return v;
    }
  return var_decl_sptr();
}

/// Test if a decl is a data member.
///
/// @param d the decl to consider.
///
/// @return a pointer to the data member iff @p d is a data member, or
/// a null pointer.
var_decl*
is_data_member(const type_or_decl_base* d)
{
 if (var_decl *v = is_var_decl(d))
    if (is_data_member(v))
      return v;
  return 0;
}

/// Test if a decl is a data member.
///
/// @param d the decl to consider.
///
/// @return a pointer to the data member iff @p d is a data member, or
/// a null pointer.
var_decl*
is_data_member(const decl_base *d)
{
  if (var_decl *v = is_var_decl(d))
    if (is_data_member(v))
      return v;
  return 0;
}

/// Get the first non-anonymous data member of a given anonymous data
/// member.
///
/// E.g:
///
///   struct S
///   {
///     union // <-- for this anonymous data member, the function
///           // returns a.
///     {
///       int a;
///       charb;
///     };
///   };
///
/// @return anon_dm the anonymous data member to consider.
///
/// @return the first non-anonymous data member of @p anon_dm.  If no
/// data member was found then this function returns @p anon_dm.
const var_decl_sptr
get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)
{
  if (!anon_dm || !is_anonymous_data_member(anon_dm))
    return anon_dm;

  class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
 var_decl_sptr first = *klass->get_non_static_data_members().begin();

 if (is_anonymous_data_member(first))
   return get_first_non_anonymous_data_member(first);

 return first;
}

/// In the context of a given class or union, this function returns
/// the data member that is located after a given data member.
///
/// @param klass the class or union to consider.
///
/// @param the data member to consider.
///
/// @return the data member that is located right after @p
/// data_member.
const var_decl_sptr
get_next_data_member(const class_or_union_sptr &klass,
		     const var_decl_sptr &data_member)
{
  if (!klass ||!data_member)
    return var_decl_sptr();

  for (class_or_union::data_members::const_iterator it =
	 klass->get_non_static_data_members().begin();
       it != klass->get_non_static_data_members().end();
       ++it)
    if (**it == *data_member)
      {
	++it;
	if (it != klass->get_non_static_data_members().end())
	  return get_first_non_anonymous_data_member(*it);
	break;
      }

  return var_decl_sptr();
}

/// Get the last data member of a class type.
///
/// @param klass the class type to consider.
var_decl_sptr
get_last_data_member(const class_or_union_sptr &klass)
{return klass->get_non_static_data_members().back();}

/// Test if a decl is an anonymous data member.
///
/// @param d the decl to consider.
///
/// @return true iff @p d is an anonymous data member.
bool
is_anonymous_data_member(const decl_base& d)
{return is_anonymous_data_member(&d);}

/// Test if a decl is an anonymous data member.
///
/// @param d the decl to consider.
///
/// @return the var_decl representing the data member iff @p d is an
/// anonymous data member.
const var_decl*
is_anonymous_data_member(const type_or_decl_base* d)
{
  if (const var_decl* v = is_data_member(d))
    {
      if (is_anonymous_data_member(v))
	return v;
    }
  return 0;
}

/// Test if a decl is an anonymous data member.
///
/// @param d the decl to consider.
///
/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
/// it's an anonymous data member.  Otherwise returns a nil pointer.
const var_decl*
is_anonymous_data_member(const decl_base* d)
{
  if (const var_decl* v = is_data_member(d))
    {
      if (is_anonymous_data_member(v))
	return v;
    }
  return 0;
}

/// Test if a decl is an anonymous data member.
///
/// @param d the decl to consider.
///
/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
/// it's an anonymous data member.  Otherwise returns a nil pointer.
var_decl_sptr
is_anonymous_data_member(const type_or_decl_base_sptr& d)
{
  if (var_decl_sptr v = is_data_member(d))
    {
      if (is_anonymous_data_member(v))
	return v;
    }
  return var_decl_sptr();
}

/// Test if a decl is an anonymous data member.
///
/// @param d the decl to consider.
///
/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
/// it's an anonymous data member.  Otherwise returns a nil pointer.
var_decl_sptr
is_anonymous_data_member(const decl_base_sptr& d)
{
  if (var_decl_sptr v = is_data_member(d))
    return is_anonymous_data_member(v);
  return var_decl_sptr();
}

/// Test if a @ref var_decl is an anonymous data member.
///
/// @param d the @ref var_decl to consider.
///
/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
/// it's an anonymous data member.  Otherwise returns a nil pointer.
var_decl_sptr
is_anonymous_data_member(const var_decl_sptr& d)
{
  if (is_anonymous_data_member(d.get()))
    return d;
  return var_decl_sptr();
}

/// Test if a @ref var_decl is an anonymous data member.
///
/// @param d the @ref var_decl to consider.
///
/// @return a non-nil pointer to the @ref var_decl denoted by @p d if
/// it's an anonymous data member.  Otherwise returns a nil pointer.
const var_decl*
is_anonymous_data_member(const var_decl* d)
{
  if (d && is_anonymous_data_member(*d))
    return d;
  return 0;
}

/// Test if a @ref var_decl is an anonymous data member.
///
/// @param d the @ref var_decl to consider.
///
/// @return true iff @p d is an anonymous data member.
bool
is_anonymous_data_member(const var_decl& d)
{
  return (is_data_member(d)
	  && d.get_is_anonymous()
	  && d.get_name().empty()
	  && is_class_or_union_type(d.get_type()));
}

/// Get the @ref class_or_union type of a given anonymous data member.
///
/// @param d the anonymous data member to consider.
///
/// @return the @ref class_or_union type of the anonymous data member
/// @p d.
class_or_union*
anonymous_data_member_to_class_or_union(const var_decl* d)
{
  if ((d = is_anonymous_data_member(d)))
    return is_class_or_union_type(d->get_type().get());
  return 0;
}

/// Test if a data member has annonymous type or not.
///
/// @param d the data member to consider.
///
/// @return the anonymous class or union type iff @p turns out to have
/// an anonymous type.  Otherwise, returns nil.
const class_or_union_sptr
data_member_has_anonymous_type(const var_decl& d)
{
  if (is_data_member(d))
    if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
      if (cou->get_is_anonymous())
	return cou;

  return class_or_union_sptr();
}

/// Test if a data member has annonymous type or not.
///
/// @param d the data member to consider.
///
/// @return the anonymous class or union type iff @p turns out to have
/// an anonymous type.  Otherwise, returns nil.
const class_or_union_sptr
data_member_has_anonymous_type(const var_decl* d)
{
  if (d)
    return data_member_has_anonymous_type(*d);
  return class_or_union_sptr();
}

/// Test if a data member has annonymous type or not.
///
/// @param d the data member to consider.
///
/// @return the anonymous class or union type iff @p turns out to have
/// an anonymous type.  Otherwise, returns nil.
const class_or_union_sptr
data_member_has_anonymous_type(const var_decl_sptr& d)
{return data_member_has_anonymous_type(d.get());}

/// Get the @ref class_or_union type of a given anonymous data member.
///
/// @param d the anonymous data member to consider.
///
/// @return the @ref class_or_union type of the anonymous data member
/// @p d.
class_or_union_sptr
anonymous_data_member_to_class_or_union(const var_decl_sptr &d)
{
  if (var_decl_sptr v = is_anonymous_data_member(d))
    return is_class_or_union_type(v->get_type());
  return class_or_union_sptr();
}

/// Test if the scope of a given decl is anonymous or anonymous with a
/// naming typedef.
///
/// @param d the decl consider.
///
/// @return true iff the scope of @p d is anonymous or anonymous with
/// a naming typedef.
bool
scope_anonymous_or_typedef_named(const decl_base& d)
{
  if (d.get_has_anonymous_parent()
      || (d.get_scope() && d.get_scope()->get_naming_typedef()))
    return true;
  return false;
}

/// Test if a given decl is anonymous or has a naming typedef.
///
/// @param d the decl to consider.
///
/// @return true iff @p d is anonymous or has a naming typedef.
bool
is_anonymous_or_typedef_named(const decl_base& d)
{
  if (d.get_is_anonymous() || d.get_naming_typedef())
    return true;
  return false;
}

/// Set the offset of a data member into its containing class.
///
/// @param m the data member to consider.
///
/// @param o the offset, in bits.
void
set_data_member_offset(var_decl_sptr m, uint64_t o)
{
  ABG_ASSERT(is_data_member(m));

  dm_context_rel* ctxt_rel =
    dynamic_cast<dm_context_rel*>(m->get_context_rel());
  ABG_ASSERT(ctxt_rel);

  ctxt_rel->set_offset_in_bits(o);
}

/// Get the offset of a data member.
///
/// @param m the data member to consider.
///
/// @return the offset (in bits) of @p m in its containing class.
uint64_t
get_data_member_offset(const var_decl& m)
{
  ABG_ASSERT(is_data_member(m));
  const dm_context_rel* ctxt_rel =
    dynamic_cast<const dm_context_rel*>(m.get_context_rel());
  ABG_ASSERT(ctxt_rel);
  return ctxt_rel->get_offset_in_bits();
}

/// Get the offset of a data member.
///
/// @param m the data member to consider.
///
/// @return the offset (in bits) of @p m in its containing class.
uint64_t
get_data_member_offset(const var_decl_sptr m)
{return get_data_member_offset(*m);}

/// Get the offset of a data member.
///
/// @param m the data member to consider.
///
/// @return the offset (in bits) of @p m in its containing class.
uint64_t
get_data_member_offset(const decl_base_sptr d)
{return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}

/// Get the offset of the non-static data member that comes after a
/// given one.
///
/// If there is no data member after after the one given to this
/// function (maybe because the given one is the last data member of
/// the class type) then the function return false.
///
/// @param klass the class to consider.
///
/// @param dm the data member before the one we want to retrieve.
///
/// @param offset out parameter.  This parameter is set by the
/// function to the offset of the data member that comes right after
/// the data member @p dm, iff the function returns true.
///
/// @return true iff the data member coming right after @p dm was
/// found.
bool
get_next_data_member_offset(const class_or_union_sptr& klass,
			    const var_decl_sptr& dm,
			    uint64_t& offset)
{
  var_decl_sptr next_dm = get_next_data_member(klass, dm);
  if (!next_dm)
    return false;
  offset = get_data_member_offset(next_dm);
  return true;
}

/// Get the absolute offset of a data member.
///
/// If the data member is part of an anonymous data member then this
/// returns the absolute offset -- relative to the beginning of the
/// containing class of the anonymous data member.
///
/// @param m the data member to consider.
///
/// @return the aboslute offset of the data member @p m.
uint64_t
get_absolute_data_member_offset(const var_decl& m)
{
  ABG_ASSERT(is_data_member(m));
  const dm_context_rel* ctxt_rel =
    dynamic_cast<const dm_context_rel*>(m.get_context_rel());
  ABG_ASSERT(ctxt_rel);

  const var_decl *containing_anonymous_data_member =
    ctxt_rel->get_anonymous_data_member();

  uint64_t containing_anonymous_data_member_offset = 0;
  if (containing_anonymous_data_member)
    containing_anonymous_data_member_offset =
      get_absolute_data_member_offset(*containing_anonymous_data_member);

  return (ctxt_rel->get_offset_in_bits()
	  +
	  containing_anonymous_data_member_offset);
}

/// Get the absolute offset of a data member.
///
/// If the data member is part of an anonymous data member then this
/// returns the absolute offset -- relative to the beginning of the
/// containing class of the anonymous data member.
///
/// @param m the data member to consider.
///
/// @return the aboslute offset of the data member @p m.
uint64_t
get_absolute_data_member_offset(const var_decl_sptr& m)
{
  if (!m)
    return 0;
  return get_absolute_data_member_offset(*m);
}

/// Get the size of a given variable.
///
/// @param v the variable to consider.
///
/// @return the size of variable @p v.
uint64_t
get_var_size_in_bits(const var_decl_sptr& v)
{
  type_base_sptr t = v->get_type();
  ABG_ASSERT(t);

  return t->get_size_in_bits();
}

/// Set a flag saying if a data member is laid out.
///
/// @param m the data member to consider.
///
/// @param l true if @p m is to be considered as laid out.
void
set_data_member_is_laid_out(var_decl_sptr m, bool l)
{
  ABG_ASSERT(is_data_member(m));
  dm_context_rel* ctxt_rel =
    dynamic_cast<dm_context_rel*>(m->get_context_rel());
  ctxt_rel->set_is_laid_out(l);
}

/// Test whether a data member is laid out.
///
/// @param m the data member to consider.
///
/// @return true if @p m is laid out, false otherwise.
bool
get_data_member_is_laid_out(const var_decl& m)
{
  ABG_ASSERT(is_data_member(m));
  const dm_context_rel* ctxt_rel =
    dynamic_cast<const dm_context_rel*>(m.get_context_rel());

  return ctxt_rel->get_is_laid_out();
}

/// Test whether a data member is laid out.
///
/// @param m the data member to consider.
///
/// @return true if @p m is laid out, false otherwise.
bool
get_data_member_is_laid_out(const var_decl_sptr m)
{return get_data_member_is_laid_out(*m);}

/// Test whether a function_decl is a member function.
///
/// @param f the function_decl to test.
///
/// @return true if @p f is a member function, false otherwise.
bool
is_member_function(const function_decl& f)
{return is_member_decl(f);}

/// Test whether a function_decl is a member function.
///
/// @param f the function_decl to test.
///
/// @return true if @p f is a member function, false otherwise.
bool
is_member_function(const function_decl* f)
{return is_member_decl(*f);}

/// Test whether a function_decl is a member function.
///
/// @param f the function_decl to test.
///
/// @return true if @p f is a member function, false otherwise.
bool
is_member_function(const function_decl_sptr& f)
{return is_member_decl(*f);}

/// Test whether a member function is a constructor.
///
/// @param f the member function to test.
///
/// @return true if @p f is a constructor, false otherwise.
bool
get_member_function_is_ctor(const function_decl& f)
{
  ABG_ASSERT(is_member_function(f));

  const method_decl* m = is_method_decl(&f);
  ABG_ASSERT(m);

  const mem_fn_context_rel* ctxt =
    dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());

  return ctxt->is_constructor();
}

/// Test whether a member function is a constructor.
///
/// @param f the member function to test.
///
/// @return true if @p f is a constructor, false otherwise.
bool
get_member_function_is_ctor(const function_decl_sptr& f)
{return get_member_function_is_ctor(*f);}


/// Setter for the is_ctor property of the member function.
///
/// @param f the member function to set.
///
/// @param f the new boolean value of the is_ctor property.  Is true
/// if @p f is a constructor, false otherwise.
void
set_member_function_is_ctor(function_decl& f, bool c)
{
  ABG_ASSERT(is_member_function(f));

  method_decl* m = is_method_decl(&f);
  ABG_ASSERT(m);

  mem_fn_context_rel* ctxt =
    dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());

  ctxt->is_constructor(c);
}

/// Setter for the is_ctor property of the member function.
///
/// @param f the member function to set.
///
/// @param f the new boolean value of the is_ctor property.  Is true
/// if @p f is a constructor, false otherwise.
void
set_member_function_is_ctor(const function_decl_sptr& f, bool c)
{set_member_function_is_ctor(*f, c);}

/// Test whether a member function is a destructor.
///
/// @param f the function to test.
///
/// @return true if @p f is a destructor, false otherwise.
bool
get_member_function_is_dtor(const function_decl& f)
{
  ABG_ASSERT(is_member_function(f));

  const method_decl* m = is_method_decl(&f);
  ABG_ASSERT(m);

  const mem_fn_context_rel* ctxt =
    dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());

  return ctxt->is_destructor();
}

/// Test whether a member function is a destructor.
///
/// @param f the function to test.
///
/// @return true if @p f is a destructor, false otherwise.
bool
get_member_function_is_dtor(const function_decl_sptr& f)
{return get_member_function_is_dtor(*f);}

/// Set the destructor-ness property of a member function.
///
/// @param f the function to set.
///
/// @param d true if @p f is a destructor, false otherwise.
void
set_member_function_is_dtor(function_decl& f, bool d)
{
    ABG_ASSERT(is_member_function(f));

    method_decl* m = is_method_decl(&f);
  ABG_ASSERT(m);

  mem_fn_context_rel* ctxt =
    dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());

  ctxt->is_destructor(d);
}

/// Set the destructor-ness property of a member function.
///
/// @param f the function to set.
///
/// @param d true if @p f is a destructor, false otherwise.
void
set_member_function_is_dtor(const function_decl_sptr& f, bool d)
{set_member_function_is_dtor(*f, d);}

/// Test whether a member function is const.
///
/// @param f the function to test.
///
/// @return true if @p f is const, false otherwise.
bool
get_member_function_is_const(const function_decl& f)
{
  ABG_ASSERT(is_member_function(f));

  const method_decl* m = is_method_decl(&f);
  ABG_ASSERT(m);

  const mem_fn_context_rel* ctxt =
    dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());

  return ctxt->is_const();
}

/// Test whether a member function is const.
///
/// @param f the function to test.
///
/// @return true if @p f is const, false otherwise.
bool
get_member_function_is_const(const function_decl_sptr& f)
{return get_member_function_is_const(*f);}

/// set the const-ness property of a member function.
///
/// @param f the function to set.
///
/// @param is_const the new value of the const-ness property of @p f
void
set_member_function_is_const(function_decl& f, bool is_const)
{
  ABG_ASSERT(is_member_function(f));

  method_decl* m = is_method_decl(&f);
  ABG_ASSERT(m);

  mem_fn_context_rel* ctxt =
    dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());

  ctxt->is_const(is_const);
}

/// set the const-ness property of a member function.
///
/// @param f the function to set.
///
/// @param is_const the new value of the const-ness property of @p f
void
set_member_function_is_const(const function_decl_sptr& f, bool is_const)
{set_member_function_is_const(*f, is_const);}

/// Test if a virtual member function has a vtable offset set.
///
/// @param f the virtual member function to consider.
///
/// @return true iff the virtual member function has its vtable offset
/// set, i.e, if the vtable offset of @p is different from -1.
bool
member_function_has_vtable_offset(const function_decl& f)
{return get_member_function_vtable_offset(f) != -1;}

/// Get the vtable offset of a member function.
///
/// @param f the member function to consider.
///
/// @return the vtable offset of @p f.  Note that a vtable offset of
/// value -1 means that the member function does *NOT* yet have a
/// vtable offset associated to it.
ssize_t
get_member_function_vtable_offset(const function_decl& f)
{
  ABG_ASSERT(is_member_function(f));

  const method_decl* m =
    dynamic_cast<const method_decl*>(&f);
  ABG_ASSERT(m);

  const mem_fn_context_rel* ctxt =
    dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());

  return ctxt->vtable_offset();
}

/// Get the vtable offset of a member function.
///
/// @param f the member function to consider.
///
/// @return the vtable offset of @p f.  Note that a vtable offset of
/// value -1 means that the member function does *NOT* yet have a
/// vtable offset associated to it.
ssize_t
get_member_function_vtable_offset(const function_decl_sptr& f)
{return get_member_function_vtable_offset(*f);}

/// Set the vtable offset of a member function.
///
/// @param f the member function to consider.
///
/// @param s the new vtable offset.  Please note that a vtable offset
/// of value -1 means that the virtual member function does not (yet)
/// have any vtable offset associated to it.
void
set_member_function_vtable_offset(function_decl& f, ssize_t s)
{
  ABG_ASSERT(is_member_function(f));

  method_decl* m = is_method_decl(&f);
  ABG_ASSERT(m);

  mem_fn_context_rel* ctxt =
    dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());

  ctxt->vtable_offset(s);
}

/// Get the vtable offset of a member function.
///
/// @param f the member function to consider.
///
/// @param s the new vtable offset.  Please note that a vtable offset
/// of value -1 means that the virtual member function does not (yet)
/// have any vtable offset associated to it.
void
set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
{return set_member_function_vtable_offset(*f, s);}

/// Test if a given member function is virtual.
///
/// @param mem_fn the member function to consider.
///
/// @return true iff a @p mem_fn is virtual.
bool
get_member_function_is_virtual(const function_decl& f)
{
  ABG_ASSERT(is_member_function(f));

  const method_decl* m =
    dynamic_cast<const method_decl*>(&f);
  ABG_ASSERT(m);

  const mem_fn_context_rel* ctxt =
    dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());

  return ctxt->is_virtual();
}

/// Test if a given member function is virtual.
///
/// @param mem_fn the member function to consider.
///
/// @return true iff a @p mem_fn is virtual.
bool
get_member_function_is_virtual(const function_decl_sptr& mem_fn)
{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}

/// Test if a given member function is virtual.
///
/// @param mem_fn the member function to consider.
///
/// @return true iff a @p mem_fn is virtual.
bool
get_member_function_is_virtual(const function_decl* mem_fn)
{return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}

/// Set the virtual-ness of a member function.
///
/// @param f the member function to consider.
///
/// @param is_virtual set to true if the function is virtual.
void
set_member_function_is_virtual(function_decl& f, bool is_virtual)
{
  ABG_ASSERT(is_member_function(f));

  method_decl* m = is_method_decl(&f);
  ABG_ASSERT(m);

  mem_fn_context_rel* ctxt =
    dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());

  ctxt->is_virtual(is_virtual);
}

/// Set the virtual-ness of a member function.
///
/// @param f the member function to consider.
///
/// @param is_virtual set to true if the function is virtual.
void
set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
{
  if (fn)
    {
      set_member_function_is_virtual(*fn, is_virtual);
      fixup_virtual_member_function
	(dynamic_pointer_cast<method_decl>(fn));
    }
}

/// Recursively returns the the underlying type of a typedef.  The
/// return type should not be a typedef of anything anymore.
///
///
/// Also recursively strip typedefs from the sub-types of the type
/// given in arguments.
///
/// Note that this function builds types in which typedefs are
/// stripped off.  Usually, types are held by their scope, so their
/// life time is bound to the life time of their scope.  But as this
/// function cannot really insert the built type into it's scope, it
/// must ensure that the newly built type stays live long enough.
///
/// So, if the newly built type has a canonical type, this function
/// returns the canonical type.  Otherwise, this function ensure that
/// the newly built type has a life time that is the same as the life
/// time of the entire libabigail library.
///
/// @param type the type to strip the typedefs from.
///
/// @return the resulting type stripped from its typedefs, or just
/// return @p type if it has no typedef in any of its sub-types.
type_base_sptr
strip_typedef(const type_base_sptr type)
{
  if (!type)
    return type;

  // If type is a class type then do not try to strip typedefs from it.
  // And if it has no canonical type (which can mean that it's a
  // declaration-only class), then, make sure its live for ever and
  // return it.
  if (class_decl_sptr cl = is_class_type(type))
    {
      if (!cl->get_canonical_type())
	keep_type_alive(type);
      return type;
    }

  environment* env = type->get_environment();
  ABG_ASSERT(env);
  type_base_sptr t = type;

  if (const typedef_decl_sptr ty = is_typedef(t))
    t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
  else if (const reference_type_def_sptr ty = is_reference_type(t))
    {
      type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
						    env));
      ABG_ASSERT(p);
      t.reset(new reference_type_def(p,
				     ty->is_lvalue(),
				     ty->get_size_in_bits(),
				     ty->get_alignment_in_bits(),
				     ty->get_location()));
    }
  else if (const pointer_type_def_sptr ty = is_pointer_type(t))
    {
      type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
						    env));
      ABG_ASSERT(p);
      t.reset(new pointer_type_def(p,
				   ty->get_size_in_bits(),
				   ty->get_alignment_in_bits(),
				   ty->get_location()));
    }
  else if (const qualified_type_def_sptr ty = is_qualified_type(t))
    {
      type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
						    env));
      ABG_ASSERT(p);
      t.reset(new qualified_type_def(p,
				     ty->get_cv_quals(),
				     ty->get_location()));
    }
  else if (const array_type_def_sptr ty = is_array_type(t))
    {
      type_base_sptr p = strip_typedef(ty->get_element_type());
      ABG_ASSERT(p);
      t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
    }
  else if (const method_type_sptr ty = is_method_type(t))
    {
      function_decl::parameters parm;
      for (function_decl::parameters::const_iterator i =
	     ty->get_parameters().begin();
	   i != ty->get_parameters().end();
	   ++i)
	{
	  function_decl::parameter_sptr p = *i;
	  type_base_sptr typ = strip_typedef(p->get_type());
	  ABG_ASSERT(typ);
	  function_decl::parameter_sptr stripped
	    (new function_decl::parameter(typ,
					  p->get_index(),
					  p->get_name(),
					  p->get_location(),
					  p->get_variadic_marker(),
					  p->get_is_artificial()));
	  parm.push_back(stripped);
	}
      type_base_sptr p = strip_typedef(ty->get_return_type());
      ABG_ASSERT(!!p == !!ty->get_return_type());
      t.reset(new method_type(p, ty->get_class_type(),
			      parm, ty->get_is_const(),
			      ty->get_size_in_bits(),
			      ty->get_alignment_in_bits()));
    }
  else if (const function_type_sptr ty = is_function_type(t))
    {
      function_decl::parameters parm;
      for (function_decl::parameters::const_iterator i =
	     ty->get_parameters().begin();
	   i != ty->get_parameters().end();
	   ++i)
	{
	  function_decl::parameter_sptr p = *i;
	  type_base_sptr typ = strip_typedef(p->get_type());
	  ABG_ASSERT(typ);
	  function_decl::parameter_sptr stripped
	    (new function_decl::parameter(typ,
					  p->get_index(),
					  p->get_name(),
					  p->get_location(),
					  p->get_variadic_marker(),
					  p->get_is_artificial()));
	  parm.push_back(stripped);
	}
      type_base_sptr p = strip_typedef(ty->get_return_type());
      ABG_ASSERT(!!p == !!ty->get_return_type());
      t.reset(new function_type(p, parm,
				ty->get_size_in_bits(),
				ty->get_alignment_in_bits()));
    }

  if (!t->get_environment())
    set_environment_for_artifact(t, env);

  if (!t->get_translation_unit())
    t->set_translation_unit(type->get_translation_unit());

  if (!(type->get_canonical_type() && canonicalize(t)))
    keep_type_alive(t);

  return t->get_canonical_type() ? t->get_canonical_type() : t;
}

/// Strip qualification from a qualified type, when it makes sense.
///
/// DWARF constructs "const reference".  This is redundant because a
/// reference is always const.  It also constructs the useless "const
/// void" type.  The issue is these redundant types then leak into the
/// IR and make for bad diagnostics.
///
/// This function thus strips the const qualifier from the type in
/// that case.  It might contain code to strip other cases like this
/// in the future.
///
/// @param t the type to strip const qualification from.
///
/// @return the stripped type or just return @p t.
decl_base_sptr
strip_useless_const_qualification(const qualified_type_def_sptr t)
{
  if (!t)
    return t;

  decl_base_sptr result = t;
  type_base_sptr u = t->get_underlying_type();
  environment* env = t->get_environment();

  if ((t->get_cv_quals() & qualified_type_def::CV_CONST
       && (is_reference_type(u)))
      || (t->get_cv_quals() & qualified_type_def::CV_CONST
	  && env->is_void_type(u))
      || t->get_cv_quals() == qualified_type_def::CV_NONE)
    // Let's strip the const qualifier because a reference is always
    // 'const' and a const void doesn't make sense.  They will just
    // lead to spurious changes later down the pipeline, that we'll
    // have to deal with by doing painful and error-prone editing of
    // the diff IR.  Dropping that useless and inconsistent artefact
    // right here seems to be a good way to go.
    result = is_decl(u);

  return result;
}

/// Return the leaf underlying type node of a @ref typedef_decl node.
///
/// If the underlying type of a @ref typedef_decl node is itself a
/// @ref typedef_decl node, then recursively look at the underlying
/// type nodes to get the first one that is not a a @ref typedef_decl
/// node.  This is what a leaf underlying type node means.
///
/// Otherwise, if the underlying type node of @ref typedef_decl is
/// *NOT* a @ref typedef_decl node, then just return the underlying
/// type node.
///
/// And if the type node considered is not a @ref typedef_decl node,
/// then just return it.
///
/// @return the leaf underlying type node of a @p type.
type_base_sptr
peel_typedef_type(const type_base_sptr& type)
{
  typedef_decl_sptr t = is_typedef(type);
  if (!t)
    return type;

  if (is_typedef(t->get_underlying_type()))
    return peel_typedef_type(t->get_underlying_type());
  return t->get_underlying_type();
}

/// Return the leaf underlying type node of a @ref typedef_decl node.
///
/// If the underlying type of a @ref typedef_decl node is itself a
/// @ref typedef_decl node, then recursively look at the underlying
/// type nodes to get the first one that is not a a @ref typedef_decl
/// node.  This is what a leaf underlying type node means.
///
/// Otherwise, if the underlying type node of @ref typedef_decl is
/// *NOT* a @ref typedef_decl node, then just return the underlying
/// type node.
///
/// And if the type node considered is not a @ref typedef_decl node,
/// then just return it.
///
/// @return the leaf underlying type node of a @p type.
const type_base*
peel_typedef_type(const type_base* type)
{
  const typedef_decl* t = is_typedef(type);
  if (!t)
    return type;

  return peel_typedef_type(t->get_underlying_type()).get();
}

/// Return the leaf pointed-to type node of a @ref pointer_type_def
/// node.
///
/// If the pointed-to type of a @ref pointer_type_def node is itself a
/// @ref pointer_type_def node, then recursively look at the
/// pointed-to type nodes to get the first one that is not a a @ref
/// pointer_type_def node.  This is what a leaf pointed-to type node
/// means.
///
/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
/// *NOT* a @ref pointer_type_def node, then just return the
/// pointed-to type node.
///
/// And if the type node considered is not a @ref pointer_type_def
/// node, then just return it.
///
/// @return the leaf pointed-to type node of a @p type.
type_base_sptr
peel_pointer_type(const type_base_sptr& type)
{
  pointer_type_def_sptr t = is_pointer_type(type);
  if (!t)
    return type;

  if (is_pointer_type(t->get_pointed_to_type()))
    return peel_pointer_type(t->get_pointed_to_type());
  return t->get_pointed_to_type();
}

/// Return the leaf pointed-to type node of a @ref pointer_type_def
/// node.
///
/// If the pointed-to type of a @ref pointer_type_def node is itself a
/// @ref pointer_type_def node, then recursively look at the
/// pointed-to type nodes to get the first one that is not a a @ref
/// pointer_type_def node.  This is what a leaf pointed-to type node
/// means.
///
/// Otherwise, if the pointed-to type node of @ref pointer_type_def is
/// *NOT* a @ref pointer_type_def node, then just return the
/// pointed-to type node.
///
/// And if the type node considered is not a @ref pointer_type_def
/// node, then just return it.
///
/// @return the leaf pointed-to type node of a @p type.
const type_base*
peel_pointer_type(const type_base* type)
{
  const pointer_type_def* t = is_pointer_type(type);
  if (!t)
    return type;

  return peel_pointer_type(t->get_pointed_to_type()).get();
}

/// Return the leaf pointed-to type node of a @ref reference_type_def
/// node.
///
/// If the pointed-to type of a @ref reference_type_def node is itself
/// a @ref reference_type_def node, then recursively look at the
/// pointed-to type nodes to get the first one that is not a a @ref
/// reference_type_def node.  This is what a leaf pointed-to type node
/// means.
///
/// Otherwise, if the pointed-to type node of @ref reference_type_def
/// is *NOT* a @ref reference_type_def node, then just return the
/// pointed-to type node.
///
/// And if the type node considered is not a @ref reference_type_def
/// node, then just return it.
///
/// @return the leaf pointed-to type node of a @p type.
type_base_sptr
peel_reference_type(const type_base_sptr& type)
{
  reference_type_def_sptr t = is_reference_type(type);
  if (!t)
    return type;

  if (is_reference_type(t->get_pointed_to_type()))
    return peel_reference_type(t->get_pointed_to_type());
  return t->get_pointed_to_type();
}

/// Return the leaf pointed-to type node of a @ref reference_type_def
/// node.
///
/// If the pointed-to type of a @ref reference_type_def node is itself
/// a @ref reference_type_def node, then recursively look at the
/// pointed-to type nodes to get the first one that is not a a @ref
/// reference_type_def node.  This is what a leaf pointed-to type node
/// means.
///
/// Otherwise, if the pointed-to type node of @ref reference_type_def
/// is *NOT* a @ref reference_type_def node, then just return the
/// pointed-to type node.
///
/// And if the type node considered is not a @ref reference_type_def
/// node, then just return it.
///
/// @return the leaf pointed-to type node of a @p type.
const type_base*
peel_reference_type(const type_base* type)
{
  const reference_type_def* t = is_reference_type(type);
  if (!t)
    return type;

  return peel_reference_type(t->get_pointed_to_type()).get();
}

/// Return the leaf element type of an array.
///
/// If the element type is itself an array, then recursively return
/// the element type of that array itself.
///
/// @param type the array type to consider.  If this is not an array
/// type, this type is returned by the function.
///
/// @return the leaf element type of the array @p type, or, if it's
/// not an array type, then just return @p.
const type_base_sptr
peel_array_type(const type_base_sptr& type)
{
  const array_type_def_sptr t = is_array_type(type);
  if (!t)
    return type;

  return peel_array_type(t->get_element_type());
}

/// Return the leaf element type of an array.
///
/// If the element type is itself an array, then recursively return
/// the element type of that array itself.
///
/// @param type the array type to consider.  If this is not an array
/// type, this type is returned by the function.
///
/// @return the leaf element type of the array @p type, or, if it's
/// not an array type, then just return @p.
const type_base*
peel_array_type(const type_base* type)
{
  const array_type_def* t = is_array_type(type);
  if (!t)
    return type;

  return peel_array_type(t->get_element_type()).get();
}

/// Return the leaf underlying type of a qualified type.
///
/// If the underlying type is itself a qualified type, then
/// recursively return the first underlying type of that qualified
/// type to return the first underlying type that is not a qualified type.
///
/// If the underlying type is NOT a qualified type, then just return
/// that underlying type.
///
/// @param type the qualified type to consider.
///
/// @return the leaf underlying type.
const type_base*
peel_qualified_type(const type_base* type)
{
  const qualified_type_def* t = is_qualified_type(type);
  if (!t)
    return type;

  return peel_qualified_type(t->get_underlying_type().get());
}

/// Return the leaf underlying type of a qualified type.
///
/// If the underlying type is itself a qualified type, then
/// recursively return the first underlying type of that qualified
/// type to return the first underlying type that is not a qualified type.
///
/// If the underlying type is NOT a qualified type, then just return
/// that underlying type.
///
/// @param type the qualified type to consider.
///
/// @return the leaf underlying type.
const type_base_sptr
peel_qualified_type(const type_base_sptr& type)
{
  const qualified_type_def_sptr t = is_qualified_type(type);
  if (!t)
    return type;

  return peel_qualified_type(t->get_underlying_type());
}

/// Return the leaf underlying type of a qualified or typedef type.
///
/// If the underlying type is itself a qualified or typedef type, then
/// recursively return the first underlying type of that qualified or
/// typedef type to return the first underlying type that is not a
/// qualified or typedef type.
///
/// If the underlying type is NOT a qualified nor a typedef type, then
/// just return that underlying type.
///
/// @param type the qualified or typedef type to consider.
///
/// @return the leaf underlying type.
type_base*
peel_qualified_or_typedef_type(const type_base* type)
{
  while (is_typedef(type) || is_qualified_type(type))
    {
      if (const typedef_decl* t = is_typedef(type))
	type = peel_typedef_type(t);

      if (const qualified_type_def* t = is_qualified_type(type))
	type = peel_qualified_type(t);
    }

  return const_cast<type_base*>(type);
}

/// Return the leaf underlying type of a qualified or typedef type.
///
/// If the underlying type is itself a qualified or typedef type, then
/// recursively return the first underlying type of that qualified or
/// typedef type to return the first underlying type that is not a
/// qualified or typedef type.
///
/// If the underlying type is NOT a qualified nor a typedef type, then
/// just return that underlying type.
///
/// @param type the qualified or typedef type to consider.
///
/// @return the leaf underlying type.
type_base_sptr
peel_qualified_or_typedef_type(const type_base_sptr &t)
{
  type_base_sptr type = t;
  while (is_typedef(type) || is_qualified_type(type))
    {
      if (typedef_decl_sptr t = is_typedef(type))
	type = peel_typedef_type(t);

      if (qualified_type_def_sptr t = is_qualified_type(type))
	type = peel_qualified_type(t);
    }

  return type;
}

/// Return the leaf underlying or pointed-to type node of a @ref
/// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
/// or @ref array_type_def node.
///
/// @param type the type to peel.
///
/// @return the leaf underlying or pointed-to type node of @p type.
type_base_sptr
peel_typedef_pointer_or_reference_type(const type_base_sptr type)
{
  type_base_sptr typ = type;
  while (is_typedef(typ)
	 || is_pointer_type(typ)
	 || is_reference_type(typ)
	 || is_array_type(typ))
    {
      if (typedef_decl_sptr t = is_typedef(typ))
	typ = peel_typedef_type(t);

      if (pointer_type_def_sptr t = is_pointer_type(typ))
	typ = peel_pointer_type(t);

      if (reference_type_def_sptr t = is_reference_type(typ))
	typ = peel_reference_type(t);

      if (const array_type_def_sptr t = is_array_type(typ))
	typ = peel_array_type(t);
    }

  return typ;
}

/// Return the leaf underlying or pointed-to type node of a @ref
/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
/// node.
///
/// @param type the type to peel.
///
/// @return the leaf underlying or pointed-to type node of @p type.
type_base*
peel_typedef_pointer_or_reference_type(const type_base* type)
{
  while (is_typedef(type)
	 || is_pointer_type(type)
	 || is_reference_type(type)
	 || is_array_type(type))
    {
      if (const typedef_decl* t = is_typedef(type))
	type = peel_typedef_type(t);

      if (const pointer_type_def* t = is_pointer_type(type))
	type = peel_pointer_type(t);

      if (const reference_type_def* t = is_reference_type(type))
	type = peel_reference_type(t);

      if (const array_type_def* t = is_array_type(type))
	type = peel_array_type(t);
    }

  return const_cast<type_base*>(type);
}

/// Return the leaf underlying or pointed-to type node of a, @ref
/// pointer_type_def, @ref reference_type_def or @ref
/// qualified_type_def type node.
///
/// @param type the type to peel.
///
/// @param peel_qualified_type if true, also peel qualified types.
///
/// @return the leaf underlying or pointed-to type node of @p type.
type_base*
peel_pointer_or_reference_type(const type_base *type,
			       bool peel_qual_type)
{
  while (is_pointer_type(type)
	 || is_reference_type(type)
	 || is_array_type(type)
	 || (peel_qual_type && is_qualified_type(type)))
    {
      if (const pointer_type_def* t = is_pointer_type(type))
	type = peel_pointer_type(t);

      if (const reference_type_def* t = is_reference_type(type))
	type = peel_reference_type(t);

      if (const array_type_def* t = is_array_type(type))
	type = peel_array_type(t);

      if (peel_qual_type)
	if (const qualified_type_def* t = is_qualified_type(type))
	  type = peel_qualified_type(t);
    }

  return const_cast<type_base*>(type);
}

/// Clone an array type.
///
/// Note that the element type of the new array is shared witht the
/// old one.
///
/// @param array the array type to clone.
///
/// @return a newly built array type.  Note that it needs to be added
/// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
/// bound to the one of that scope.  Otherwise, its lifetime is bound
/// to the lifetime of its containing shared pointer.
array_type_def_sptr
clone_array(const array_type_def_sptr& array)
{
  vector<array_type_def::subrange_sptr> subranges;

  for (vector<array_type_def::subrange_sptr>::const_iterator i =
	 array->get_subranges().begin();
       i != array->get_subranges().end();
       ++i)
    {
      array_type_def::subrange_sptr subrange
	(new array_type_def::subrange_type(array->get_environment(),
					   (*i)->get_name(),
					   (*i)->get_lower_bound(),
					   (*i)->get_upper_bound(),
					   (*i)->get_underlying_type(),
					   (*i)->get_location(),
					   (*i)->get_language()));
      subrange->is_infinite((*i)->is_infinite());
      if (scope_decl *scope = (*i)->get_scope())
	add_decl_to_scope(subrange, scope);
      subranges.push_back(subrange);
    }

  array_type_def_sptr result
    (new array_type_def(array->get_element_type(),
			subranges, array->get_location()));

  return result;
}

/// Clone a typedef type.
///
/// Note that the underlying type of the newly constructed typedef is
/// shared with the old one.
///
/// @param t the typedef to clone.
///
/// @return the newly constructed typedef.  Note that it needs to be
/// added to a scope (e.g, using add_decl_to_scope) for its lifetime
/// to be bound to the one of that scope.  Otherwise, its lifetime is
/// bound to the lifetime of its containing shared pointer.
typedef_decl_sptr
clone_typedef(const typedef_decl_sptr& t)
{
  if (!t)
    return t;

  typedef_decl_sptr result
    (new typedef_decl(t->get_name(), t->get_underlying_type(),
		      t->get_location(), t->get_linkage_name(),
		      t->get_visibility()));
  return result;
}

/// Clone a qualifiend type.
///
/// Note that underlying type of the newly constructed qualified type
/// is shared with the old one.
///
/// @param t the qualified type to clone.
///
/// @return the newly constructed qualified type.  Note that it needs
/// to be added to a scope (e.g, using add_decl_to_scope) for its
/// lifetime to be bound to the one of that scope.  Otherwise, its
/// lifetime is bound to the lifetime of its containing shared
/// pointer.
qualified_type_def_sptr
clone_qualified_type(const qualified_type_def_sptr& t)
{
  if (!t)
    return t;

  qualified_type_def_sptr result
    (new qualified_type_def(t->get_underlying_type(),
			    t->get_cv_quals(), t->get_location()));

  return result;
}

/// Clone a typedef, an array or a qualified tree.
///
/// @param type the typedef, array or qualified tree to clone.  any
/// order.
///
/// @return the cloned type, or NULL if @type was neither a typedef,
/// array nor a qualified type.
static type_base_sptr
clone_typedef_array_qualified_type(type_base_sptr type)
{
  if (!type)
    return type;

  scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
  type_base_sptr result;

  if (typedef_decl_sptr t = is_typedef(type))
    result = clone_typedef(is_typedef(t));
  else if (qualified_type_def_sptr t = is_qualified_type(type))
    result = clone_qualified_type(t);
  else if (array_type_def_sptr t = is_array_type(type))
    result = clone_array(t);
  else
    return type_base_sptr();

  if (scope)
    add_decl_to_scope(is_decl(result), scope);

  return result;
}

/// Clone a type tree made of an array or a typedef of array.
///
/// Note that this can be a tree which root node is a typedef an which
/// sub-tree can be any arbitrary combination of typedef, qualified
/// type and arrays.
///
/// @param t the array or typedef of qualified array to consider.
///
/// @return a clone of @p t.
type_base_sptr
clone_array_tree(const type_base_sptr t)
{
  ABG_ASSERT(is_typedef_of_array(t) || is_array_type(t));

  scope_decl* scope = is_decl(t)->get_scope();
  type_base_sptr result = clone_typedef_array_qualified_type(t);
  ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));

  type_base_sptr subtree;
  if (typedef_decl_sptr type = is_typedef(result))
    {
      type_base_sptr s =
	clone_typedef_array_qualified_type(type->get_underlying_type());
      if (s)
	{
	  subtree = s;
	  type->set_underlying_type(subtree);
	}
    }
  else if (array_type_def_sptr type = is_array_type(result))
    {
      type_base_sptr s =
	clone_typedef_array_qualified_type(type->get_element_type());
      if (s)
	{
	  subtree = s;
	  type->set_element_type(subtree);
	}
    }
  add_decl_to_scope(is_decl(subtree), scope);

  for (;;)
    {
      if (typedef_decl_sptr t = is_typedef(subtree))
	{
	  type_base_sptr s =
	    clone_typedef_array_qualified_type(t->get_underlying_type());
	  if (s)
	    {
	      scope_decl* scope =
		is_decl(t->get_underlying_type())->get_scope();
	      ABG_ASSERT(scope);
	      add_decl_to_scope(is_decl(s), scope);
	      t->set_underlying_type (s);
	      subtree = s;
	    }
	  else
	    break;
	}
      else if (qualified_type_def_sptr t = is_qualified_type(subtree))
	{
	  type_base_sptr s =
	    clone_typedef_array_qualified_type(t->get_underlying_type());
	  if (s)
	    {
	      scope_decl* scope =
		is_decl(t->get_underlying_type())->get_scope();
	      ABG_ASSERT(scope);
	      add_decl_to_scope(is_decl(s), scope);
	      t->set_underlying_type(s);
	      subtree = s;
	    }
	  else
	    break;
	}
      else if (array_type_def_sptr t = is_array_type(subtree))
	{
	  type_base_sptr e = t->get_element_type();
	  if (is_typedef(e) || is_qualified_type(e))
	    {
	      type_base_sptr s =
		clone_typedef_array_qualified_type(e);
	      if (s)
		{
		  scope_decl* scope = is_decl(e)->get_scope();
		  ABG_ASSERT(scope);
		  add_decl_to_scope(is_decl(s), scope);
		  t->set_element_type(s);
		}
	      else
		break;
	    }
	  break;
	}
      else
	break;
    }
  return result;
}

/// Update the qualified name of a given sub-tree.
///
/// @param d the sub-tree for which to update the qualified name.
static void
update_qualified_name(decl_base * d)
{
  ::qualified_name_setter setter;
  d->traverse(setter);
}

/// Update the qualified name of a given sub-tree.
///
/// @param d the sub-tree for which to update the qualified name.
static void
update_qualified_name(decl_base_sptr d)
{return update_qualified_name(d.get());}

// <scope_decl stuff>

/// Hash a type by returning the pointer value of its canonical type.
///
/// @param l the type to hash.
///
/// @return the the pointer value of the canonical type of @p l.
size_t
canonical_type_hash::operator()(const type_base_sptr& l) const
{return operator()(l.get());}

/// Hash a (canonical) type by returning its pointer value
///
/// @param l the canonical type to hash.
///
/// @return the pointer value of the canonical type of @p l.
size_t
canonical_type_hash::operator()(const type_base *l) const
{return reinterpret_cast<size_t>(l);}

struct scope_decl::priv
{
  declarations members_;
  declarations sorted_members_;
  scopes member_scopes_;
  canonical_type_sptr_set_type canonical_types_;
  type_base_sptrs_type sorted_canonical_types_;
}; // end struct scope_decl::priv

/// Constructor of the @ref scope_decl type.
///
/// @param the environment to use for the new instance.
///
/// @param the name of the scope decl.
///
/// @param locus the source location where the scope_decl is defined.
///
/// @param vis the visibility of the declaration.
scope_decl::scope_decl(const environment* env,
		       const string& name,
		       const location& locus,
		       visibility vis)
  : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
    decl_base(env, name, locus, /*mangled_name=*/name, vis),
    priv_(new priv)
{}

/// Constructor of the @ref scope_decl type.
///
/// @param the environment to use for the new instance.
///
/// @param l the source location where the scope_decl is defined.
///
/// @param vis the visibility of the declaration.
scope_decl::scope_decl(const environment* env, location& l)
  : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
    decl_base(env, "", l),
    priv_(new priv)
{}

/// @eturn the set of canonical types of the the current scope.
canonical_type_sptr_set_type&
scope_decl::get_canonical_types()
{return priv_->canonical_types_;}

/// @eturn the set of canonical types of the the current scope.
const canonical_type_sptr_set_type&
scope_decl::get_canonical_types() const
{return const_cast<scope_decl*>(this)->get_canonical_types();}

/// Return a vector of sorted canonical types of the current scope.
///
/// The types are sorted "almost topologically". That means, they are
/// sorted using the lexicographic order of the string representing
/// the location their definition point.  If a type doesn't have a
/// location, then its pretty representation is used.
///
/// @return a vector of sorted canonical types of the current scope.
const type_base_sptrs_type&
scope_decl::get_sorted_canonical_types() const
{
  if (priv_->sorted_canonical_types_.empty())
    {
      for (canonical_type_sptr_set_type::const_iterator e =
	     get_canonical_types().begin();
	   e != get_canonical_types().end();
	   ++e)
	priv_->sorted_canonical_types_.push_back(*e);

      type_topo_comp comp;
      std::stable_sort(priv_->sorted_canonical_types_.begin(),
		       priv_->sorted_canonical_types_.end(),
		       comp);
    }
  return priv_->sorted_canonical_types_;
}

/// Getter for the member declarations carried by the current @ref
/// scope_decl.
///
/// @return the member declarations carried by the current @ref
/// scope_decl.
const scope_decl::declarations&
scope_decl::get_member_decls() const
{return priv_->members_;}

/// Getter for the member declarations carried by the current @ref
/// scope_decl.
///
/// @return the member declarations carried by the current @ref
/// scope_decl.
scope_decl::declarations&
scope_decl::get_member_decls()
{return priv_->members_;}

/// Getter for the sorted member declarations carried by the current
/// @ref scope_decl.
///
/// @return the sorted member declarations carried by the current @ref
/// scope_decl.  The declarations are sorted topologically.
const scope_decl::declarations&
scope_decl::get_sorted_member_decls() const
{
  decl_topo_comp comp;
  if (priv_->sorted_members_.empty())
    {
      for (declarations::const_iterator i = get_member_decls().begin();
	   i != get_member_decls().end();
	   ++i)
	priv_->sorted_members_.push_back(*i);

      std::stable_sort(priv_->sorted_members_.begin(),
		       priv_->sorted_members_.end(),
		       comp);
    }
  return priv_->sorted_members_;
}

/// Getter for the number of anonymous classes contained in this
/// scope.
///
/// @return the number of anonymous classes contained in this scope.
size_t
scope_decl::get_num_anonymous_member_classes() const
{
  int result = 0;
  for (declarations::const_iterator it = get_member_decls().begin();
       it != get_member_decls().end();
       ++it)
    if (class_decl_sptr t = is_class_type(*it))
      if (t->get_is_anonymous())
	++result;

  return result;
}

/// Getter for the number of anonymous unions contained in this
/// scope.
///
/// @return the number of anonymous unions contained in this scope.
size_t
scope_decl::get_num_anonymous_member_unions() const
{
  int result = 0;
  for (declarations::const_iterator it = get_member_decls().begin();
       it != get_member_decls().end();
       ++it)
    if (union_decl_sptr t = is_union_type(*it))
      if (t->get_is_anonymous())
	++result;

  return result;
}

/// Getter for the number of anonymous enums contained in this
/// scope.
///
/// @return the number of anonymous enums contained in this scope.
size_t
scope_decl::get_num_anonymous_member_enums() const
{
  int result = 0;
  for (declarations::const_iterator it = get_member_decls().begin();
       it != get_member_decls().end();
       ++it)
    if (enum_type_decl_sptr t = is_enum_type(*it))
      if (t->get_is_anonymous())
	++result;

  return result;
}

/// Getter for the scopes carried by the current scope.
///
/// @return the scopes carried by the current scope.
scope_decl::scopes&
scope_decl::get_member_scopes()
{return priv_->member_scopes_;}

/// Getter for the scopes carried by the current scope.
///
/// @return the scopes carried by the current scope.
const scope_decl::scopes&
scope_decl::get_member_scopes() const
{return priv_->member_scopes_;}

/// Test if the current scope is empty.
///
/// @return true iff the current scope is empty.
bool
scope_decl::is_empty() const
{
  return (get_member_decls().empty()
	  && get_canonical_types().empty());
}

/// Add a member decl to this scope.  Note that user code should not
/// use this, but rather use add_decl_to_scope.
///
/// Note that this function updates the qualified name of the member
/// decl that is added.  It also sets the scope of the member.  Thus,
/// it ABG_ASSERTs that member should not have its scope set, prior to
/// calling this function.
///
/// @param member the new member decl to add to this scope.
decl_base_sptr
scope_decl::add_member_decl(const decl_base_sptr& member)
{
  ABG_ASSERT(!has_scope(member));

  member->set_scope(this);
  priv_->members_.push_back(member);

  if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
    priv_->member_scopes_.push_back(m);

  update_qualified_name(member);

  if (const environment* env = get_environment())
    set_environment_for_artifact(member, env);

  if (translation_unit* tu = get_translation_unit())
    {
      if (translation_unit* existing_tu = member->get_translation_unit())
	ABG_ASSERT(tu == existing_tu);
      else
	member->set_translation_unit(tu);
    }

  maybe_update_types_lookup_map(member);

  return member;
}

/// Insert a member decl to this scope, right before an element
/// pointed to by a given iterator.  Note that user code should not
/// use this, but rather use insert_decl_into_scope.
///
/// Note that this function updates the qualified name of the inserted
/// member.
///
/// @param member the new member decl to add to this scope.
///
/// @param before an interator pointing to the element before which
/// the new member should be inserted.
decl_base_sptr
scope_decl::insert_member_decl(decl_base_sptr member,
			       declarations::iterator before)
{
  ABG_ASSERT(!member->get_scope());

  member->set_scope(this);
  priv_->members_.insert(before, member);

  if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
   priv_-> member_scopes_.push_back(m);

  update_qualified_name(member);

  if (const environment* env = get_environment())
    set_environment_for_artifact(member, env);

  if (translation_unit* tu = get_translation_unit())
    {
      if (translation_unit* existing_tu = member->get_translation_unit())
	ABG_ASSERT(tu == existing_tu);
      else
	member->set_translation_unit(tu);
    }

  maybe_update_types_lookup_map(member);

  return member;
}

/// Remove a declaration from the current scope.
///
/// @param member the declaration to remove from the scope.
void
scope_decl::remove_member_decl(decl_base_sptr member)
{
  for (declarations::iterator i = priv_->members_.begin();
       i != priv_->members_.end();
       ++i)
    {
      if (**i == *member)
	{
	  priv_->members_.erase(i);
	  // Do not access i after this point as it's invalided by the
	  // erase call.
	  break;
	}
    }

  scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
  if (scope)
    {
      for (scopes::iterator i = priv_->member_scopes_.begin();
	   i != priv_->member_scopes_.end();
	   ++i)
	{
	  if (**i == *member)
	    {
	      priv_->member_scopes_.erase(i);
	      break;
	    }
	}
    }
}

/// Return the hash value for the current instance of scope_decl.
///
/// This method can trigger the computing of the hash value, if need be.
///
/// @return the hash value.
size_t
scope_decl::get_hash() const
{
  scope_decl::hash hash_scope;
  return hash_scope(this);
}

/// Compares two instances of @ref scope_decl.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const scope_decl& l, const scope_decl& r, change_kind* k)
{
  bool result = true;

  if (!l.decl_base::operator==(r))
    {
      result = false;
      if (k)
	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }

  scope_decl::declarations::const_iterator i, j;
  for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
       i != l.get_member_decls().end() && j != r.get_member_decls().end();
       ++i, ++j)
    {
      if (**i != **j)
	{
	  result = false;
	  if (k)
	    {
	      *k |= SUBTYPE_CHANGE_KIND;
	      break;
	    }
	  else
	    ABG_RETURN_FALSE;
	}
    }

  if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
    {
      result = false;
      if (k)
	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }

  ABG_RETURN(result);
}

/// Return true iff both scopes have the same names and have the same
/// member decls.
///
/// This function doesn't check for equality of the scopes of its
/// arguments.
bool
scope_decl::operator==(const decl_base& o) const
{
  const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
  if (!other)
    return false;

  return equals(*this, *other, 0);
}

/// Equality operator for @ref scope_decl_sptr.
///
/// @param l the left hand side operand of the equality operator.
///
/// @pram r the right hand side operand of the equalify operator.
///
/// @return true iff @p l equals @p r.
bool
operator==(const scope_decl_sptr& l, const scope_decl_sptr& r)
{
  if (!!l != !!r)
    return false;
  if (l.get() == r.get())
    return true;
  return *l == *r;
}

/// Inequality operator for @ref scope_decl_sptr.
///
/// @param l the left hand side operand of the equality operator.
///
/// @pram r the right hand side operand of the equalify operator.
///
/// @return true iff @p l equals @p r.
bool
operator!=(const scope_decl_sptr& l, const scope_decl_sptr& r)
{return !operator==(l, r);}

/// Find a member of the current scope and return an iterator on it.
///
/// @param decl the scope member to find.
///
/// @param i the iterator to set to the member @p decl.  This is set
/// iff the function returns true.
///
/// @return true if the member decl was found, false otherwise.
bool
scope_decl::find_iterator_for_member(const decl_base* decl,
				     declarations::iterator& i)
{
  if (!decl)
    return false;

  if (get_member_decls().empty())
    {
      i = get_member_decls().end();
      return false;
    }

  for (declarations::iterator it = get_member_decls().begin();
       it != get_member_decls().end();
       ++it)
    {
      if ((*it).get() == decl)
	{
	  i = it;
	  return true;
	}
    }

  return false;
}

/// Find a member of the current scope and return an iterator on it.
///
/// @param decl the scope member to find.
///
/// @param i the iterator to set to the member @p decl.  This is set
/// iff the function returns true.
///
/// @return true if the member decl was found, false otherwise.
bool
scope_decl::find_iterator_for_member(const decl_base_sptr decl,
				     declarations::iterator& i)
{return find_iterator_for_member(decl.get(), i);}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance of scope_decl
/// and on its member nodes.
///
/// @return true if the traversal of the tree should continue, false
/// otherwise.
bool
scope_decl::traverse(ir_node_visitor &v)
{
  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      for (scope_decl::declarations::const_iterator i =
	     get_member_decls().begin();
	   i != get_member_decls ().end();
	   ++i)
	if (!(*i)->traverse(v))
	  break;
      visiting(false);
    }
  return v.visit_end(this);
}

scope_decl::~scope_decl()
{}

/// Appends a declaration to a given scope, if the declaration
/// doesn't already belong to one.
///
/// @param decl the declaration to add to the scope
///
/// @param scope the scope to append the declaration to
decl_base_sptr
add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
{
  ABG_ASSERT(scope);

  if (scope && decl && !decl->get_scope())
    decl = scope->add_member_decl(decl);

  return decl;
}

/// Appends a declaration to a given scope, if the declaration doesn't
/// already belong to a scope.
///
/// @param decl the declaration to add append to the scope
///
/// @param scope the scope to append the decl to
decl_base_sptr
add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
{return add_decl_to_scope(decl, scope.get());}

/// Remove a given decl from its scope
///
/// @param decl the decl to remove from its scope.
void
remove_decl_from_scope(decl_base_sptr decl)
{
  if (!decl)
    return;

  scope_decl* scope = decl->get_scope();
  scope->remove_member_decl(decl);
  decl->set_scope(0);
}

/// Inserts a declaration into a given scope, before a given IR child
/// node of the scope.
///
/// @param decl the declaration to insert into the scope.
///
/// @param before an iterator pointing to the child IR node before
/// which to insert the declaration.
///
/// @param scope the scope into which to insert the declaration.
decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,
		       scope_decl::declarations::iterator before,
		       scope_decl* scope)
{
  if (scope && decl && !decl->get_scope())
    {
      decl_base_sptr d = scope->insert_member_decl(decl, before);
      decl = d;
    }
  return decl;
}

/// Inserts a declaration into a given scope, before a given IR child
/// node of the scope.
///
/// @param decl the declaration to insert into the scope.
///
/// @param before an iterator pointing to the child IR node before
/// which to insert the declaration.
///
/// @param scope the scope into which to insert the declaration.
decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,
		       scope_decl::declarations::iterator before,
		       scope_decl_sptr scope)
{return insert_decl_into_scope(decl, before, scope.get());}

/// Constructor of the @ref global_scope type.
///
/// @param tu the translation unit the scope belongs to.
global_scope::global_scope(translation_unit *tu)
  : type_or_decl_base(tu->get_environment(),
		      GLOBAL_SCOPE_DECL
		      | ABSTRACT_DECL_BASE
		      | ABSTRACT_SCOPE_DECL),
    decl_base(tu->get_environment(), "", location()),
    scope_decl(tu->get_environment(), "", location()),
    translation_unit_(tu)
{
  runtime_type_instance(this);
}

/// return the global scope as seen by a given declaration.
///
/// @param decl the declaration to consider.
///
/// @return the global scope of the decl, or a null pointer if the
/// decl is not yet added to a translation_unit.
const global_scope*
get_global_scope(const decl_base& decl)
{
  if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
    return s;

  scope_decl* scope = decl.get_scope();
  while (scope && !dynamic_cast<global_scope*>(scope))
    scope = scope->get_scope();

  return scope ? dynamic_cast<global_scope*> (scope) : 0;
}

/// return the global scope as seen by a given declaration.
///
/// @param decl the declaration to consider.
///
/// @return the global scope of the decl, or a null pointer if the
/// decl is not yet added to a translation_unit.
const global_scope*
get_global_scope(const decl_base* decl)
{return get_global_scope(*decl);}

/// Return the global scope as seen by a given declaration.
///
/// @param decl the declaration to consider.
///
/// @return the global scope of the decl, or a null pointer if the
/// decl is not yet added to a translation_unit.
const global_scope*
get_global_scope(const shared_ptr<decl_base> decl)
{return get_global_scope(decl.get());}

/// Return the a scope S containing a given declaration and that is
/// right under a given scope P.
///
/// Note that @p scope must come before @p decl in topological
/// order.
///
/// @param decl the decl for which to find a scope.
///
/// @param scope the scope under which the resulting scope must be.
///
/// @return the resulting scope.
const scope_decl*
get_top_most_scope_under(const decl_base* decl,
			 const scope_decl* scope)
{
  if (!decl)
    return 0;

  if (scope == 0)
    return get_global_scope(decl);

  // Handle the case where decl is a scope itself.
  const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
  if (!s)
    s = decl->get_scope();

  if (is_global_scope(s))
    return scope;

  // Here, decl is in the scope 'scope', or decl and 'scope' are the
  // same.  The caller needs to be prepared to deal with this case.
  if (s == scope)
    return s;

  while (s && !is_global_scope(s) && s->get_scope() != scope)
    s = s->get_scope();

  if (!s || is_global_scope(s))
    // SCOPE must come before decl in topological order, but I don't
    // know how to ensure that ...
    return scope;
  ABG_ASSERT(s);

  return s;
}

/// Return the a scope S containing a given declaration and that is
/// right under a given scope P.
///
/// @param decl the decl for which to find a scope.
///
/// @param scope the scope under which the resulting scope must be.
///
/// @return the resulting scope.
const scope_decl*
get_top_most_scope_under(const decl_base_sptr decl,
			 const scope_decl* scope)
{return get_top_most_scope_under(decl.get(), scope);}

/// Return the a scope S containing a given declaration and that is
/// right under a given scope P.
///
/// @param decl the decl for which to find a scope.
///
/// @param scope the scope under which the resulting scope must be.
///
/// @return the resulting scope.
const scope_decl*
get_top_most_scope_under(const decl_base_sptr decl,
			 const scope_decl_sptr scope)
{return get_top_most_scope_under(decl, scope.get());}

// </scope_decl stuff>


/// Get the string representation of a CV qualifier bitmap.
///
/// @param cv_quals the bitmap of CV qualifiers to consider.
///
/// @return the string representation.
string
get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)
{
  string repr;
  if (cv_quals & qualified_type_def::CV_RESTRICT)
    repr = "restrict";
  if (cv_quals & qualified_type_def::CV_CONST)
    {
      if (!repr.empty())
	repr += ' ';
      repr += "const";
    }
  if (cv_quals & qualified_type_def::CV_VOLATILE)
    {
      if (!repr.empty())
	repr += ' ';
      repr += "volatile";
    }
  return repr;
}

/// Build and return a copy of the name of an ABI artifact that is
/// either a type or a decl.
///
/// @param tod the ABI artifact to get the name for.
///
/// @param qualified if yes, return the qualified name of @p tod;
/// otherwise, return the non-qualified name;
///
/// @return the name of @p tod.
string
get_name(const type_or_decl_base *tod, bool qualified)
{
  string result;

  type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);

  if (type_base* t = dynamic_cast<type_base*>(a))
    result = get_type_name(t, qualified);
  else if (decl_base *d = dynamic_cast<decl_base*>(a))
    {
      if (qualified)
	result = d->get_qualified_name();
      else
	result = d->get_name();
    }
  else
    // We should never reach this point.
    abort();

  return result;
}

/// Build and return a copy of the name of an ABI artifact that is
/// either a type of a decl.
///
/// @param tod the ABI artifact to get the name for.
///
/// @param qualified if yes, return the qualified name of @p tod;
/// otherwise, return the non-qualified name;
///
/// @return the name of @p tod.
string
get_name(const type_or_decl_base_sptr& tod, bool qualified)
{return get_name(tod.get(), qualified);}

/// Build and return a qualified name from a name and its scope.
///
/// The name is supposed to be for an entity that is part of the
/// scope.
///
/// @param the scope to consider.
///
/// @param name of the name to consider.
///
/// @return a copy of the string that represents the qualified name.
string
build_qualified_name(const scope_decl* scope, const string& name)
{
  if (name.empty())
    return "";

  string qualified_name;
  if (scope)
    qualified_name = scope->get_qualified_name();

  if (qualified_name.empty())
    qualified_name = name;
  else
    qualified_name = qualified_name + "::" + name;

  return qualified_name;
}

/// Build and return the qualified name of a type in its scope.
///
/// @param scope the scope of the type to consider.
///
/// @param type the type to consider.
string
build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
{return build_qualified_name(scope, get_name((type)));}

// </scope_decl stuff>

/// Get the location of the declaration of a given type.
///
/// @param type the type to consider.
///
/// @return the location of the declaration of type @p type.
location
get_location(const type_base_sptr& type)
{
  if (decl_base_sptr decl = get_type_declaration(type))
    return get_location(decl);
  return location();
}

/// Get the location of a given declaration.
///
/// @param decl the declaration to consider.
///
/// @return the location of the declaration @p decl.
location
get_location(const decl_base_sptr& decl)
{
  location loc = decl->get_location();
  if (!loc)
    {
      if (class_or_union_sptr c = is_class_or_union_type(decl))
	if (c->get_is_declaration_only() && c->get_definition_of_declaration())
	  {
	    c = is_class_or_union_type(c->get_definition_of_declaration());
	    loc = c->get_location();
	  }
    }
  return loc;
}

/// Get the scope of a given type.
///
/// @param t the type to consider.
///
/// @return the scope of type @p t or 0 if the type has no scope yet.
scope_decl*
get_type_scope(type_base* t)
{
  if (!t)
    return 0;

  decl_base* d = get_type_declaration(t);
  if (d)
    return d->get_scope();
  return 0;
}

/// Get the scope of a given type.
///
/// @param t the type to consider.
///
/// @return the scope of type @p t or 0 if the type has no scope yet.
scope_decl*
get_type_scope(const type_base_sptr& t)
{return get_type_scope(t.get());}

/// Get the name of a given type and return a copy of it.
///
/// @param t the type to consider.
///
/// @param qualified if true then return the qualified name of the
/// type.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return a copy of the type name if the type has a name, or the
/// empty string if it does not.
interned_string
get_type_name(const type_base_sptr& t, bool qualified, bool internal)
{return get_type_name(t.get(), qualified, internal);}

/// Return true iff a decl is for a type type that has a generic
/// anonymous internal type name.
///
/// @param d the decl to considier.
///
/// @return true iff @p d is for a type type that has a generic
/// anonymous internal type name.
static bool
has_generic_anonymous_internal_type_name(const decl_base *d)
{
  return is_class_or_union_type(d) || is_enum_type(d);
}

/// Return the generic internal name of an anonymous type.
///
/// For internal purposes, we want to define a generic name for all
/// anonymous types of a certain kind.  For instance, all anonymous
/// structs will be have a generic name of "__anonymous_struct__", all
/// anonymous unions will have a generic name of
/// "__anonymous_union__", etc.
///
/// That generic name can be used as a hash to put all anonymous types
/// of a certain kind in the same hash table bucket, for instance.
static interned_string
get_generic_anonymous_internal_type_name(const decl_base *d)
{
  ABG_ASSERT(has_generic_anonymous_internal_type_name(d));

  const environment *env = d->get_environment();

  interned_string result;
  if (is_class_type(d))
    result =
      env->intern(tools_utils::get_anonymous_struct_internal_name_prefix());
  else if (is_union_type(d))
    result =
      env->intern(tools_utils::get_anonymous_union_internal_name_prefix());
  else if (is_enum_type(d))
    result =
      env->intern(tools_utils::get_anonymous_enum_internal_name_prefix());
  else
    ABG_ASSERT_NOT_REACHED;

  return result;
}

/// Get the name of a given type and return a copy of it.
///
/// @param t the type to consider.
///
/// @param qualified if true then return the qualified name of the
/// type.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return a copy of the type name if the type has a name, or the
/// empty string if it does not.
interned_string
get_type_name(const type_base* t, bool qualified, bool internal)
{
  const decl_base* d = dynamic_cast<const decl_base*>(t);
  if (!d)
    {
      const function_type* fn_type = is_function_type(t);
      ABG_ASSERT(fn_type);
      return fn_type->get_cached_name(internal);
    }

  // All anonymous types of a given kind get to have the same internal
  // name for internal purpose.  This to allow them to be compared
  // among themselves during type canonicalization.
  if (internal && d->get_is_anonymous())
    {
      string r;
      r += get_generic_anonymous_internal_type_name(d);
      return t->get_environment()->intern(r);
    }

  if (qualified)
    return d->get_qualified_name(internal);
  return d->get_name();
}

/// Get the name of a given type and return a copy of it.
///
/// @param t the type to consider.
///
/// @param qualified if true then return the qualified name of the
/// type.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return a copy of the type name if the type has a name, or the
/// empty string if it does not.
interned_string
get_type_name(const type_base& t, bool qualified, bool internal)
{return get_type_name(&t, qualified, internal);}

/// Get the name of the pointer to a given type.
///
/// @param pointed_to_type the pointed-to-type to consider.
///
/// @param qualified this is true if the resulting name should be of a
/// pointer to a *fully-qualified* pointed-to-type.
///
/// @param internal true if the name is for libabigail-internal
/// purposes.
///
/// @return the name (string representation) of the pointer.
interned_string
get_name_of_pointer_to_type(const type_base& pointed_to_type,
			    bool qualified, bool internal)
{
  const environment* env = pointed_to_type.get_environment();
  ABG_ASSERT(env);

  string tn = get_type_name(pointed_to_type, qualified, internal);
  tn =  tn + "*";

  return env->intern(tn);
}

/// Get the name of the reference to a given type.
///
/// @param pointed_to_type the pointed-to-type to consider.
///
/// @param qualified this is true if the resulting name should be of a
/// reference to a *fully-qualified* pointed-to-type.
///
/// @param internal true if the name is for libabigail-internal
/// purposes.
///
/// @return the name (string representation) of the reference.
interned_string
get_name_of_reference_to_type(const type_base& pointed_to_type,
			      bool lvalue_reference,
			      bool qualified, bool internal)
{
  const environment* env = pointed_to_type.get_environment();
  ABG_ASSERT(env);

  string name = get_type_name(pointed_to_type, qualified, internal);
  if (lvalue_reference)
    name = name + "&";
  else
    name = name + "&&";

  return env->intern(name);
}

/// Get the name of a qualified type, given the underlying type and
/// its qualifiers.
///
/// @param underlying_type the underlying type to consider.
///
/// @param quals the CV qualifiers of the name.
///
/// @param qualified true if we should consider the fully qualified
/// name of @p underlying_type.
///
/// @param internal true if the result is to be used for
/// libabigail-internal purposes.
///
/// @return the name (string representation) of the qualified type.
interned_string
get_name_of_qualified_type(const type_base_sptr& underlying_type,
			   qualified_type_def::CV quals,
			   bool qualified, bool internal)
{
  const environment* env = underlying_type->get_environment();
  ABG_ASSERT(env);

  string quals_repr = get_string_representation_of_cv_quals(quals);
  string name = get_type_name(underlying_type, qualified, internal);

  if (quals_repr.empty() && internal)
    // We are asked to return the internal name, that might be used
    // for type canonicalization.  For that canonicalization, we need
    // to make a difference between a no-op qualified type which
    // underlying type is foo (the qualified type is named "none
    // foo"), and the name of foo, which is just "foo".
    //
    // Please remember that this has to be kept in sync with what is
    // done in die_qualified_name, in abg-dwarf-reader.cc.  So if you
    // change this code here, please change that code there too.
    quals_repr = "";

  if (!quals_repr.empty())
    {
      if (is_pointer_type(underlying_type)
	  || is_reference_type(underlying_type)
	  || is_array_type(underlying_type))
	{
	  name += " ";
	  name += quals_repr;
	}
      else
	name = quals_repr + " " + name;
    }

  return env->intern(name);
}

/// Get the name of a given function type and return a copy of it.
///
/// @param fn_type the function type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return a copy of the function type name
interned_string
get_function_type_name(const function_type_sptr& fn_type,
		       bool internal)
{return get_function_type_name(fn_type.get(), internal);}

/// Get the name of a given function type and return a copy of it.
///
/// @param fn_type the function type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return a copy of the function type name
interned_string
get_function_type_name(const function_type* fn_type,
		       bool internal)
{
  ABG_ASSERT(fn_type);

  if (const method_type* method = is_method_type(fn_type))
    return get_method_type_name(method, internal);

  return get_function_type_name(*fn_type, internal);
}

/// Get the name of a given function type and return a copy of it.
///
/// @param fn_type the function type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return a copy of the function type name
interned_string
get_function_type_name(const function_type& fn_type,
		       bool internal)
{
  std::ostringstream o;
  type_base_sptr return_type = fn_type.get_return_type();
  const environment* env = fn_type.get_environment();
  ABG_ASSERT(env);

  o <<  get_pretty_representation(return_type, internal);

  o << " (";
  for (function_type::parameters::const_iterator i =
	 fn_type.get_parameters().begin();
       i != fn_type.get_parameters().end();
       ++i)
    {
      if (i != fn_type.get_parameters().begin())
	o << ", ";
      o << get_pretty_representation((*i)->get_type(), internal);
    }
  o <<")";

  return env->intern(o.str());
}

/// Get the name of a given method type and return a copy of it.
///
/// @param fn_type the function type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return a copy of the function type name
interned_string
get_method_type_name(const method_type_sptr fn_type,
		     bool internal)
{return get_method_type_name(fn_type.get(), internal);}

/// Get the name of a given method type and return a copy of it.
///
/// @param fn_type the function type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return a copy of the function type name
interned_string
get_method_type_name(const method_type* fn_type,
		     bool internal)
{
  if (fn_type)
    return get_method_type_name(*fn_type, internal);

  return interned_string();
}

/// Get the name of a given method type and return a copy of it.
///
/// @param fn_type the function type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return a copy of the function type name
interned_string
get_method_type_name(const method_type& fn_type,
		     bool internal)
{
  std::ostringstream o;
  type_base_sptr return_type= fn_type.get_return_type();
  const environment* env = fn_type.get_environment();
  ABG_ASSERT(env);

  if (return_type)
    o << return_type->get_cached_pretty_representation(internal);
  else
    // There are still some abixml files out there in which "void"
    // can be expressed as an empty type.
    o << "void";

  class_or_union_sptr class_type = fn_type.get_class_type();
  ABG_ASSERT(class_type);

  o << " (" << class_type->get_qualified_name(internal) << "::*)"
    << " (";

  for (function_type::parameters::const_iterator i =
	 fn_type.get_parameters().begin();
       i != fn_type.get_parameters().end();
       ++i)
    {
      if (i != fn_type.get_parameters().begin())
	o << ", ";
      if (*i)
	o << (*i)->get_type()->get_cached_pretty_representation(internal);
      else
	// There are still some abixml files out there in which "void"
	// can be expressed as an empty type.
	o << "void";
    }
  o <<")";

  return env->intern(o.str());
}

/// Build and return a copy of the pretty representation of an ABI
/// artifact that could be either a type of a decl.
///
/// param tod the ABI artifact to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return a copy of the pretty representation of an ABI artifact
/// that could be either a type of a decl.
string
get_pretty_representation(const type_or_decl_base* tod, bool internal)
{
  string result;

  if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
    result = get_pretty_representation(t, internal);
  else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
    result =  get_pretty_representation(d, internal);
  else
    // We should never reach this point
    abort();

  return result;
}

/// Build and return a copy of the pretty representation of an ABI
/// artifact that could be either a type of a decl.
///
/// param tod the ABI artifact to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return a copy of the pretty representation of an ABI artifact
/// that could be either a type of a decl.
string
get_pretty_representation(const type_or_decl_base_sptr& tod, bool internal)
{return get_pretty_representation(tod.get(), internal);}

/// Get a copy of the pretty representation of a decl.
///
/// @param d the decl to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the pretty representation of the decl.
string
get_pretty_representation(const decl_base* d, bool internal)
{
  if (!d)
    return "";
  return d->get_pretty_representation(internal);
}

/// Get a copy of the pretty representation of a type.
///
/// @param d the type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the pretty representation of the type.
string
get_pretty_representation(const type_base* t, bool internal)
{
  if (!t)
    return "void";
  if (const function_type* fn_type = is_function_type(t))
    return get_pretty_representation(fn_type, internal);

  const decl_base* d = get_type_declaration(t);
  ABG_ASSERT(d);
  return get_pretty_representation(d, internal);
}

/// Get a copy of the pretty representation of a decl.
///
/// @param d the decl to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the pretty representation of the decl.
string
get_pretty_representation(const decl_base_sptr& d, bool internal)
{return get_pretty_representation(d.get(), internal);}

/// Get a copy of the pretty representation of a type.
///
/// @param d the type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the pretty representation of the type.
string
get_pretty_representation(const type_base_sptr& t, bool internal)
{return get_pretty_representation(t.get(), internal);}

/// Get the pretty representation of a function type.
///
/// @param fn_type the function type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the string represenation of the function type.
string
get_pretty_representation(const function_type_sptr& fn_type,
			  bool internal)
{return get_pretty_representation(fn_type.get(), internal);}

/// Get the pretty representation of a function type.
///
/// @param fn_type the function type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the string represenation of the function type.
string
get_pretty_representation(const function_type* fn_type, bool internal)
{
  if (!fn_type)
    return "void";

  if (const method_type* method = is_method_type(fn_type))
    return get_pretty_representation(method, internal);

  return get_pretty_representation(*fn_type, internal);
}

/// Get the pretty representation of a function type.
///
/// @param fn_type the function type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the string represenation of the function type.
string
get_pretty_representation(const function_type& fn_type, bool internal)
{
  std::ostringstream o;
  o << "function type " << get_function_type_name(fn_type, internal);
  return o.str();
}

/// Get the pretty representation of a method type.
///
/// @param method the method type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the string represenation of the method type.
string
get_pretty_representation(const method_type& method, bool internal)
{
  std::ostringstream o;
  o << "method type " << get_method_type_name(method, internal);
  return o.str();
}

/// Get the pretty representation of a method type.
///
/// @param method the method type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the string represenation of the method type.
string
get_pretty_representation(const method_type* method, bool internal)
{
  if (!method)
    return "void";
  return get_pretty_representation(*method, internal);
}

/// Get the pretty representation of a method type.
///
/// @param method the method type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the string represenation of the method type.
string
get_pretty_representation(const method_type_sptr method, bool internal)
{return get_pretty_representation(method.get(), internal);}

/// Get the flat representation of an instance of @ref class_or_union
/// type.
///
/// The flat representation of a given @ref class_or_union type is the
/// actual definition of the type, for instance:
///
///   struct foo {int a; char b;}
///
///@param cou the instance of @ref class_or_union to consider.
///
///@param indent the identation spaces to use in the representation.
///
///@param one_line if true, then the flat representation stands on one
///line.  Otherwise, it stands on multiple lines.
///
///@return the resulting flat representation.
string
get_class_or_union_flat_representation(const class_or_union& cou,
				       const string& indent,
				       bool one_line,
				       bool internal,
				       bool qualified_names)
{
  string repr;
  string local_indent = "  ";

  if (class_decl* clazz = is_class_type(&cou))
    {
      repr = indent;
      if (!internal && clazz->is_struct())
	repr += "struct";
      else
	repr += "class";
    }
  else if (is_union_type(cou))
    repr = indent + "union";
  else
    return "";

  repr += " ";

  string name = cou.get_qualified_name();

  if (!cou.get_is_anonymous())
    repr += name;

  repr += "{";

  if (!one_line)
    repr += "\n";

  string real_indent;
  const class_or_union::data_members &dmems = cou.get_data_members();
  for (class_or_union::data_members::const_iterator dm = dmems.begin();
       dm != dmems.end();
       ++dm)
    {
      if (dm != dmems.begin())
	{
	  if (one_line)
	    real_indent = " ";
	  else
	    real_indent = "\n" + indent + local_indent;
	}

      if (var_decl_sptr v = is_anonymous_data_member(*dm))
	repr +=
	  get_class_or_union_flat_representation
	  (anonymous_data_member_to_class_or_union(*dm),
	   real_indent, one_line, internal, qualified_names);
      else
	{
	  if (one_line)
	    {
	      if (dm != dmems.begin())
		repr += real_indent;
	      repr += (*dm)->get_pretty_representation(internal,
						       qualified_names);
	    }
	  else
	    repr +=
	      real_indent+ (*dm)->get_pretty_representation(internal,
							    qualified_names);
	}
      repr += ";";
    }

  if (one_line)
    repr += "}";
  else
    repr += indent + "}";

  return repr;
}

/// Get the flat representation of an instance of @ref class_or_union
/// type.
///
/// The flat representation of a given @ref class_or_union type is the
/// actual definition of the type, for instance:
///
///   struct foo {int a; char b;}
///
///@param cou the instance of @ref class_or_union to consider.
///
///@param indent the identation spaces to use in the representation.
///
///@param one_line if true, then the flat representation stands on one
///line.  Otherwise, it stands on multiple lines.
///
///@return the resulting flat representation.
string
get_class_or_union_flat_representation(const class_or_union* cou,
				       const string& indent,
				       bool one_line,
				       bool internal,
				       bool qualified_names)
{
  if (cou)
    return get_class_or_union_flat_representation(*cou, indent, one_line,
						  internal, qualified_names);
  return "";
}

/// Get the flat representation of an instance of @ref class_or_union
/// type.
///
/// The flat representation of a given @ref class_or_union type is the
/// actual definition of the type, for instance:
///
///   struct foo {int a; char b;}
///
///@param cou the instance of @ref class_or_union to consider.
///
///@param indent the identation spaces to use in the representation.
///
///@param one_line if true, then the flat representation stands on one
///line.  Otherwise, it stands on multiple lines.
///
///@return the resulting flat representation.
string
get_class_or_union_flat_representation(const class_or_union_sptr& cou,
				       const string& indent,
				       bool one_line,
				       bool internal,
				       bool qualified_names)
{return get_class_or_union_flat_representation(cou.get(),
					       indent,
					       one_line,
					       internal,
					       qualified_names);}

/// Get the textual representation of a type for debugging purposes.
///
/// If the type is a class/union, this shows the data members, virtual
/// member functions, size, pointer value of its canonical type, etc.
/// Otherwise, this just shows the name of the artifact as returned by
/// type_or_decl_base:get_pretty_representation().
///
/// @param artifact the artifact to show a debugging representation of.
///
/// @return a debugging string representation of @p artifact.
string
get_debug_representation(const type_or_decl_base* artifact)
{
  if (!artifact)
    return string("");

  class_or_union * c = is_class_or_union_type(artifact);
  if (c)
    {
      class_decl *clazz = is_class_type(c);
      string name = c->get_qualified_name();
      std::ostringstream o;
      o << name;

      if (clazz)
	{
	  if (!clazz->get_base_specifiers().empty())
	    o << " :" << std::endl;
	  for (auto &b : clazz->get_base_specifiers())
	    {
	      o << "  ";
	      if (b->get_is_virtual())
		o << "virtual ";
	      o << b->get_base_class()->get_qualified_name()
		<< std::endl;
	    }
	}
      o << std::endl
	<< "{"
	<< "   // size in bits: " << c->get_size_in_bits() << "\n"
	<< "   // is-declaration-only: " << c->get_is_declaration_only() << "\n"
	<< "   // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
	<< "   // translation unit: " << c->get_translation_unit()->get_absolute_path() << std::endl
	<< "   // @: " << std::hex << is_type(c)
	<< ", @canonical: " << c->get_canonical_type().get() << std::dec
	<< "\n\n";

      for (auto m : c->get_data_members())
	{
	  type_base_sptr t = m->get_type();
	  t = peel_typedef_pointer_or_reference_type(t);

	  o << "  "
	    << m->get_pretty_representation(/*internal=*/false,
					    /*qualified=*/false)
	    << ";";

	  if (t && t->get_canonical_type())
	    o << " // uses canonical type '@"
	      << std::hex << t->get_canonical_type().get() << std::dec;

	  o << "'" << std::endl;
	}

      if (clazz && clazz->has_vtable())
	{
	  o << "  // virtual member functions\n\n";
	  for (auto f : clazz->get_virtual_mem_fns())
	    o << "  " << f->get_pretty_representation(/*internal=*/false,
						      /*qualified=*/false)
	      << ";" << std::endl;
	}

      o << "};" << std::endl;

      return o.str();
    }
  else if (const enum_type_decl* e = is_enum_type(artifact))
    {
      string name = e->get_qualified_name();
      std::ostringstream o;
      o << name
	<< " : "
	<< e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
							       true)
	<< "\n"
	<< "{\n"
	<< "  // size in bits: " << e->get_size_in_bits() << "\n"
	<< "  // is-declaration-only: " << e->get_is_declaration_only() << "\n"
	<< " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
	<< "  // translation unit: "
	<< e->get_translation_unit()->get_absolute_path() << "\n"
	<< "  // @: " << std::hex << is_type(e)
	<< ", @canonical: " << e->get_canonical_type().get() << std::dec
	<< "\n\n";

      for (const auto &enom : e->get_enumerators())
	o << "  " << enom.get_name() << " = " << enom.get_value() << ",\n";

      o << "};\n";

      return o.str();
    }
  return artifact->get_pretty_representation(/*internal=*/true,
					     /*qualified=*/true);
}

/// Get a given data member, referred to by its name, of a class type.
///
/// @param clazz the class to consider.
///
/// @param member_name name of the data member to get.
///
/// @return the resulting data member or nullptr if none was found.
var_decl_sptr
get_data_member(class_or_union *clazz, const char* member_name)
{
  if (!clazz)
    return var_decl_sptr();
  return clazz->find_data_member(member_name);
}

/// Get a given data member, referred to by its name, of a class type.
///
/// @param clazz the class to consider.
///
/// @param member_name name of the data member to get.
///
/// @return the resulting data member or nullptr if none was found.
var_decl_sptr
get_data_member(type_base *clazz, const char* member_name)
{return get_data_member(is_class_or_union_type(clazz), member_name);}

/// Get the non-artificial (natural) location of a decl.
///
/// If the decl doesn't have a natural location then return its
/// artificial one.
///
/// @param decl the decl to consider.
///
/// @return the natural location @p decl if it has one; otherwise,
/// return its artificial one.
const location&
get_natural_or_artificial_location(const decl_base* decl)
{
  ABG_ASSERT(decl);

  if (decl->get_location())
    return decl->get_location();
  return decl->get_artificial_location();
}

/// Get the artificial location of a decl.
///
/// If the decl doesn't have an artificial location then return its
/// natural one.
///
/// @param decl the decl to consider.
///
/// @return the artificial location @p decl if it has one; otherwise,
/// return its natural one.
const location&
get_artificial_or_natural_location(const decl_base* decl)
{
  ABG_ASSERT(decl);

  if (decl->has_artificial_location())
    return decl->get_artificial_location();
  return decl->get_location();
}

/// Emit a textual representation of an artifact to std error stream
/// for debugging purposes.
///
/// This is useful to invoke from within a command line debugger like
/// GDB to help make sense of a given ABI artifact.
///
/// @param artifact the ABI artifact to emit the debugging
/// representation for.
///
/// @return the artifact @p artifact.
type_or_decl_base*
debug(const type_or_decl_base* artifact)
{
  std::cerr << get_debug_representation(artifact) << std::endl;
  return const_cast<type_or_decl_base*>(artifact);
}

/// Emit a textual representation of an artifact to std error stream
/// for debugging purposes.
///
/// This is useful to invoke from within a command line debugger like
/// GDB to help make sense of a given ABI artifact.
///
/// @param artifact the ABI artifact to emit the debugging
/// representation for.
///
/// @return the artifact @p artifact.
type_base*
debug(const type_base* artifact)
{
  debug(static_cast<const type_or_decl_base*>(artifact));
  return const_cast<type_base*>(artifact);
}

/// Emit a textual representation of an artifact to std error stream
/// for debugging purposes.
///
/// This is useful to invoke from within a command line debugger like
/// GDB to help make sense of a given ABI artifact.
///
/// @param artifact the ABI artifact to emit the debugging
/// representation for.
///
/// @return the artifact @p artifact.
decl_base*
debug(const decl_base* artifact)
{
  debug(static_cast<const type_or_decl_base*>(artifact));
  return const_cast<decl_base*>(artifact);
}

/// Test if two ABI artifacts are equal.
///
/// This can be useful when used from the command line of a debugger
/// like GDB.
///
/// @param l the first ABI artifact to consider in the comparison.
///
/// @param r the second ABI artifact to consider in the comparison.
///
/// @return true iff @p l equals @p r.
bool
debug_equals(const type_or_decl_base *l, const type_or_decl_base *r)
{
  if (!!l != !!r)
    return false;
  if (!l && !r)
    return true;

  return (*l == *r);
}

/// By looking at the language of the TU a given ABI artifact belongs
/// to, test if the ONE Definition Rule should apply.
///
/// To date, it applies to c++, java and ada.
///
/// @param artifact the ABI artifact to consider.
///
/// @return true iff the One Definition Rule should apply.
bool
odr_is_relevant(const type_or_decl_base& artifact)
{
  translation_unit::language l =
    artifact.get_translation_unit()->get_language();

  if (is_cplus_plus_language(l)
      || is_java_language(l)
      || is_ada_language(l))
    return true;

  return false;
}

/// Get the declaration for a given type.
///
/// @param t the type to consider.
///
/// @return the declaration for the type to return.
const decl_base*
get_type_declaration(const type_base* t)
{return dynamic_cast<const decl_base*>(t);}

/// Get the declaration for a given type.
///
/// @param t the type to consider.
///
/// @return the declaration for the type to return.
decl_base*
get_type_declaration(type_base* t)
{return dynamic_cast<decl_base*>(t);}

/// Get the declaration for a given type.
///
/// @param t the type to consider.
///
/// @return the declaration for the type to return.
decl_base_sptr
get_type_declaration(const type_base_sptr t)
{return dynamic_pointer_cast<decl_base>(t);}

/// Test if two types are equal modulo a typedef.
///
/// Type A and B are compatible if
///
///	- A and B are equal
///	- or if one type is a typedef of the other one.
///
/// @param type1 the first type to consider.
///
/// @param type2 the second type to consider.
///
/// @return true iff @p type1 and @p type2 are compatible.
bool
types_are_compatible(const type_base_sptr type1,
		     const type_base_sptr type2)
{
  if (!type1 || !type2)
    return false;

  if (type1 == type2)
    return true;

  // Normally we should strip typedefs entirely, but this is
  // potentially costly, especially on binaries with huge changesets
  // like the Linux Kernel.  So we just get the leaf types for now.
  //
  // Maybe there should be an option by which users accepts to pay the
  // CPU usage toll in exchange for finer filtering?

  // type_base_sptr t1 = strip_typedef(type1);
  // type_base_sptr t2 = strip_typedef(type2);

  type_base_sptr t1 = peel_typedef_type(type1);
  type_base_sptr t2 = peel_typedef_type(type2);

  return t1 == t2;
}

/// Test if two types are equal modulo a typedef.
///
/// Type A and B are compatible if
///
///	- A and B are equal
///	- or if one type is a typedef of the other one.
///
/// @param type1 the declaration of the first type to consider.
///
/// @param type2 the declaration of the second type to consider.
///
/// @return true iff @p type1 and @p type2 are compatible.
bool
types_are_compatible(const decl_base_sptr d1,
		     const decl_base_sptr d2)
{return types_are_compatible(is_type(d1), is_type(d2));}

/// Return the translation unit a declaration belongs to.
///
/// @param decl the declaration to consider.
///
/// @return the resulting translation unit, or null if the decl is not
/// yet added to a translation unit.
translation_unit*
get_translation_unit(const decl_base& decl)
{return const_cast<translation_unit*>(decl.get_translation_unit());}

/// Return the translation unit a declaration belongs to.
///
/// @param decl the declaration to consider.
///
/// @return the resulting translation unit, or null if the decl is not
/// yet added to a translation unit.
translation_unit*
get_translation_unit(const decl_base* decl)
{return decl ? get_translation_unit(*decl) : 0;}

/// Return the translation unit a declaration belongs to.
///
/// @param decl the declaration to consider.
///
/// @return the resulting translation unit, or null if the decl is not
/// yet added to a translation unit.
translation_unit*
get_translation_unit(const shared_ptr<decl_base> decl)
{return get_translation_unit(decl.get());}

/// Tests whether if a given scope is the global scope.
///
/// @param scope the scope to consider.
///
/// @return true iff the current scope is the global one.
bool
is_global_scope(const scope_decl& scope)
{return !!dynamic_cast<const global_scope*>(&scope);}

/// Tests whether if a given scope is the global scope.
///
/// @param scope the scope to consider.
///
/// @return the @ref global_scope* representing the scope @p scope or
/// 0 if @p scope is not a global scope.
const global_scope*
is_global_scope(const scope_decl* scope)
{return dynamic_cast<const global_scope*>(scope);}

/// Tests whether if a given scope is the global scope.
///
/// @param scope the scope to consider.
///
/// @return true iff the current scope is the global one.
bool
is_global_scope(const shared_ptr<scope_decl>scope)
{return is_global_scope(scope.get());}

/// Tests whether a given declaration is at global scope.
///
/// @param decl the decl to consider.
///
/// @return true iff decl is at global scope.
bool
is_at_global_scope(const decl_base& decl)
{return (is_global_scope(decl.get_scope()));}

/// Tests whether a given declaration is at global scope.
///
/// @param decl the decl to consider.
///
/// @return true iff decl is at global scope.
bool
is_at_global_scope(const decl_base_sptr decl)
{return (decl && is_global_scope(decl->get_scope()));}

/// Tests whether a given declaration is at global scope.
///
/// @param decl the decl to consider.
///
/// @return true iff decl is at global scope.
bool
is_at_global_scope(const decl_base* decl)
{return is_at_global_scope(*decl);}

/// Tests whether a given decl is at class scope.
///
/// @param decl the decl to consider.
///
/// @return true iff decl is at class scope.
class_or_union*
is_at_class_scope(const decl_base_sptr decl)
{return is_at_class_scope(decl.get());}

/// Tests whether a given decl is at class scope.
///
/// @param decl the decl to consider.
///
/// @return true iff decl is at class scope.
class_or_union*
is_at_class_scope(const decl_base* decl)
{
  if (!decl)
    return 0;

  return is_at_class_scope(*decl);
}

/// Tests whether a given decl is at class scope.
///
/// @param decl the decl to consider.
///
/// @return true iff decl is at class scope.
class_or_union*
is_at_class_scope(const decl_base& decl)
{
  scope_decl* scope = decl.get_scope();
  if (class_or_union* cl = is_class_type(scope))
    return cl;
  if (class_or_union* cl = is_union_type(scope))
    return cl;
  return 0;
}

/// Find a data member inside an anonymous data member.
///
/// An anonymous data member has a type which is a class or union.
/// This function looks for a data member inside the type of that
/// anonymous data member.
///
/// @param anon_dm the anonymous data member to consider.
///
/// @param name the name of the data member to look for.
var_decl_sptr
find_data_member_from_anonymous_data_member(const var_decl_sptr& anon_dm,
					    const string& name)
{
  const class_or_union* containing_class_or_union =
    anonymous_data_member_to_class_or_union(anon_dm.get());

  if (!containing_class_or_union)
    return var_decl_sptr();

  var_decl_sptr result = containing_class_or_union->find_data_member(name);
  return result;
}

/// Tests whether a given decl is at template scope.
///
/// Note that only template parameters , types that are compositions,
/// and template patterns (function or class) can be at template scope.
///
/// @param decl the decl to consider.
///
/// @return true iff the decl is at template scope.
bool
is_at_template_scope(const shared_ptr<decl_base> decl)
{return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}

/// Tests whether a decl is a template parameter.
///
/// @param decl the decl to consider.
///
/// @return true iff decl is a template parameter.
bool
is_template_parameter(const shared_ptr<decl_base> decl)
{
  return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
		   || dynamic_pointer_cast<non_type_tparameter>(decl)
		   || dynamic_pointer_cast<template_tparameter>(decl)));
}

/// Test whether a declaration is a @ref function_decl.
///
/// @param d the declaration to test for.
///
/// @return a shared pointer to @ref function_decl if @p d is a @ref
/// function_decl.  Otherwise, a nil shared pointer.
function_decl*
is_function_decl(const type_or_decl_base* d)
{return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}

/// Test whether a declaration is a @ref function_decl.
///
/// @param d the declaration to test for.
///
/// @return true if @p d is a function_decl.
bool
is_function_decl(const type_or_decl_base& d)
{return is_function_decl(&d);}

/// Test whether a declaration is a @ref function_decl.
///
/// @param d the declaration to test for.
///
/// @return a shared pointer to @ref function_decl if @p d is a @ref
/// function_decl.  Otherwise, a nil shared pointer.
function_decl_sptr
is_function_decl(const type_or_decl_base_sptr& d)
{return dynamic_pointer_cast<function_decl>(d);}

/// Test whether a declaration is a @ref function_decl.
///
/// @param d the declaration to test for.
///
/// @return a pointer to @ref function_decl if @p d is a @ref
/// function_decl.  Otherwise, a nil shared pointer.
function_decl::parameter*
is_function_parameter(const type_or_decl_base* tod)
{
  return dynamic_cast<function_decl::parameter*>
    (const_cast<type_or_decl_base*>(tod));
}

/// Test whether an ABI artifact is a @ref function_decl.
///
/// @param tod the declaration to test for.
///
/// @return a pointer to @ref function_decl if @p d is a @ref
/// function_decl.  Otherwise, a nil shared pointer.
function_decl::parameter_sptr
is_function_parameter(const type_or_decl_base_sptr tod)
{return dynamic_pointer_cast<function_decl::parameter>(tod);}

/// Test if an ABI artifact is a declaration.
///
/// @param d the artifact to consider.
///
/// @param return the declaration sub-object of @p d if it's a
/// declaration, or NULL if it is not.
decl_base*
is_decl(const type_or_decl_base* d)
{
  if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
    {
      if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
	// The artifact is a decl-only (like a function or a
	// variable).  That is, it's not a type that also has a
	// declaration.  In this case, we are in the fast path and we
	// have a pointer to the decl sub-object handy.  Just return
	// it ...
	return reinterpret_cast<decl_base*>
	  (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());

      // ... Otherwise, we are in the slow path, which is that the
      // artifact is a type which has a declaration.  In that case,
      // let's use the slow dynamic_cast because we don't have the
      // pointer to the decl sub-object handily present.
      return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
    }
  return 0;
}

/// Test if an ABI artifact is a declaration.
///
/// @param d the artifact to consider.
///
/// @param return the declaration sub-object of @p d if it's a
/// declaration, or NULL if it is not.
decl_base_sptr
is_decl(const type_or_decl_base_sptr& d)
{return dynamic_pointer_cast<decl_base>(d);}

/// Test if an ABI artifact is a declaration.
///
/// This is done using a slow path that uses dynamic_cast.
///
/// @param d the artifact to consider.
///
/// @param return the declaration sub-object of @p d if it's a
decl_base*
is_decl_slow(const type_or_decl_base* t)
{return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}

/// Test if an ABI artifact is a declaration.
///
/// This is done using a slow path that uses dynamic_cast.
///
/// @param d the artifact to consider.
///
/// @param return the declaration sub-object of @p d if it's a
decl_base_sptr
is_decl_slow(const type_or_decl_base_sptr& t)
{return dynamic_pointer_cast<decl_base>(t);}

/// Test whether a declaration is a type.
///
/// @param d the IR artefact to test for.
///
/// @return true if the artifact is a type, false otherwise.
bool
is_type(const type_or_decl_base& tod)
{
  if (dynamic_cast<const type_base*>(&tod))
    return true;
  return false;
}

/// Test whether a declaration is a type.
///
/// @param d the IR artefact to test for.
///
/// @return true if the artifact is a type, false otherwise.
type_base*
is_type(const type_or_decl_base* t)
{
  if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
    return reinterpret_cast<type_base*>
      (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());

  return 0;
}

/// Test whether a declaration is a type.
///
/// @param d the IR artefact to test for.
///
/// @return true if the artifact is a type, false otherwise.
type_base_sptr
is_type(const type_or_decl_base_sptr& tod)
{return dynamic_pointer_cast<type_base>(tod);}

/// Test whether a declaration is a type.
///
/// @param d the declaration to test for.
///
/// @return true if the declaration is a type, false otherwise.

/// Test if a given type is anonymous.
///
/// Note that this function considers that an anonymous class that is
/// named by a typedef is not anonymous anymore.  This is the C idiom:
///
///       typedef struct {int member;} s_type;
///
/// The typedef s_type becomes the name of the originally anonymous
/// struct.
///
/// @param t the type to consider.
///
/// @return true iff @p t is anonymous.
bool
is_anonymous_type(const type_base* t)
{
  const decl_base* d = get_type_declaration(t);
  if (d)
    if (d->get_is_anonymous())
      {
	if (class_or_union *cou = is_class_or_union_type(t))
	  {
	    // An anonymous class that is named by a typedef is not
	    // considered anonymous anymore.
	    if (!cou->get_naming_typedef())
	      return true;
	  }
	else
	  return true;
      }
  return false;
}

/// Test if a given type is anonymous.
///
/// @param t the type to consider.
///
/// @return true iff @p t is anonymous.
bool
is_anonymous_type(const type_base_sptr& t)
{return is_anonymous_type(t.get());}

/// Test whether a type is a type_decl (a builtin type).
///
/// @return the type_decl* for @t if it's type_decl, otherwise, return
/// nil.
const type_decl*
is_type_decl(const type_or_decl_base* t)
{return dynamic_cast<const type_decl*>(t);}

/// Test whether a type is a type_decl (a builtin type).
///
/// @return the type_decl_sptr for @t if it's type_decl, otherwise,
/// return nil.
type_decl_sptr
is_type_decl(const type_or_decl_base_sptr& t)
{return dynamic_pointer_cast<type_decl>(t);}

/// Test whether a type is a typedef.
///
/// @param t the type to test for.
///
/// @return the typedef declaration of the @p t, or NULL if it's not a
/// typedef.
typedef_decl_sptr
is_typedef(const type_or_decl_base_sptr t)
{return dynamic_pointer_cast<typedef_decl>(t);}

/// Test whether a type is a typedef.
///
/// @param t the declaration of the type to test for.
///
/// @return the typedef declaration of the @p t, or NULL if it's not a
/// typedef.
const typedef_decl*
is_typedef(const type_base* t)
{return dynamic_cast<const typedef_decl*>(t);}

/// Test whether a type is a typedef.
///
/// @param t the declaration of the type to test for.
///
/// @return the typedef declaration of the @p t, or NULL if it's not a
/// typedef.
typedef_decl*
is_typedef(type_base* t)
{return dynamic_cast<typedef_decl*>(t);}

/// Test if a type is an enum. This function looks through typedefs.
///
/// @parm t the type to consider.
///
/// @return the enum_decl if @p t is an @ref enum_decl or null
/// otherwise.
enum_type_decl_sptr
is_compatible_with_enum_type(const type_base_sptr& t)
{
  if (!t)
    return enum_type_decl_sptr();

  // Normally we should strip typedefs entirely, but this is
  // potentially costly, especially on binaries with huge changesets
  // like the Linux Kernel.  So we just get the leaf types for now.
  //
  // Maybe there should be an option by which users accepts to pay the
  // CPU usage toll in exchange for finer filtering?

  // type_base_sptr ty = strip_typedef(t);
  type_base_sptr ty = peel_typedef_type(t);;
  return is_enum_type(ty);
}

/// Test if a type is an enum. This function looks through typedefs.
///
/// @parm t the type to consider.
///
/// @return the enum_decl if @p t is an @ref enum_decl or null
/// otherwise.
enum_type_decl_sptr
is_compatible_with_enum_type(const decl_base_sptr& t)
{return is_compatible_with_enum_type(is_type(t));}

/// Test if a decl is an enum_type_decl
///
/// @param d the decl to test for.
///
/// @return the enum_type_decl* if @p d is an enum, nil otherwise.
const enum_type_decl*
is_enum_type(const type_or_decl_base* d)
{return dynamic_cast<const enum_type_decl*>(d);}

/// Test if a decl is an enum_type_decl
///
/// @param d the decl to test for.
///
/// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
enum_type_decl_sptr
is_enum_type(const type_or_decl_base_sptr& d)
{return dynamic_pointer_cast<enum_type_decl>(d);}

/// Test if a type is a class. This function looks through typedefs.
///
/// @parm t the type to consider.
///
/// @return the class_decl if @p t is a class_decl or null otherwise.
class_decl_sptr
is_compatible_with_class_type(const type_base_sptr& t)
{
  if (!t)
    return class_decl_sptr();

  // Normally we should strip typedefs entirely, but this is
  // potentially costly, especially on binaries with huge changesets
  // like the Linux Kernel.  So we just get the leaf types for now.
  //
  // Maybe there should be an option by which users accepts to pay the
  // CPU usage toll in exchange for finer filtering?

  // type_base_sptr ty = strip_typedef(t);
  type_base_sptr ty = peel_typedef_type(t);
  return is_class_type(ty);
}

/// Test if a type is a class. This function looks through typedefs.
///
/// @parm t the type to consider.
///
/// @return the class_decl if @p t is a class_decl or null otherwise.
class_decl_sptr
is_compatible_with_class_type(const decl_base_sptr& t)
{return is_compatible_with_class_type(is_type(t));}

/// Test whether a type is a class.
///
/// @parm t the type to consider.
///
/// @return true iff @p t is a class_decl.
bool
is_class_type(const type_or_decl_base& t)
{return is_class_type(&t);}

/// Test whether a type is a class.
///
/// @parm t the type to consider.
///
/// @return the class_decl if @p t is a class_decl or null otherwise.
class_decl*
is_class_type(const type_or_decl_base* t)
{
  if (!t)
    return 0;

  if (t->kind() & type_or_decl_base::CLASS_TYPE)
    return reinterpret_cast<class_decl*>
      (const_cast<type_or_decl_base*>(t)->runtime_type_instance());

  return 0;
}

/// Test whether a type is a class.
///
/// @parm t the type to consider.
///
/// @return the class_decl if @p t is a class_decl or null otherwise.
class_decl_sptr
is_class_type(const type_or_decl_base_sptr& d)
{return dynamic_pointer_cast<class_decl>(d);}


/// Test wheter a type is a declaration-only class.
///
/// @param t the type to considier.
///
/// @return true iff @p t is a declaration-only class.
bool
is_declaration_only_class_or_union_type(const type_base *t)
{
  if (const class_or_union *klass = is_class_or_union_type(t))
    return klass->get_is_declaration_only();
  return false;
}

/// Test wheter a type is a declaration-only class.
///
/// @param t the type to considier.
///
/// @return true iff @p t is a declaration-only class.
bool
is_declaration_only_class_type(const type_base_sptr& t)
{return is_declaration_only_class_or_union_type(t.get());}

/// Test if a type is a @ref class_or_union.
///
/// @param t the type to consider.
///
/// @return the @ref class_or_union is @p is a @ref class_or_union, or
/// nil otherwise.
class_or_union*
is_class_or_union_type(const type_or_decl_base* t)
{return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}

/// Test if a type is a @ref class_or_union.
///
/// @param t the type to consider.
///
/// @return the @ref class_or_union is @p is a @ref class_or_union, or
/// nil otherwise.
shared_ptr<class_or_union>
is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
{return dynamic_pointer_cast<class_or_union>(t);}

/// Test if a type is a @ref union_decl.
///
/// @param t the type to consider.
///
/// @return true iff @p t is a union_decl.
bool
is_union_type(const type_or_decl_base& t)
{return is_union_type(&t);}

/// Test if a type is a @ref union_decl.
///
/// @param t the type to consider.
///
/// @return the @ref union_decl is @p is a @ref union_decl, or nil
/// otherwise.
union_decl*
is_union_type(const type_or_decl_base* t)
{return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}

/// Test if a type is a @ref union_decl.
///
/// @param t the type to consider.
///
/// @return the @ref union_decl is @p is a @ref union_decl, or nil
/// otherwise.
union_decl_sptr
is_union_type(const shared_ptr<type_or_decl_base>& t)
{return dynamic_pointer_cast<union_decl>(t);}

/// Test whether a type is a pointer_type_def.
///
/// @param t the type to test.
///
/// @return the @ref pointer_type_def_sptr if @p t is a
/// pointer_type_def, null otherwise.
pointer_type_def*
is_pointer_type(type_or_decl_base* t)
{
  if (!t)
    return 0;

  if (t->kind() & type_or_decl_base::POINTER_TYPE)
    return reinterpret_cast<pointer_type_def*>
      (const_cast<type_or_decl_base*>(t)->runtime_type_instance());

  return 0;
}

/// Test whether a type is a pointer_type_def.
///
/// @param t the type to test.
///
/// @return the @ref pointer_type_def_sptr if @p t is a
/// pointer_type_def, null otherwise.
const pointer_type_def*
is_pointer_type(const type_or_decl_base* t)
{
  return is_pointer_type(const_cast<type_or_decl_base*>(t));
}

/// Test whether a type is a pointer_type_def.
///
/// @param t the type to test.
///
/// @return the @ref pointer_type_def_sptr if @p t is a
/// pointer_type_def, null otherwise.
pointer_type_def_sptr
is_pointer_type(const type_or_decl_base_sptr &t)
{return dynamic_pointer_cast<pointer_type_def>(t);}

/// Test whether a type is a reference_type_def.
///
/// @param t the type to test.
///
/// @return the @ref reference_type_def_sptr if @p t is a
/// reference_type_def, null otherwise.
reference_type_def*
is_reference_type(type_or_decl_base* t)
{return dynamic_cast<reference_type_def*>(t);}

/// Test whether a type is a reference_type_def.
///
/// @param t the type to test.
///
/// @return the @ref reference_type_def_sptr if @p t is a
/// reference_type_def, null otherwise.
const reference_type_def*
is_reference_type(const type_or_decl_base* t)
{return dynamic_cast<const reference_type_def*>(t);}

/// Test whether a type is a reference_type_def.
///
/// @param t the type to test.
///
/// @return the @ref reference_type_def_sptr if @p t is a
/// reference_type_def, null otherwise.
reference_type_def_sptr
is_reference_type(const type_or_decl_base_sptr& t)
{return dynamic_pointer_cast<reference_type_def>(t);}

/// Test if a type is a pointer to void type.
///
/// Note that this looks trough typedefs or CV qualifiers to look for
/// the void pointer.
///
/// @param type the type to consider.
///
/// @return the actual void pointer if @p is a void pointer or NULL if
/// it's not.
const type_base*
is_void_pointer_type(const type_base* type)
{
  type = peel_qualified_or_typedef_type(type);

  const pointer_type_def * t = is_pointer_type(type);
  if (!t)
    return 0;

  // Look through typedefs in the pointed-to type as well.
  type_base * ty = t->get_pointed_to_type().get();
  ty = peel_qualified_or_typedef_type(ty);
  if (ty->get_environment()->is_void_type(ty))
    return ty;

  return 0;
}

/// Test whether a type is a reference_type_def.
///
/// @param t the type to test.
///
/// @return the @ref reference_type_def_sptr if @p t is a
/// reference_type_def, null otherwise.
qualified_type_def*
is_qualified_type(const type_or_decl_base* t)
{return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}

/// Test whether a type is a qualified_type_def.
///
/// @param t the type to test.
///
/// @return the @ref qualified_type_def_sptr if @p t is a
/// qualified_type_def, null otherwise.
qualified_type_def_sptr
is_qualified_type(const type_or_decl_base_sptr& t)
{return dynamic_pointer_cast<qualified_type_def>(t);}

/// Test whether a type is a function_type.
///
/// @param t the type to test.
///
/// @return the @ref function_type_sptr if @p t is a
/// function_type, null otherwise.
function_type_sptr
is_function_type(const type_or_decl_base_sptr& t)
{return dynamic_pointer_cast<function_type>(t);}

/// Test whether a type is a function_type.
///
/// @param t the type to test.
///
/// @return the @ref function_type_sptr if @p t is a
/// function_type, null otherwise.
function_type*
is_function_type(type_or_decl_base* t)
{return dynamic_cast<function_type*>(t);}

/// Test whether a type is a function_type.
///
/// @param t the type to test.
///
/// @return the @ref function_type_sptr if @p t is a
/// function_type, null otherwise.
const function_type*
is_function_type(const type_or_decl_base* t)
{return dynamic_cast<const function_type*>(t);}

/// Test whether a type is a method_type.
///
/// @param t the type to test.
///
/// @return the @ref method_type_sptr if @p t is a
/// method_type, null otherwise.
method_type_sptr
is_method_type(const type_or_decl_base_sptr& t)
{return dynamic_pointer_cast<method_type>(t);}

/// Test whether a type is a method_type.
///
/// @param t the type to test.
///
/// @return the @ref method_type_sptr if @p t is a
/// method_type, null otherwise.
const method_type*
is_method_type(const type_or_decl_base* t)
{return dynamic_cast<const method_type*>(t);}

/// Test whether a type is a method_type.
///
/// @param t the type to test.
///
/// @return the @ref method_type_sptr if @p t is a
/// method_type, null otherwise.
method_type*
is_method_type(type_or_decl_base* t)
{return dynamic_cast<method_type*>(t);}

/// If a class (or union) is a decl-only class, get its definition.
/// Otherwise, just return the initial class.
///
/// @param the_class the class (or union) to consider.
///
/// @return either the definition of the class, or the class itself.
class_or_union*
look_through_decl_only_class(class_or_union* the_class)
{return is_class_or_union_type(look_through_decl_only(the_class));}

/// If a class (or union) is a decl-only class, get its definition.
/// Otherwise, just return the initial class.
///
/// @param klass the class (or union) to consider.
///
/// @return either the definition of the class, or the class itself.
class_or_union_sptr
look_through_decl_only_class(class_or_union_sptr klass)
{return is_class_or_union_type(look_through_decl_only(klass));}

/// If an enum is a decl-only enum, get its definition.
/// Otherwise, just return the initial enum.
///
/// @param enom the enum to consider.
///
/// @return either the definition of the enum, or the enum itself.
enum_type_decl_sptr
look_through_decl_only_enum(enum_type_decl_sptr enom)
{return is_enum_type(look_through_decl_only(enom));}

/// If a decl is decl-only enum, get its definition.  Otherwise, just
/// return the initial decl.
///
/// @param d the decl to consider.
///
/// @return either the definition of the enum, or the decl itself.
decl_base*
look_through_decl_only(decl_base* d)
{
  decl_base_sptr decl(d, sptr_utils::noop_deleter());
  return look_through_decl_only(decl).get();
}

/// If a decl is decl-only get its definition.  Otherwise, just return nil.
///
/// @param d the decl to consider.
///
/// @return either the definition of the decl, or nil.
decl_base_sptr
look_through_decl_only(decl_base_sptr d)
{
  if (!d)
    return d;

  while (d->get_is_declaration_only())
    {
      decl_base_sptr definition = d->get_definition_of_declaration();
      if (!definition)
        break;
      d = definition;
    }

  return d;
}

/// Tests if a declaration is a variable declaration.
///
/// @param decl the decl to test.
///
/// @return the var_decl_sptr iff decl is a variable declaration; nil
/// otherwise.
var_decl*
is_var_decl(const type_or_decl_base* tod)
{return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}

/// Tests if a declaration is a variable declaration.
///
/// @param decl the decl to test.
///
/// @return the var_decl_sptr iff decl is a variable declaration; nil
/// otherwise.
var_decl_sptr
is_var_decl(const type_or_decl_base_sptr& decl)
{return dynamic_pointer_cast<var_decl>(decl);}

/// Tests if a declaration is a namespace declaration.
///
/// @param d the decalration to consider.
///
/// @return the namespace declaration if @p d is a namespace.
namespace_decl_sptr
is_namespace(const decl_base_sptr& d)
{return dynamic_pointer_cast<namespace_decl>(d);}

/// Tests if a declaration is a namespace declaration.
///
/// @param d the decalration to consider.
///
/// @return the namespace declaration if @p d is a namespace.
namespace_decl*
is_namespace(const decl_base* d)
{return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}

/// Tests whether a decl is a template parameter composition type.
///
/// @param decl the declaration to consider.
///
/// @return true iff decl is a template parameter composition type.
bool
is_template_parm_composition_type(const shared_ptr<decl_base> decl)
{
  return (decl
	  && is_at_template_scope(decl)
	  && is_type(decl)
	  && !is_template_parameter(decl));
}

/// Test whether a decl is the pattern of a function template.
///
/// @param decl the decl to consider.
///
/// @return true iff decl is the pattern of a function template.
bool
is_function_template_pattern(const shared_ptr<decl_base> decl)
{
  return (decl
	  && dynamic_pointer_cast<function_decl>(decl)
	  && dynamic_cast<template_decl*>(decl->get_scope()));
}

/// Test if a type is an array_type_def.
///
/// @param type the type to consider.
///
/// @return true iff @p type is an array_type_def.
array_type_def*
is_array_type(const type_or_decl_base* type)
{return dynamic_cast<array_type_def*>(const_cast<type_or_decl_base*>(type));}

/// Test if a type is an array_type_def.
///
/// @param type the type to consider.
///
/// @return true iff @p type is an array_type_def.
array_type_def_sptr
is_array_type(const type_or_decl_base_sptr& type)
{return dynamic_pointer_cast<array_type_def>(type);}

/// Tests if the element of a given array is a qualified type.
///
/// @param array the array type to consider.
///
/// @return the qualified element of the array iff it's a qualified
/// type.  Otherwise, return a nil object.
qualified_type_def_sptr
is_array_of_qualified_element(const array_type_def_sptr& array)
{
  if (!array)
    return qualified_type_def_sptr();

  return is_qualified_type(array->get_element_type());
}

/// Test if an array type is an array to a qualified element type.
///
/// @param type the array type to consider.
///
/// @return true the array @p type iff it's an array to a qualified
/// element type.
array_type_def_sptr
is_array_of_qualified_element(const type_base_sptr& type)
{
  if (array_type_def_sptr array = is_array_type(type))
    if (is_array_of_qualified_element(array))
      return array;

  return array_type_def_sptr();
}

/// Test if a type is a typedef of an array.
///
/// Note that the function looks through qualified and typedefs types
/// of the underlying type of the current typedef.  In other words, if
/// we are looking at a typedef of a CV-qualified array, or at a
/// typedef of a CV-qualified typedef of an array, this function will
/// still return TRUE.
///
/// @param t the type to consider.
///
/// @return true if t is a typedef which underlying type is an array.
/// That array might be either cv-qualified array or a typedef'ed
/// array, or a combination of both.
array_type_def_sptr
is_typedef_of_array(const type_base_sptr& t)
{
  array_type_def_sptr result;

  if (typedef_decl_sptr typdef = is_typedef(t))
    {
      type_base_sptr u =
	peel_qualified_or_typedef_type(typdef->get_underlying_type());
      result = is_array_type(u);
    }

  return result;
}

/// Test if a type is an array_type_def::subrange_type.
///
/// @param type the type to consider.
///
/// @return the array_type_def::subrange_type which @p type is a type
/// of, or nil if it's not of that type.
array_type_def::subrange_type*
is_subrange_type(const type_or_decl_base *type)
{
  return dynamic_cast<array_type_def::subrange_type*>
    (const_cast<type_or_decl_base*>(type));
}

/// Test if a type is an array_type_def::subrange_type.
///
/// @param type the type to consider.
///
/// @return the array_type_def::subrange_type which @p type is a type
/// of, or nil if it's not of that type.
array_type_def::subrange_sptr
is_subrange_type(const type_or_decl_base_sptr &type)
{return dynamic_pointer_cast<array_type_def::subrange_type>(type);}

/// Tests whether a decl is a template.
///
/// @param decl the decl to consider.
///
/// @return true iff decl is a function template, class template, or
/// template template parameter.
bool
is_template_decl(const shared_ptr<decl_base> decl)
{return decl && dynamic_pointer_cast<template_decl>(decl);}

/// This enum describe the kind of entity to lookup, while using the
/// lookup API.
enum lookup_entity_kind
{
  LOOKUP_ENTITY_TYPE,
  LOOKUP_ENTITY_VAR,
};

/// Find the first relevant delimiter (the "::" string) in a fully
/// qualified C++ type name, starting from a given position.  The
/// delimiter returned separates a type name from the name of its
/// context.
///
/// This is supposed to work correctly on names in cases like this:
///
///    foo<ns1::name1, ns2::name2>
///
/// In that case when called with with parameter @p begin set to 0, no
/// delimiter is returned, because the type name in this case is:
/// 'foo<ns1::name1, ns2::name2>'.
///
/// But in this case:
///
///   foo<p1, bar::name>::some_type
///
/// The "::" returned is the one right before 'some_type'.
///
/// @param fqn the fully qualified name of the type to consider.
///
/// @param begin the position from which to look for the delimiter.
///
/// @param delim_pos out parameter. Is set to the position of the
/// delimiter iff the function returned true.
///
/// @return true iff the function found and returned the delimiter.
static bool
find_next_delim_in_cplus_type(const string&	fqn,
			      size_t		begin,
			      size_t&		delim_pos)
{
  int angle_count = 0;
  bool found = false;
  size_t i = begin;
  for (; i < fqn.size(); ++i)
    {
      if (fqn[i] == '<')
	++angle_count;
      else if (fqn[i] == '>')
	--angle_count;
      else if (i + 1 < fqn.size()
	       && !angle_count
	       && fqn[i] == ':'
	       && fqn[i+1] == ':')
	{
	  delim_pos = i;
	  found = true;
	  break;
	}
    }
  return found;
}

/// Decompose a fully qualified name into the list of its components.
///
/// @param fqn the fully qualified name to decompose.
///
/// @param comps the resulting list of component to fill.
void
fqn_to_components(const string& fqn,
		  list<string>& comps)
{
  string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
  do
    {
      if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
	comp_end = fqn_size;

      string comp = fqn.substr(comp_begin, comp_end - comp_begin);
      comps.push_back(comp);

      comp_begin = comp_end + 2;
      if (comp_begin >= fqn_size)
	break;
    } while (true);
}

/// Turn a set of qualified name components (that name a type) into a
/// qualified name string.
///
/// @param comps the name components
///
/// @return the resulting string, which would be the qualified name of
/// a type.
string
components_to_type_name(const list<string>& comps)
{
  string result;
  for (list<string>::const_iterator c = comps.begin();
       c != comps.end();
       ++c)
    if (c == comps.begin())
      result = *c;
    else
      result += "::" + *c;
  return result;
}

/// This predicate returns true if a given container iterator points
/// to the last element of the container, false otherwise.
///
/// @tparam T the type of the container of the iterator.
///
/// @param container the container the iterator points into.
///
/// @param i the iterator to consider.
///
/// @return true iff the iterator points to the last element of @p
/// container.
template<typename T>
static bool
iterator_is_last(T& container,
		 typename T::const_iterator i)
{
  typename T::const_iterator next = i;
  ++next;
  return (next == container.end());
}

//--------------------------------
// <type and decls lookup stuff>
// ------------------------------

/// Lookup all the type*s* that have a given fully qualified name.
///
/// @param type_name the fully qualified name of the type to
/// lookup.
///
/// @param type_map the map to look into.
///
/// @return the vector containing the types named @p type_name.  If
/// the lookup didn't yield any type, then this function returns nil.
static const type_base_wptrs_type*
lookup_types_in_map(const interned_string& type_name,
		    const istring_type_base_wptrs_map_type& type_map)
{
  istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
  if (i != type_map.end())
    return &i->second;
  return 0;
}

/// Lookup a type (with a given name) in a map that associates a type
/// name to a type.  If there are several types with a given name,
/// then return the last of such types, that is, the last one that got
/// registered.
///
/// @tparam TypeKind the type of the type this function is supposed to
/// return.
///
/// @param type_name the name of the type to lookup.
///
/// @param type_map the map in which to look.
///
/// @return a shared_ptr to the type found.  If no type was found or
/// if the type found was not of type @p TypeKind then the function
/// returns nil.
template <class TypeKind>
static shared_ptr<TypeKind>
lookup_type_in_map(const interned_string& type_name,
		   const istring_type_base_wptrs_map_type& type_map)
{
  istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
  if (i != type_map.end())
    return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
  return shared_ptr<TypeKind>();
}

/// Lookup a basic type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param type_name the name of the basic type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the basic type found or nil if no basic type was found.
type_decl_sptr
lookup_basic_type(const interned_string& type_name, const translation_unit& tu)
{
  return lookup_type_in_map<type_decl>(type_name,
				       tu.get_types().basic_types());
}

/// Lookup a basic type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param type_name the name of the basic type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the basic type found or nil if no basic type was found.
type_decl_sptr
lookup_basic_type(const string& type_name, const translation_unit& tu)
{
  const environment* env = tu.get_environment();
  ABG_ASSERT(env);

  interned_string s = env->intern(type_name);
  return lookup_basic_type(s, tu);
}

/// Lookup a class type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param fqn the fully qualified name of the class type node to look
/// up.
///
/// @param tu the translation unit to perform lookup from.
///
/// @return the declaration of the class type IR node found, NULL
/// otherwise.
class_decl_sptr
lookup_class_type(const string& fqn, const translation_unit& tu)
{
  const environment* env = tu.get_environment();
  ABG_ASSERT(env);

  interned_string s = env->intern(fqn);
  return lookup_class_type(s, tu);
}

/// Lookup a class type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param type_name the name of the class type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the class type found or nil if no class type was found.
class_decl_sptr
lookup_class_type(const interned_string& type_name, const translation_unit& tu)
{
  return lookup_type_in_map<class_decl>(type_name,
					tu.get_types().class_types());
}

/// Lookup a union type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param type_name the name of the union type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the union type found or nil if no union type was found.
union_decl_sptr
lookup_union_type(const interned_string& type_name, const translation_unit& tu)
{
  return lookup_type_in_map<union_decl>(type_name,
					tu.get_types().union_types());
}

/// Lookup a union type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param fqn the fully qualified name of the type to lookup.
///
/// @param tu the translation unit to look into.
///
/// @return the union type found or nil if no union type was found.
union_decl_sptr
lookup_union_type(const string& fqn, const translation_unit& tu)
{
  const environment* env = tu.get_environment();
  ABG_ASSERT(env);

  interned_string s = env->intern(fqn);
  return lookup_union_type(s, tu);
}

/// Lookup a union type in a given corpus, from its location.
///
/// @param loc the location of the union type to look for.
///
/// @param corp the corpus to look it from.
///
/// @return the resulting union_decl.
union_decl_sptr
lookup_union_type_per_location(const interned_string &loc, const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m =
    corp.get_type_per_loc_map().union_types();
  union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);

  return result;
}

/// Lookup a union type in a given corpus, from its location.
///
/// @param loc the location of the union type to look for.
///
/// @param corp the corpus to look it from.
///
/// @return the resulting union_decl.
union_decl_sptr
lookup_union_type_per_location(const string& loc, const corpus& corp)
{
  const environment* env = corp.get_environment();
  ABG_ASSERT(env);

  return lookup_union_type_per_location(env->intern(loc), corp);
}

/// Lookup an enum type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param type_name the name of the enum type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the enum type found or nil if no enum type was found.
enum_type_decl_sptr
lookup_enum_type(const interned_string& type_name, const translation_unit& tu)
{
  return lookup_type_in_map<enum_type_decl>(type_name,
					    tu.get_types().enum_types());
}

/// Lookup an enum type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param type_name the name of the enum type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the enum type found or nil if no enum type was found.
enum_type_decl_sptr
lookup_enum_type(const string& type_name, const translation_unit& tu)
{
  const environment* env = tu.get_environment();
  ABG_ASSERT(env);

  interned_string s = env->intern(type_name);
  return lookup_enum_type(s, tu);
}

/// Lookup a typedef type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param type_name the name of the typedef type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the typedef type found or nil if no typedef type was
/// found.
typedef_decl_sptr
lookup_typedef_type(const interned_string& type_name,
		    const translation_unit& tu)
{
  return lookup_type_in_map<typedef_decl>(type_name,
					  tu.get_types().typedef_types());
}

/// Lookup a typedef type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param type_name the name of the typedef type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the typedef type found or nil if no typedef type was
/// found.
typedef_decl_sptr
lookup_typedef_type(const string& type_name, const translation_unit& tu)
{
  const environment* env = tu.get_environment();
  ABG_ASSERT(env);

  interned_string s = env->intern(type_name);
  return lookup_typedef_type(s, tu);
}

/// Lookup a qualified type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param type_name the name of the qualified type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the qualified type found or nil if no qualified type was
/// found.
qualified_type_def_sptr
lookup_qualified_type(const interned_string& type_name,
		      const translation_unit& tu)
{
  const type_maps& m = tu.get_types();
  return lookup_type_in_map<qualified_type_def>(type_name,
						m.qualified_types());
}

/// Lookup a qualified type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param underlying_type the underying type of the qualified type to
/// look up.
///
/// @param quals the CV-qualifiers of the qualified type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the qualified type found or nil if no qualified type was
/// found.
qualified_type_def_sptr
lookup_qualified_type(const type_base_sptr& underlying_type,
		      qualified_type_def::CV quals,
		      const translation_unit& tu)
{
  interned_string type_name = get_name_of_qualified_type(underlying_type,
							 quals);
  return lookup_qualified_type(type_name, tu);
}

/// Lookup a pointer type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param type_name the name of the pointer type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the pointer type found or nil if no pointer type was
/// found.
pointer_type_def_sptr
lookup_pointer_type(const interned_string& type_name,
		    const translation_unit& tu)
{
  const type_maps& m = tu.get_types();
  return lookup_type_in_map<pointer_type_def>(type_name,
					      m.pointer_types());
}

/// Lookup a pointer type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param type_name the name of the pointer type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the pointer type found or nil if no pointer type was
/// found.
pointer_type_def_sptr
lookup_pointer_type(const string& type_name, const translation_unit& tu)
{
  const environment* env = tu.get_environment();
  ABG_ASSERT(env);

  interned_string s = env->intern(type_name);
  return lookup_pointer_type(s, tu);
}

/// Lookup a pointer type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param pointed_to_type the pointed-to-type of the pointer to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the pointer type found or nil if no pointer type was
/// found.
pointer_type_def_sptr
lookup_pointer_type(const type_base_sptr& pointed_to_type,
		    const translation_unit& tu)
{
  interned_string type_name = get_name_of_pointer_to_type(*pointed_to_type);
  return lookup_pointer_type(type_name, tu);
}

/// Lookup a reference type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param type_name the name of the reference type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the reference type found or nil if no reference type was
/// found.
reference_type_def_sptr
lookup_reference_type(const interned_string& type_name,
		      const translation_unit& tu)
{
  const type_maps& m = tu.get_types();
  return lookup_type_in_map<reference_type_def>(type_name,
						m.reference_types());
}

/// Lookup a reference type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param pointed_to_type the pointed-to-type of the reference to
/// look up.
///
/// @param tu the translation unit to look into.
///
/// @return the reference type found or nil if no reference type was
/// found.
const reference_type_def_sptr
lookup_reference_type(const type_base_sptr& pointed_to_type,
		      bool lvalue_reference,
		      const translation_unit& tu)
{
  interned_string type_name =
    get_name_of_reference_to_type(*pointed_to_type, lvalue_reference);
  return lookup_reference_type(type_name, tu);
}

/// Lookup an array type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param type_name the name of the array type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the array type found or nil if no array type was found.
array_type_def_sptr
lookup_array_type(const interned_string& type_name,
		  const translation_unit& tu)
{
  const type_maps& m = tu.get_types();
  return lookup_type_in_map<array_type_def>(type_name,
					    m.array_types());
}

/// Lookup a function type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param type_name the name of the type to lookup.
///
/// @param tu the translation unit to look into.
///
/// @return the function type found, or NULL of none was found.
function_type_sptr
lookup_function_type(const interned_string& type_name,
		     const translation_unit& tu)
{
  const type_maps& m = tu.get_types();
  return lookup_type_in_map<function_type>(type_name,
					   m.function_types());
}

/// Lookup a function type from a translation unit.
///
/// This walks all the function types held by the translation unit and
/// compare their sub-type *names*.  If the names match then return
/// the function type found in the translation unit.
///
/// @param t the function type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the function type found, or NULL of none was found.
function_type_sptr
lookup_function_type(const function_type& t,
		     const translation_unit& tu)
{
  interned_string type_name = get_type_name(t);
  return lookup_function_type(type_name, tu);
}

/// Lookup a function type from a translation unit.
///
/// This is done by looking the type up in the type map that is
/// maintained in the translation unit.  So this is as fast as
/// possible.
///
/// @param t the function type to look for.
///
/// @param tu the translation unit to look into.
///
/// @return the function type found, or NULL of none was found.
function_type_sptr
lookup_function_type(const function_type_sptr& t,
		     const translation_unit& tu)
{return lookup_function_type(*t, tu);}

/// Lookup a type in a translation unit.
///
/// @param fqn the fully qualified name of the type to lookup.
///
/// @param tu the translation unit to consider.
///
/// @return the declaration of the type if found, NULL otherwise.
const type_base_sptr
lookup_type(const interned_string& fqn,
	    const translation_unit& tu)
{
  type_base_sptr result;
  ((result = lookup_typedef_type(fqn, tu))
   || (result = lookup_class_type(fqn, tu))
   || (result = lookup_union_type(fqn, tu))
   || (result = lookup_enum_type(fqn, tu))
   || (result = lookup_qualified_type(fqn, tu))
   || (result = lookup_pointer_type(fqn, tu))
   || (result = lookup_reference_type(fqn, tu))
   || (result = lookup_array_type(fqn, tu))
   || (result = lookup_function_type(fqn, tu))
   || (result = lookup_basic_type(fqn, tu)));

  return result;
}

/// Lookup a type in a translation unit, starting from the global
/// namespace.
///
/// @param fqn the fully qualified name of the type to lookup.
///
/// @param tu the translation unit to consider.
///
/// @return the declaration of the type if found, NULL otherwise.
type_base_sptr
lookup_type(const string& fqn, const translation_unit& tu)
{
  const environment *env = tu.get_environment();
  ABG_ASSERT(env);
  interned_string ifqn = env->intern(fqn);
  return lookup_type(ifqn, tu);
}

/// Lookup a type from a translation unit.
///
/// @param fqn the components of the fully qualified name of the node
/// to look up.
///
/// @param tu the translation unit to perform lookup from.
///
/// @return the declaration of the IR node found, NULL otherwise.
const type_base_sptr
lookup_type(const type_base_sptr type,
	    const translation_unit& tu)
{
  interned_string type_name = get_type_name(type);
  return lookup_type(type_name, tu);
}

/// Lookup a type in a scope.
///
/// This is really slow as it walks the member types of the scope in
/// sequence to find the type with a given name.
///
/// If possible, users should prefer looking up types from the
/// enclosing translation unit or even ABI corpus because both the
/// translation unit and the corpus have a map of type, indexed by
/// their name.  Looking up a type from those maps is thus much
/// faster.
///
/// @param fqn the fully qualified name of the type to lookup.
///
/// @param skope the scope to look into.
///
/// @return the declaration of the type if found, NULL otherwise.
const type_base_sptr
lookup_type_in_scope(const string& fqn,
		     const scope_decl_sptr& skope)
{
  list<string> comps;
  fqn_to_components(fqn, comps);
  return lookup_type_in_scope(comps, skope);
}

/// Lookup a @ref var_decl in a scope.
///
/// @param fqn the fuly qualified name of the @var_decl to lookup.
///
/// @param skope the scope to look into.
///
/// @return the declaration of the @ref var_decl if found, NULL
/// otherwise.
const decl_base_sptr
lookup_var_decl_in_scope(const string& fqn,
			 const scope_decl_sptr& skope)
{
  list<string> comps;
  fqn_to_components(fqn, comps);
  return lookup_var_decl_in_scope(comps, skope);
}

/// A generic function (template) to get the name of a node, whatever
/// node it is.  This has to be specialized for the kind of node we
/// want.
///
/// Note that a node is a member of a scope.
///
/// @tparam NodeKind the kind of node to consider.
///
/// @param node the node to get the name from.
///
/// @return the name of the node.
template<typename NodeKind>
static const interned_string&
get_node_name(shared_ptr<NodeKind> node);

/// Gets the name of a class_decl node.
///
/// @param node the decl_base node to get the name from.
///
/// @return the name of the node.
template<>
const interned_string&
get_node_name(class_decl_sptr node)
{return node->get_name();}

/// Gets the name of a type_base node.
///
/// @param node the type_base node to get the name from.
///
/// @return the name of the node.
template<>
const interned_string&
get_node_name(type_base_sptr node)
{return get_type_declaration(node)->get_name();}

/// Gets the name of a var_decl node.
///
/// @param node the var_decl node to get the name from.
///
/// @return the name of the node.
template<>
const interned_string&
get_node_name(var_decl_sptr node)
{return node->get_name();}

/// Generic function to get the declaration of a given node, whatever
/// it is.  There has to be specializations for the kind of the nodes
/// we want to support.
///
/// @tparam NodeKind the type of the node we are looking at.
///
/// @return the declaration.
template<typename NodeKind>
static decl_base_sptr
convert_node_to_decl(shared_ptr<NodeKind> node);

/// Lookup a node in a given scope.
///
/// @tparam the type of the node to lookup.
///
/// @param fqn the components of the fully qualified name of the node
/// to lookup.
///
/// @param skope the scope to look into.
///
/// @return the declaration of the looked up node, or NULL if it
/// wasn't found.
template<typename NodeKind>
static const type_or_decl_base_sptr
lookup_node_in_scope(const list<string>& fqn,
		     const scope_decl_sptr& skope)
{
  type_or_decl_base_sptr resulting_decl;
  shared_ptr<NodeKind> node;
  bool it_is_last = false;
  scope_decl_sptr cur_scope = skope, new_scope, scope;

  for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
    {
      new_scope.reset();
      it_is_last = iterator_is_last(fqn, c);
      for (scope_decl::declarations::const_iterator m =
	     cur_scope->get_member_decls().begin();
	   m != cur_scope->get_member_decls().end();
	   ++m)
	{
	  if (!it_is_last)
	    {
	      // looking for a scope
	      scope = dynamic_pointer_cast<scope_decl>(*m);
	      if (scope && scope->get_name() == *c)
		{
		  new_scope = scope;
		  break;
		}
	    }
	  else
	    {
	      //looking for a final type.
	      node = dynamic_pointer_cast<NodeKind>(*m);
	      if (node && get_node_name(node) == *c)
		{
		  if (class_decl_sptr cl =
		      dynamic_pointer_cast<class_decl>(node))
		    if (cl->get_is_declaration_only()
			&& !cl->get_definition_of_declaration())
		      continue;
		  resulting_decl = node;
		  break;
		}
	    }
	}
      if (!new_scope && !resulting_decl)
	return decl_base_sptr();
      cur_scope = new_scope;
    }
  ABG_ASSERT(resulting_decl);
  return resulting_decl;
}

/// lookup a type in a scope.
///
///
/// This is really slow as it walks the member types of the scope in
/// sequence to find the type with a given name.
///
/// If possible, users should prefer looking up types from the
/// enclosing translation unit or even ABI corpus because both the
/// translation unit and the corpus have a map of type, indexed by
/// their name.  Looking up a type from those maps is thus much
/// faster.
///
/// @param comps the components of the fully qualified name of the
/// type to lookup.
///
/// @param skope the scope to look into.
///
/// @return the declaration of the type found.
const type_base_sptr
lookup_type_in_scope(const list<string>& comps,
		     const scope_decl_sptr& scope)
{return is_type(lookup_node_in_scope<type_base>(comps, scope));}

/// lookup a type in a scope.
///
/// This is really slow as it walks the member types of the scope in
/// sequence to find the type with a given name.
///
/// If possible, users should prefer looking up types from the
/// enclosing translation unit or even ABI corpus because both the
/// translation unit and the corpus have a map of type, indexed by
/// their name.  Looking up a type from those maps is thus much
/// faster.
///
/// @param type the type to look for.
///
/// @param access_path a vector of scopes the path of scopes to follow
/// before reaching the scope into which to look for @p type.  Note
/// that the deepest scope (the one immediately containing @p type) is
/// at index 0 of this vector, and the top-most scope is the last
/// element of the vector.
///
/// @param scope the top-most scope into which to look for @p type.
///
/// @return the scope found in @p scope, or NULL if it wasn't found.
static const type_base_sptr
lookup_type_in_scope(const type_base& type,
		     const vector<scope_decl*>& access_path,
		     const scope_decl* scope)
{
  vector<scope_decl*> a = access_path;
  type_base_sptr result;

  scope_decl* first_scope = 0;
  if (!a.empty())
    {
      first_scope = a.back();
      ABG_ASSERT(first_scope->get_name() == scope->get_name());
      a.pop_back();
    }

  if (a.empty())
    {
      interned_string n = get_type_name(type, false);
      for (scope_decl::declarations::const_iterator i =
	     scope->get_member_decls().begin();
	   i != scope->get_member_decls().end();
	   ++i)
	if (is_type(*i) && (*i)->get_name() == n)
	  {
	    result = is_type(*i);
	    break;
	  }
    }
  else
    {
      first_scope = a.back();
      interned_string scope_name, cur_scope_name = first_scope->get_name();
      for (scope_decl::scopes::const_iterator i =
	     scope->get_member_scopes().begin();
	   i != scope->get_member_scopes().end();
	   ++i)
	{
	  scope_name = (*i)->get_name();
	  if (scope_name == cur_scope_name)
	    {
	      result = lookup_type_in_scope(type, a, (*i).get());
	      break;
	    }
	}
    }
  return result;
}

/// lookup a type in a scope.
///
/// This is really slow as it walks the member types of the scope in
/// sequence to find the type with a given name.
///
/// If possible, users should prefer looking up types from the
/// enclosing translation unit or even ABI corpus because both the
/// translation unit and the corpus have a map of type, indexed by
/// their name.  Looking up a type from those maps is thus much
/// faster.
///
/// @param type the type to look for.
///
/// @param scope the top-most scope into which to look for @p type.
///
/// @return the scope found in @p scope, or NULL if it wasn't found.
static const type_base_sptr
lookup_type_in_scope(const type_base_sptr type,
		     const scope_decl* scope)
{
  if (!type || is_function_type(type))
    return type_base_sptr();

  decl_base_sptr type_decl = get_type_declaration(type);
  ABG_ASSERT(type_decl);
  vector<scope_decl*> access_path;
  for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
    {
      access_path.push_back(s);
      if (is_global_scope(s))
	break;
    }
  return lookup_type_in_scope(*type, access_path, scope);
}

/// Lookup a type from a translation unit by walking the scopes of the
/// translation unit in sequence and looking into them.
///
/// This is really slow as it walks the member types of the scopes in
/// sequence to find the type with a given name.
///
/// If possible, users should prefer looking up types from the
/// translation unit or even ABI corpus in a more direct way, by using
/// the lookup_type() functins.
///
///
/// This is because both the translation unit and the corpus have a
/// map of types, indexed by their name.  Looking up a type from those
/// maps is thus much faster.  @param fqn the components of the fully
/// qualified name of the node to look up.
///
/// @param tu the translation unit to perform lookup from.
///
/// @return the declaration of the IR node found, NULL otherwise.
const type_base_sptr
lookup_type_through_scopes(const type_base_sptr type,
			   const translation_unit& tu)
{
  if (function_type_sptr fn_type = is_function_type(type))
    return lookup_function_type(fn_type, tu);
  return lookup_type_in_scope(type, tu.get_global_scope().get());
}

/// lookup a var_decl in a scope.
///
/// @param comps the components of the fully qualified name of the
/// var_decl to lookup.
///
/// @param skope the scope to look into.
const decl_base_sptr
lookup_var_decl_in_scope(const std::list<string>& comps,
			 const scope_decl_sptr& skope)
{return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}

/// Lookup an IR node from a translation unit.
///
/// @tparam NodeKind the type of the IR node to lookup from the
/// translation unit.
///
/// @param fqn the components of the fully qualified name of the node
/// to look up.
///
/// @param tu the translation unit to perform lookup from.
///
/// @return the declaration of the IR node found, NULL otherwise.
template<typename NodeKind>
static const type_or_decl_base_sptr
lookup_node_in_translation_unit(const list<string>& fqn,
				const translation_unit& tu)
{return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}

/// Lookup a type from a translation unit by walking its scopes in
/// sequence and by looking into them.
///
/// This is much slower than using the lookup_type() function.
///
/// @param fqn the components of the fully qualified name of the node
/// to look up.
///
/// @param tu the translation unit to perform lookup from.
///
/// @return the declaration of the IR node found, NULL otherwise.
type_base_sptr
lookup_type_through_scopes(const list<string>& fqn,
			   const translation_unit& tu)
{return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}


/// Lookup a class type from a translation unit by walking its scopes
/// in sequence and by looking into them.
///
/// This is much slower than using the lookup_class_type() function
/// because it walks all the scopes of the translation unit in
/// sequence and lookup the types to find one that has a given name.
///
/// @param fqn the components of the fully qualified name of the class
/// type node to look up.
///
/// @param tu the translation unit to perform lookup from.
///
/// @return the declaration of the class type IR node found, NULL
/// otherwise.
class_decl_sptr
lookup_class_type_through_scopes(const list<string>& fqn,
				 const translation_unit& tu)
{return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}

/// Lookup a basic type from all the translation units of a given
/// corpus.
///
/// @param fqn the components of the fully qualified name of the basic
/// type node to look up.
///
/// @param tu the translation unit to perform lookup from.
///
/// @return the declaration of the basic type IR node found, NULL
/// otherwise.
static type_decl_sptr
lookup_basic_type_through_translation_units(const interned_string& type_name,
					    const corpus& abi_corpus)
{
  type_decl_sptr result;

  for (translation_units::const_iterator tu =
	 abi_corpus.get_translation_units().begin();
       tu != abi_corpus.get_translation_units().end();
       ++tu)
    if ((result = lookup_basic_type(type_name, **tu)))
      break;

  return result;
}

/// Lookup a union type from all the translation units of a given
/// corpus.
///
/// @param fqn the components of the fully qualified name of the union
/// type node to look up.
///
/// @param tu the translation unit to perform lookup from.
///
/// @return the declaration of the union type IR node found, NULL
/// otherwise.
static union_decl_sptr
lookup_union_type_through_translation_units(const interned_string& type_name,
					    const corpus & abi_corpus)
{
 union_decl_sptr result;

  for (translation_units::const_iterator tu =
	 abi_corpus.get_translation_units().begin();
       tu != abi_corpus.get_translation_units().end();
       ++tu)
    if ((result = lookup_union_type(type_name, **tu)))
      break;

  return result;
}

/// Lookup an enum type from all the translation units of a given
/// corpus.
///
/// @param fqn the components of the fully qualified name of the enum
/// type node to look up.
///
/// @param tu the translation unit to perform lookup from.
///
/// @return the declaration of the enum type IR node found, NULL
/// otherwise.
static enum_type_decl_sptr
lookup_enum_type_through_translation_units(const interned_string& type_name,
					   const corpus & abi_corpus)
{
  enum_type_decl_sptr result;

  for (translation_units::const_iterator tu =
	 abi_corpus.get_translation_units().begin();
       tu != abi_corpus.get_translation_units().end();
       ++tu)
    if ((result = lookup_enum_type(type_name, **tu)))
      break;

  return result;
}

/// Lookup a typedef type definition in all the translation units of a
/// given ABI corpus.
///
/// @param @param qn the fully qualified name of the typedef type to lookup.
///
/// @param abi_corpus the ABI corpus which to look the type up in.
///
/// @return the type definition if any was found, or a NULL pointer.
static typedef_decl_sptr
lookup_typedef_type_through_translation_units(const interned_string& type_name,
					      const corpus & abi_corpus)
{
  typedef_decl_sptr result;

  for (translation_units::const_iterator tu =
	 abi_corpus.get_translation_units().begin();
       tu != abi_corpus.get_translation_units().end();
       ++tu)
    if ((result = lookup_typedef_type(type_name, **tu)))
      break;

  return result;
}

/// Lookup a qualified type definition in all the translation units of a
/// given ABI corpus.
///
/// @param @param qn the fully qualified name of the qualified type to
/// lookup.
///
/// @param abi_corpus the ABI corpus which to look the type up in.
///
/// @return the type definition if any was found, or a NULL pointer.
static qualified_type_def_sptr
lookup_qualified_type_through_translation_units(const interned_string& t_name,
						const corpus & abi_corpus)
{
  qualified_type_def_sptr result;

  for (translation_units::const_iterator tu =
	 abi_corpus.get_translation_units().begin();
       tu != abi_corpus.get_translation_units().end();
       ++tu)
    if ((result = lookup_qualified_type(t_name, **tu)))
      break;

  return result;
}

/// Lookup a pointer type definition in all the translation units of a
/// given ABI corpus.
///
/// @param @param qn the fully qualified name of the pointer type to
/// lookup.
///
/// @param abi_corpus the ABI corpus which to look the type up in.
///
/// @return the type definition if any was found, or a NULL pointer.
static pointer_type_def_sptr
lookup_pointer_type_through_translation_units(const interned_string& type_name,
					      const corpus & abi_corpus)
{
  pointer_type_def_sptr result;

  for (translation_units::const_iterator tu =
	 abi_corpus.get_translation_units().begin();
       tu != abi_corpus.get_translation_units().end();
       ++tu)
    if ((result = lookup_pointer_type(type_name, **tu)))
      break;

  return result;
}

/// Lookup a reference type definition in all the translation units of a
/// given ABI corpus.
///
/// @param @param qn the fully qualified name of the reference type to
/// lookup.
///
/// @param abi_corpus the ABI corpus which to look the type up in.
///
/// @return the type definition if any was found, or a NULL pointer.
static reference_type_def_sptr
lookup_reference_type_through_translation_units(const interned_string& t_name,
						const corpus & abi_corpus)
{
  reference_type_def_sptr result;

  for (translation_units::const_iterator tu =
	 abi_corpus.get_translation_units().begin();
       tu != abi_corpus.get_translation_units().end();
       ++tu)
    if ((result = lookup_reference_type(t_name, **tu)))
      break;

  return result;
}

/// Lookup a array type definition in all the translation units of a
/// given ABI corpus.
///
/// @param @param qn the fully qualified name of the array type to
/// lookup.
///
/// @param abi_corpus the ABI corpus which to look the type up in.
///
/// @return the type definition if any was found, or a NULL pointer.
static array_type_def_sptr
lookup_array_type_through_translation_units(const interned_string& type_name,
					    const corpus & abi_corpus)
{
  array_type_def_sptr result;

  for (translation_units::const_iterator tu =
	 abi_corpus.get_translation_units().begin();
       tu != abi_corpus.get_translation_units().end();
       ++tu)
    if ((result = lookup_array_type(type_name, **tu)))
      break;

  return result;
}

/// Lookup a function type definition in all the translation units of
/// a given ABI corpus.
///
/// @param @param qn the fully qualified name of the function type to
/// lookup.
///
/// @param abi_corpus the ABI corpus which to look the type up in.
///
/// @return the type definition if any was found, or a NULL pointer.
static function_type_sptr
lookup_function_type_through_translation_units(const interned_string& type_name,
					       const corpus & abi_corpus)
{
  function_type_sptr result;

  for (translation_units::const_iterator tu =
	 abi_corpus.get_translation_units().begin();
       tu != abi_corpus.get_translation_units().end();
       ++tu)
    if ((result = lookup_function_type(type_name, **tu)))
      break;

  return result;
}

/// Lookup a type definition in all the translation units of a given
/// ABI corpus.
///
/// @param @param qn the fully qualified name of the type to lookup.
///
/// @param abi_corpus the ABI corpus which to look the type up in.
///
/// @return the type definition if any was found, or a NULL pointer.
type_base_sptr
lookup_type_through_translation_units(const string& qn,
				      const corpus& abi_corpus)
{
  type_base_sptr result;

  for (translation_units::const_iterator tu =
	 abi_corpus.get_translation_units().begin();
       tu != abi_corpus.get_translation_units().end();
       ++tu)
    if ((result = lookup_type(qn, **tu)))
      break;

  return result;
}

/// Lookup a type from a given translation unit present in a give corpus.
///
/// @param type_name the name of the type to look for.
///
/// @parm tu_path the path of the translation unit to consider.
///
/// @param corp the corpus to consider.
///
/// @return the resulting type, if any.
type_base_sptr
lookup_type_from_translation_unit(const string& type_name,
				  const string& tu_path,
				  const corpus& corp)
{
  string_tu_map_type::const_iterator i =  corp.priv_->path_tu_map.find(tu_path);
  if (i == corp.priv_->path_tu_map.end())
    return type_base_sptr();

  translation_unit_sptr tu = i->second;
  ABG_ASSERT(tu);

  type_base_sptr t = lookup_type(type_name, *tu);
  return t;
}

/// Look into an ABI corpus for a function type.
///
/// @param fn_type the function type to be looked for in the ABI
/// corpus.
///
/// @param corpus the ABI corpus into which to look for the function
/// type.
///
/// @return the function type found in the corpus.
function_type_sptr
lookup_or_synthesize_fn_type(const function_type_sptr& fn_t,
			     const corpus& corpus)
{
  ABG_ASSERT(fn_t);

  function_type_sptr result;

  if ((result = lookup_function_type(fn_t, corpus)))
    return result;

  for (translation_units::const_iterator i =
	 corpus.get_translation_units().begin();
       i != corpus.get_translation_units().end();
       ++i)
    if ((result = synthesize_function_type_from_translation_unit(*fn_t,
								 **i)))
      return result;

  return result;
}

/// Look into a given corpus to find a type which has the same
/// qualified name as a giventype.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param t the type which has the same qualified name as the type we
/// are looking for.
///
/// @param corp the ABI corpus to look into for the type.
type_decl_sptr
lookup_basic_type(const type_decl& t, const corpus& corp)
{return lookup_basic_type(t.get_name(), corp);}

/// Look into a given corpus to find a basic type which has a given
/// qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the basic type to look
/// for.
///
/// @param corp the corpus to look into.
type_decl_sptr
lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m = corp.get_types().basic_types();
  type_decl_sptr result;

  if (!m.empty())
    result = lookup_type_in_map<type_decl>(qualified_name, m);
  else
    result = lookup_basic_type_through_translation_units(qualified_name, corp);

  return result;
}

/// Lookup a @ref type_decl type from a given corpus, by its location.
///
/// @param loc the location to consider.
///
/// @param corp the corpus to consider.
///
/// @return the resulting basic type, if any.
type_decl_sptr
lookup_basic_type_per_location(const interned_string &loc,
			       const corpus &corp)
{
  const istring_type_base_wptrs_map_type& m =
    corp.get_type_per_loc_map().basic_types();
  type_decl_sptr result;

  result = lookup_type_in_map<type_decl>(loc, m);

  return result;
}

/// Lookup a @ref type_decl type from a given corpus, by its location.
///
/// @param loc the location to consider.
///
/// @param corp the corpus to consider.
///
/// @return the resulting basic type, if any.
type_decl_sptr
lookup_basic_type_per_location(const string &loc, const corpus &corp)
{
  const environment* env = corp.get_environment();
  ABG_ASSERT(env);

  return lookup_basic_type_per_location(env->intern(loc), corp);
}

/// Look into a given corpus to find a basic type which has a given
/// qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the basic type to look
/// for.
///
/// @param corp the corpus to look into.
type_decl_sptr
lookup_basic_type(const string& qualified_name, const corpus& corp)
{
  return lookup_basic_type(corp.get_environment()->intern(qualified_name),
			   corp);
}

/// Look into a given corpus to find a class type which has the same
/// qualified name as a given type.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param t the class decl type which has the same qualified name as
/// the type we are looking for.
///
/// @param corp the corpus to look into.
class_decl_sptr
lookup_class_type(const class_decl& t, const corpus& corp)
{
  interned_string s = get_type_name(t);
  return lookup_class_type(s, corp);
}

/// Look into a given corpus to find a class type which has a given
/// qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the type to look for.
///
/// @param corp the corpus to look into.
class_decl_sptr
lookup_class_type(const string& qualified_name, const corpus& corp)
{
  interned_string s = corp.get_environment()->intern(qualified_name);
  return lookup_class_type(s, corp);
}

/// Look into a given corpus to find a class type which has a given
/// qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the type to look for.
///
/// @param corp the corpus to look into.
class_decl_sptr
lookup_class_type(const interned_string& qualified_name, const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();

  class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);

  return result;
}

/// Look into a given corpus to find the class type*s* that have a
/// given qualified name.
///
/// @param qualified_name the qualified name of the type to look for.
///
/// @param corp the corpus to look into.
///
/// @return the vector of class types named @p qualified_name.
const type_base_wptrs_type *
lookup_class_types(const interned_string& qualified_name, const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();

  return lookup_types_in_map(qualified_name, m);
}

/// Look into a given corpus to find the class type*s* that have a
/// given qualified name.
///
/// @param qualified_name the qualified name of the type to look for.
///
/// @param corp the corpus to look into.
///
/// @return the vector of class types that which name is @p qualified_name.
const type_base_wptrs_type*
lookup_class_types(const string& qualified_name, const corpus& corp)
{
  interned_string s = corp.get_environment()->intern(qualified_name);
  return lookup_class_types(s, corp);
}

/// Look up a @ref class_decl from a given corpus by its location.
///
/// @param loc the location to consider.
///
/// @param corp the corpus to consider.
///
/// @return the resulting class decl, if any.
class_decl_sptr
lookup_class_type_per_location(const interned_string& loc,
			       const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m =
    corp.get_type_per_loc_map().class_types();
  class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);

  return result;
}

/// Look up a @ref class_decl from a given corpus by its location.
///
/// @param loc the location to consider.
///
/// @param corp the corpus to consider.
///
/// @return the resulting class decl, if any.
class_decl_sptr
lookup_class_type_per_location(const string &loc, const corpus &corp)
{
  const environment* env = corp.get_environment();
  ABG_ASSERT(env);

  return lookup_class_type_per_location(env->intern(loc), corp);
}

/// Look into a given corpus to find a union type which has a given
/// qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the type to look for.
///
/// @param corp the corpus to look into.
union_decl_sptr
lookup_union_type(const interned_string& type_name, const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m = corp.get_types().union_types();

  union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
  if (!result)
    result = lookup_union_type_through_translation_units(type_name, corp);

  return result;
}

/// Look into a given corpus to find a union type which has a given
/// qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the type to look for.
///
/// @param corp the corpus to look into.
union_decl_sptr
lookup_union_type(const string& type_name, const corpus& corp)
{
  interned_string s = corp.get_environment()->intern(type_name);
  return lookup_union_type(s, corp);
}

/// Look into a given corpus to find an enum type which has the same
/// qualified name as a given enum type.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param t the enum type which has the same qualified name as the
/// type we are looking for.
///
/// @param corp the corpus to look into.
enum_type_decl_sptr
lookup_enum_type(const enum_type_decl& t, const corpus& corp)
{
  interned_string s = get_type_name(t);
  return lookup_enum_type(s, corp);
}

/// Look into a given corpus to find an enum type which has a given
/// qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the enum type to look
/// for.
///
/// @param corp the corpus to look into.
enum_type_decl_sptr
lookup_enum_type(const string& qualified_name, const corpus& corp)
{
  interned_string s = corp.get_environment()->intern(qualified_name);
  return lookup_enum_type(s, corp);
}

/// Look into a given corpus to find an enum type which has a given
/// qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the enum type to look
/// for.
///
/// @param corp the corpus to look into.
enum_type_decl_sptr
lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m = corp.get_types().enum_types();

  enum_type_decl_sptr result =
    lookup_type_in_map<enum_type_decl>(qualified_name, m);
  if (!result)
    result = lookup_enum_type_through_translation_units(qualified_name, corp);

  return result;
}

/// Look into a given corpus to find the enum type*s* that have a
/// given qualified name.
///
/// @param qualified_name the qualified name of the type to look for.
///
/// @param corp the corpus to look into.
///
/// @return the vector of enum types that which name is @p qualified_name.
const type_base_wptrs_type *
lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m = corp.get_types().enum_types();

  return lookup_types_in_map(qualified_name, m);
}

/// Look into a given corpus to find the enum type*s* that have a
/// given qualified name.
///
/// @param qualified_name the qualified name of the type to look for.
///
/// @param corp the corpus to look into.
///
/// @return the vector of enum types that which name is @p qualified_name.
const type_base_wptrs_type*
lookup_enum_types(const string& qualified_name, const corpus& corp)
{
  interned_string s = corp.get_environment()->intern(qualified_name);
  return lookup_enum_types(s, corp);
}

/// Look up an @ref enum_type_decl from a given corpus, by its location.
///
/// @param loc the location to consider.
///
/// @param corp the corpus to look the type from.
///
/// @return the resulting enum type, if any.
enum_type_decl_sptr
lookup_enum_type_per_location(const interned_string &loc, const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m =
    corp.get_type_per_loc_map().enum_types();
  enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);

  return result;
}

/// Look up an @ref enum_type_decl from a given corpus, by its location.
///
/// @param loc the location to consider.
///
/// @param corp the corpus to look the type from.
///
/// @return the resulting enum type, if any.
enum_type_decl_sptr
lookup_enum_type_per_location(const string &loc, const corpus &corp)
{
  const environment* env = corp.get_environment();
  ABG_ASSERT(env);

  return lookup_enum_type_per_location(env->intern(loc), corp);
}

/// Look into a given corpus to find a typedef type which has the
/// same qualified name as a given typedef type.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param t the typedef type which has the same qualified name as the
/// typedef type we are looking for.
///
/// @param corp the corpus to look into.
typedef_decl_sptr
lookup_typedef_type(const typedef_decl& t, const corpus& corp)
{
  interned_string s = get_type_name(t);
  return lookup_typedef_type(s, corp);
}

/// Look into a given corpus to find a typedef type which has the
/// same qualified name as a given typedef type.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param t the typedef type which has the same qualified name as the
/// typedef type we are looking for.
///
/// @param corp the corpus to look into.
typedef_decl_sptr
lookup_typedef_type(const string& qualified_name, const corpus& corp)
{
  interned_string s = corp.get_environment()->intern(qualified_name);
  return lookup_typedef_type(s, corp);
}

/// Look into a given corpus to find a typedef type which has a
/// given qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the typedef type to
/// look for.
///
/// @param corp the corpus to look into.
typedef_decl_sptr
lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m = corp.get_types().typedef_types();

  typedef_decl_sptr result =
    lookup_type_in_map<typedef_decl>(qualified_name, m);
  if (!result)
    result = lookup_typedef_type_through_translation_units(qualified_name,
							   corp);

  return result;
}

/// Lookup a @ref typedef_decl from a corpus, by its location.
///
/// @param loc the location to consider.
///
/// @param corp the corpus to consider.
///
/// @return the typedef_decl found, if any.
typedef_decl_sptr
lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
{
  const istring_type_base_wptrs_map_type& m =
    corp.get_type_per_loc_map().typedef_types();
  typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);

  return result;
}

/// Lookup a @ref typedef_decl from a corpus, by its location.
///
/// @param loc the location to consider.
///
/// @param corp the corpus to consider.
///
/// @return the typedef_decl found, if any.
typedef_decl_sptr
lookup_typedef_type_per_location(const string &loc, const corpus &corp)
{
  const environment* env = corp.get_environment();
  ABG_ASSERT(env);

  return lookup_typedef_type_per_location(env->intern(loc), corp);
}

/// Look into a corpus to find a class, union or typedef type which
/// has a given qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the name of the type to find.
///
/// @param corp the corpus to look into.
///
/// @return the typedef or class type found.
type_base_sptr
lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
{
  type_base_sptr result = lookup_class_type(qualified_name, corp);
  if (!result)
    result = lookup_union_type(qualified_name, corp);

  if (!result)
    result = lookup_typedef_type(qualified_name, corp);
  return result;
}

/// Look into a corpus to find a class, typedef or enum type which has
/// a given qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the type to look for.
///
/// @param corp the corpus to look into.
///
/// @return the typedef, class or enum type found.
type_base_sptr
lookup_class_typedef_or_enum_type(const string& qualified_name,
				  const corpus& corp)
{
  type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
  if (!result)
    result = lookup_enum_type(qualified_name, corp);

  return result;
}

/// Look into a given corpus to find a qualified type which has the
/// same qualified name as a given type.
///
/// @param t the type which has the same qualified name as the
/// qualified type we are looking for.
///
/// @param corp the corpus to look into.
///
/// @return the qualified type found.
qualified_type_def_sptr
lookup_qualified_type(const qualified_type_def& t, const corpus& corp)
{
  interned_string s = get_type_name(t);
  return lookup_qualified_type(s, corp);
}

/// Look into a given corpus to find a qualified type which has a
/// given qualified name.
///
/// @param qualified_name the qualified name of the type to look for.
///
/// @param corp the corpus to look into.
///
/// @return the type found.
qualified_type_def_sptr
lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m =
    corp.get_types().qualified_types();

  qualified_type_def_sptr result =
    lookup_type_in_map<qualified_type_def>(qualified_name, m);

  if (!result)
    result = lookup_qualified_type_through_translation_units(qualified_name,
							     corp);

  return result;
}

/// Look into a given corpus to find a pointer type which has the same
/// qualified name as a given pointer type.
///
/// @param t the pointer type which has the same qualified name as the
/// type we are looking for.
///
/// @param corp the corpus to look into.
///
/// @return the pointer type found.
pointer_type_def_sptr
lookup_pointer_type(const pointer_type_def& t, const corpus& corp)
{
  interned_string s = get_type_name(t);
  return lookup_pointer_type(s, corp);
}

/// Look into a given corpus to find a pointer type which has a given
/// qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the pointer type to
/// look for.
///
/// @param corp the corpus to look into.
///
/// @return the pointer type found.
pointer_type_def_sptr
lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m = corp.get_types().pointer_types();

  pointer_type_def_sptr result =
    lookup_type_in_map<pointer_type_def>(qualified_name, m);
  if (!result)
    result = lookup_pointer_type_through_translation_units(qualified_name,
							   corp);

  return result;
}

/// Look into a given corpus to find a reference type which has the
/// same qualified name as a given reference type.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param t the reference type which has the same qualified name as
/// the reference type we are looking for.
///
/// @param corp the corpus to look into.
///
/// @return the reference type found.
reference_type_def_sptr
lookup_reference_type(const reference_type_def& t, const corpus& corp)
{
  interned_string s = get_type_name(t);
  return lookup_reference_type(s, corp);
}

/// Look into a given corpus to find a reference type which has a
/// given qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the reference type to
/// look for.
///
/// @param corp the corpus to look into.
///
/// @return the reference type found.
reference_type_def_sptr
lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m =
    corp.get_types().reference_types();

  reference_type_def_sptr result =
    lookup_type_in_map<reference_type_def>(qualified_name, m);
  if (!result)
    result = lookup_reference_type_through_translation_units(qualified_name,
							     corp);

  return result;
}

/// Look into a given corpus to find an array type which has a given
/// qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the array type to look
/// for.
///
/// @param corp the corpus to look into.
///
/// @return the array type found.
array_type_def_sptr
lookup_array_type(const array_type_def& t, const corpus& corp)
{
  interned_string s = get_type_name(t);
  return lookup_array_type(s, corp);
}

/// Look into a given corpus to find an array type which has the same
/// qualified name as a given array type.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param t the type which has the same qualified name as the type we
/// are looking for.
///
/// @param corp the corpus to look into.
///
/// @return the type found.
array_type_def_sptr
lookup_array_type(const interned_string& qualified_name, const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m = corp.get_types().array_types();

  array_type_def_sptr result =
    lookup_type_in_map<array_type_def>(qualified_name, m);
  if (!result)
    result = lookup_array_type_through_translation_units(qualified_name, corp);

  return result;
}

/// Look into a given corpus to find a function type which has the same
/// qualified name as a given function type.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param t the function type which has the same qualified name as
/// the function type we are looking for.
///
/// @param corp the corpus to look into.
///
/// @return the function type found.
function_type_sptr
lookup_function_type(const function_type&t, const corpus& corp)
{
  interned_string type_name = get_type_name(t);
  return lookup_function_type(type_name, corp);
}

/// Look into a given corpus to find a function type which has the same
/// qualified name as a given function type.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param t the function type which has the same qualified name as
/// the function type we are looking for.
///
/// @param corp the corpus to look into.
///
/// @return the function type found.
function_type_sptr
lookup_function_type(const function_type_sptr& fn_t,
		     const corpus& corpus)
{
  if (fn_t)
    return lookup_function_type(*fn_t, corpus);
  return function_type_sptr();
}

/// Look into a given corpus to find a function type which has a given
/// qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the function type to
/// look for.
///
/// @param corp the corpus to look into.
///
/// @return the function type found.
function_type_sptr
lookup_function_type(const interned_string& qualified_name, const corpus& corp)
{
  const istring_type_base_wptrs_map_type& m = corp.get_types().function_types();

  function_type_sptr result =
    lookup_type_in_map<function_type>(qualified_name, m);
  if (!result)
    result = lookup_function_type_through_translation_units(qualified_name,
							    corp);

  return result;
}

/// Look into a given corpus to find a type which has a given
/// qualified name.
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the function type to
/// look for.
///
/// @param corp the corpus to look into.
///
/// @return the function type found.
type_base_sptr
lookup_type(const interned_string& n, const corpus& corp)
{
  type_base_sptr result;

  ((result = lookup_basic_type(n, corp))
   || (result = lookup_class_type(n, corp))
   || (result = lookup_union_type(n, corp))
   || (result = lookup_enum_type(n, corp))
   || (result = lookup_typedef_type(n, corp))
   || (result = lookup_qualified_type(n, corp))
   || (result = lookup_pointer_type(n, corp))
   || (result = lookup_reference_type(n, corp))
   || (result = lookup_array_type(n, corp))
   || (result= lookup_function_type(n, corp)));

  return result;
}

/// Lookup a type from a corpus, by its location.
///
/// @param loc the location to consider.
///
/// @param corp the corpus to look the type from.
///
/// @return the resulting type, if any found.
type_base_sptr
lookup_type_per_location(const interned_string& loc, const corpus& corp)
{
  // TODO: finish this.

  //TODO: when we fully support types indexed by their location, this
  //function should return a vector of types because at each location,
  //there can be several types that are defined (yay, C and C++,
  //*sigh*).

  type_base_sptr result;
  ((result = lookup_basic_type_per_location(loc, corp))
   || (result = lookup_class_type_per_location(loc, corp))
   || (result = lookup_union_type_per_location(loc, corp))
   || (result = lookup_enum_type_per_location(loc, corp))
   || (result = lookup_typedef_type_per_location(loc, corp)));

  return result;
}

/// Look into a given corpus to find a type
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the function type to
/// look for.
///
/// @param corp the corpus to look into.
///
/// @return the function type found.
type_base_sptr
lookup_type(const type_base&t, const corpus& corp)
{
  interned_string n = get_type_name(t);
  return lookup_type(n, corp);
}

/// Look into a given corpus to find a type
///
/// If the per-corpus type map is non-empty (because the corpus allows
/// the One Definition Rule) then the type islooked up in that
/// per-corpus type map.  Otherwise, the type is looked-up in each
/// translation unit.
///
/// @param qualified_name the qualified name of the function type to
/// look for.
///
/// @param corp the corpus to look into.
///
/// @return the function type found.
type_base_sptr
lookup_type(const type_base_sptr&t, const corpus& corp)
{
  if (t)
    return lookup_type(*t, corp);
  return type_base_sptr();
}

/// Update the map that associates a fully qualified name of a given
/// type to that type.
///
///
/// @param type the type we are considering.
///
/// @param types_map the map to update.  It's a map that assciates a
/// fully qualified name of a type to the type itself.
///
/// @param use_type_name_as_key if true, use the name of the type as
/// the key to look it up later.  If false, then use the location of
/// the type as a key to look it up later.
///
/// @return true iff the type was added to the map.
template<typename TypeKind>
bool
maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
			      istring_type_base_wptrs_map_type& types_map,
			      bool use_type_name_as_key = true)
{
  interned_string s;

  if (use_type_name_as_key)
    s = get_type_name(type);
  else if (location l = type->get_location())
    {
      string str = l.expand();
      s = type->get_environment()->intern(str);
    }

  istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
  bool result = false;

  if (i == types_map.end())
    {
      types_map[s].push_back(type);
      result = true;
    }
  else
    i->second.push_back(type);

  return result;
}

/// This is the specialization for type @ref class_decl of the
/// function template:
///
///    maybe_update_types_lookup_map<T>(scope_decl*,
///					const shared_ptr<T>&,
///					istring_type_base_wptrs_map_type&)
///
/// @param class_type the type to consider.
///
/// @param types_map the type map to update.
///
/// @return true iff the type was added to the map.
template<>
bool
maybe_update_types_lookup_map<class_decl>(const class_decl_sptr& class_type,
					  istring_type_base_wptrs_map_type& map,
					  bool use_type_name_as_key)
{
  class_decl_sptr type = class_type;

  bool update_qname_map = true;
  if (type->get_is_declaration_only())
    {
      if (class_decl_sptr def =
	  is_class_type(class_type->get_definition_of_declaration()))
	type = def;
      else
	update_qname_map = false;
    }

  if (!update_qname_map)
    return false;

  interned_string s;
  if (use_type_name_as_key)
    {
      string qname = type->get_qualified_name();
      s = type->get_environment()->intern(qname);
    }
  else if (location l = type->get_location())
    {
      string str = l.expand();
      s = type->get_environment()->intern(str);
    }

  bool result = false;
  istring_type_base_wptrs_map_type::iterator i = map.find(s);
  if (i == map.end())
    {
      map[s].push_back(type);
      result = true;
    }
  else
    i->second.push_back(type);

  return result;
}

/// This is the specialization for type @ref function_type of the
/// function template:
///
///    maybe_update_types_lookup_map<T>(scope_decl*,
///					const shared_ptr<T>&,
///					istring_type_base_wptrs_map_type&)
///
/// @param scope the scope of the type to consider.
///
/// @param class_type the type to consider.
///
/// @param types_map the type map to update.
///
/// @return true iff the type was added to the map.
template<>
bool
maybe_update_types_lookup_map<function_type>
(const function_type_sptr& type,
 istring_type_base_wptrs_map_type& types_map,
 bool /*use_type_name_as_key*/)
{
  bool result = false;
  interned_string s = get_type_name(type);
  istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
  if (i == types_map.end())
    {
      types_map[s].push_back(type);
      result = true;
    }
  else
    i->second.push_back(type);

  return result;
}

/// Update the map that associates the fully qualified name of a basic
/// type with the type itself.
///
/// The per-translation unit type map is updated if no type with this
/// name was already existing in that map.
///
/// If no type with this name did already exist in the per-corpus type
/// map, then that per-corpus type map is updated. Otherwise, that
/// type is erased from that per-corpus map.
///
/// @param basic_type the basic type to consider.
void
maybe_update_types_lookup_map(const type_decl_sptr& basic_type)
{
  if (translation_unit *tu = basic_type->get_translation_unit())
    maybe_update_types_lookup_map<type_decl>
      (basic_type, tu->get_types().basic_types());

  if (corpus *type_corpus = basic_type->get_corpus())
    {
      maybe_update_types_lookup_map<type_decl>
	(basic_type,
	 type_corpus->priv_->get_types().basic_types());

      maybe_update_types_lookup_map<type_decl>
	(basic_type,
	 type_corpus->get_type_per_loc_map().basic_types(),
	 /*use_type_name_as_key*/false);

      if (corpus *group = type_corpus->get_group())
	{
	  maybe_update_types_lookup_map<type_decl>
	    (basic_type,
	     group->priv_->get_types().basic_types());

	  maybe_update_types_lookup_map<type_decl>
	    (basic_type,
	     group->get_type_per_loc_map().basic_types(),
	     /*use_type_name_as_key*/false);
	}
    }

}

/// Update the map that associates the fully qualified name of a class
/// type with the type itself.
///
/// The per-translation unit type map is updated if no type with this
/// name was already existing in that map.
///
/// If no type with this name did already exist in the per-corpus type
/// map, then that per-corpus type map is updated. Otherwise, that
/// type is erased from that per-corpus map.
///
/// @param class_type the class type to consider.
void
maybe_update_types_lookup_map(const class_decl_sptr& class_type)
{
  if (translation_unit *tu = class_type->get_translation_unit())
    maybe_update_types_lookup_map<class_decl>
      (class_type, tu->get_types().class_types());

  if (corpus *type_corpus = class_type->get_corpus())
    {
      maybe_update_types_lookup_map<class_decl>
	(class_type,
	 type_corpus->priv_->get_types().class_types());

      maybe_update_types_lookup_map<class_decl>
	(class_type,
	 type_corpus->get_type_per_loc_map().class_types(),
	 /*use_type_name_as_key*/false);

      if (corpus *group = type_corpus->get_group())
	{
	  maybe_update_types_lookup_map<class_decl>
	    (class_type,
	     group->priv_->get_types().class_types());

	  maybe_update_types_lookup_map<class_decl>
	    (class_type,
	     group->get_type_per_loc_map().class_types(),
	     /*use_type_name_as_key*/false);
	}
    }
}

/// Update the map that associates the fully qualified name of a union
/// type with the type itself.
///
/// The per-translation unit type map is updated if no type with this
/// name was already existing in that map.
///
/// If no type with this name did already exist in the per-corpus type
/// map, then that per-corpus type map is updated. Otherwise, that
/// type is erased from that per-corpus map.
///
/// @param union_type the union type to consider.
void
maybe_update_types_lookup_map(const union_decl_sptr& union_type)
{
  if (translation_unit *tu = union_type->get_translation_unit())
    maybe_update_types_lookup_map<union_decl>
      (union_type, tu->get_types().union_types());

  if (corpus *type_corpus = union_type->get_corpus())
    {
      maybe_update_types_lookup_map<union_decl>
	(union_type,
	 type_corpus->priv_->get_types().union_types());

      maybe_update_types_lookup_map<union_decl>
	(union_type,
	 type_corpus->get_type_per_loc_map().union_types(),
	 /*use_type_name_as_key*/false);

      if (corpus *group = type_corpus->get_group())
	{
	  maybe_update_types_lookup_map<union_decl>
	    (union_type,
	     group->priv_->get_types().union_types());

	  maybe_update_types_lookup_map<union_decl>
	    (union_type,
	     group->get_type_per_loc_map().union_types(),
	     /*use_type_name_as_key*/false);
	}
    }
}

/// Update the map that associates the fully qualified name of an enum
/// type with the type itself.
///
/// The per-translation unit type map is updated if no type with this
/// name was already existing in that map.
///
/// If no type with this name did already exist in the per-corpus type
/// map, then that per-corpus type map is updated. Otherwise, that
/// type is erased from that per-corpus map.
///
/// @param enum_type the type to consider.
void
maybe_update_types_lookup_map(const enum_type_decl_sptr& enum_type)
{
  if (translation_unit *tu = enum_type->get_translation_unit())
    maybe_update_types_lookup_map<enum_type_decl>
      (enum_type, tu->get_types().enum_types());

  if (corpus *type_corpus = enum_type->get_corpus())
    {
      maybe_update_types_lookup_map<enum_type_decl>
	(enum_type,
	 type_corpus->priv_->get_types().enum_types());

      maybe_update_types_lookup_map<enum_type_decl>
	(enum_type,
	 type_corpus->get_type_per_loc_map().enum_types(),
	 /*use_type_name_as_key*/false);

      if (corpus *group = type_corpus->get_group())
	{
	  maybe_update_types_lookup_map<enum_type_decl>
	    (enum_type,
	     group->priv_->get_types().enum_types());

	  maybe_update_types_lookup_map<enum_type_decl>
	    (enum_type,
	     group->get_type_per_loc_map().enum_types(),
	     /*use_type_name_as_key*/false);
	}
    }

}

/// Update the map that associates the fully qualified name of a
/// typedef type with the type itself.
///
/// The per-translation unit type map is updated if no type with this
/// name was already existing in that map.
///
/// If no type with this name did already exist in the per-corpus type
/// map, then that per-corpus type map is updated. Otherwise, that
/// type is erased from that per-corpus map.
///
/// @param typedef_type the type to consider.
void
maybe_update_types_lookup_map(const typedef_decl_sptr& typedef_type)
{
  if (translation_unit *tu = typedef_type->get_translation_unit())
    maybe_update_types_lookup_map<typedef_decl>
      (typedef_type, tu->get_types().typedef_types());

  if (corpus *type_corpus = typedef_type->get_corpus())
    {
      maybe_update_types_lookup_map<typedef_decl>
	(typedef_type,
	 type_corpus->priv_->get_types().typedef_types());

      maybe_update_types_lookup_map<typedef_decl>
	(typedef_type,
	 type_corpus->get_type_per_loc_map().typedef_types(),
	 /*use_type_name_as_key*/false);

      if (corpus *group = type_corpus->get_group())
	{
	  maybe_update_types_lookup_map<typedef_decl>
	    (typedef_type,
	     group->priv_->get_types().typedef_types());

	  maybe_update_types_lookup_map<typedef_decl>
	    (typedef_type,
	     group->get_type_per_loc_map().typedef_types(),
	     /*use_type_name_as_key*/false);
	}
    }
}

/// Update the map that associates the fully qualified name of a
/// qualified type with the type itself.
///
/// The per-translation unit type map is updated if no type with this
/// name was already existing in that map.
///
/// If no type with this name did already exist in the per-corpus type
/// map, then that per-corpus type map is updated. Otherwise, that
/// type is erased from that per-corpus map.
///
/// @param qualified_type the type to consider.
void
maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
{
  if (translation_unit *tu = qualified_type->get_translation_unit())
    maybe_update_types_lookup_map<qualified_type_def>
      (qualified_type, tu->get_types().qualified_types());

  if (corpus *type_corpus = qualified_type->get_corpus())
    {
      maybe_update_types_lookup_map<qualified_type_def>
	(qualified_type,
	 type_corpus->priv_->get_types().qualified_types());

      if (corpus *group = type_corpus->get_group())
	{
	  maybe_update_types_lookup_map<qualified_type_def>
	    (qualified_type,
	     group->priv_->get_types().qualified_types());
	}
    }
}

/// Update the map that associates the fully qualified name of a
/// pointer type with the type itself.
///
/// The per-translation unit type map is updated if no type with this
/// name was already existing in that map.
///
/// If no type with this name did already exist in the per-corpus type
/// map, then that per-corpus type map is updated. Otherwise, that
/// type is erased from that per-corpus map.
///
/// @param pointer_type the type to consider.
void
maybe_update_types_lookup_map(const pointer_type_def_sptr& pointer_type)
{
  if (translation_unit *tu = pointer_type->get_translation_unit())
    maybe_update_types_lookup_map<pointer_type_def>
      (pointer_type, tu->get_types().pointer_types());

  if (corpus *type_corpus = pointer_type->get_corpus())
    {
      maybe_update_types_lookup_map<pointer_type_def>
	(pointer_type,
	 type_corpus->priv_->get_types().pointer_types());

      if (corpus *group = type_corpus->get_group())
	{
	  maybe_update_types_lookup_map<pointer_type_def>
	    (pointer_type,
	     group->priv_->get_types().pointer_types());
	}
    }
}

/// Update the map that associates the fully qualified name of a
/// reference type with the type itself.
///
/// The per-translation unit type map is updated if no type with this
/// name was already existing in that map.
///
/// If no type with this name did already exist in the per-corpus type
/// map, then that per-corpus type map is updated. Otherwise, that
/// type is erased from that per-corpus map.
///
/// @param reference_type the type to consider.
void
maybe_update_types_lookup_map(const reference_type_def_sptr& reference_type)
{
  if (translation_unit *tu = reference_type->get_translation_unit())
    maybe_update_types_lookup_map<reference_type_def>
      (reference_type, tu->get_types().reference_types());

  if (corpus *type_corpus = reference_type->get_corpus())
    {
      maybe_update_types_lookup_map<reference_type_def>
	(reference_type,
	 type_corpus->priv_->get_types().reference_types());

      if (corpus *group = type_corpus->get_group())
	{
	  maybe_update_types_lookup_map<reference_type_def>
	    (reference_type,
	     group->priv_->get_types().reference_types());
	}
    }
}

/// Update the map that associates the fully qualified name of a type
/// with the type itself.
///
/// The per-translation unit type map is updated if no type with this
/// name was already existing in that map.
///
/// If no type with this name did already exist in the per-corpus type
/// map, then that per-corpus type map is updated. Otherwise, that
/// type is erased from that per-corpus map.
///
/// @param array_type the type to consider.
void
maybe_update_types_lookup_map(const array_type_def_sptr& array_type)
{
  if (translation_unit *tu = array_type->get_translation_unit())
    maybe_update_types_lookup_map<array_type_def>
      (array_type, tu->get_types().array_types());

  if (corpus *type_corpus = array_type->get_corpus())
    {
      maybe_update_types_lookup_map<array_type_def>
	(array_type,
	 type_corpus->priv_->get_types().array_types());

      maybe_update_types_lookup_map<array_type_def>
	(array_type,
	 type_corpus->get_type_per_loc_map().array_types(),
	 /*use_type_name_as_key*/false);

      if (corpus *group = type_corpus->get_group())
	{
	  maybe_update_types_lookup_map<array_type_def>
	    (array_type,
	     group->priv_->get_types().array_types());

	  maybe_update_types_lookup_map<array_type_def>
	    (array_type,
	     group->get_type_per_loc_map().array_types(),
	     /*use_type_name_as_key*/false);
	}
    }
}

/// Update the map that associates the fully qualified name of a type
/// with the type itself.
///
/// The per-translation unit type map is updated if no type with this
/// name was already existing in that map.
///
/// If no type with this name did already exist in the per-corpus type
/// map, then that per-corpus type map is updated. Otherwise, that
/// type is erased from that per-corpus map.
///
/// @param subrange_type the type to consider.
void
maybe_update_types_lookup_map
(const array_type_def::subrange_sptr& subrange_type)
{
  if (translation_unit *tu = subrange_type->get_translation_unit())
    maybe_update_types_lookup_map<array_type_def::subrange_type>
      (subrange_type, tu->get_types().subrange_types());

  if (corpus *type_corpus = subrange_type->get_corpus())
    {
      maybe_update_types_lookup_map<array_type_def::subrange_type>
	(subrange_type,
	 type_corpus->priv_->get_types().subrange_types());

      maybe_update_types_lookup_map<array_type_def::subrange_type>
	(subrange_type,
	 type_corpus->get_type_per_loc_map().subrange_types(),
	 /*use_type_name_as_key*/false);

      if (corpus *group = subrange_type->get_corpus())
	{
	  maybe_update_types_lookup_map<array_type_def::subrange_type>
	    (subrange_type,
	     group->priv_->get_types().subrange_types());

	  maybe_update_types_lookup_map<array_type_def::subrange_type>
	    (subrange_type,
	     group->get_type_per_loc_map().subrange_types(),
	     /*use_type_name_as_key*/false);
	}
    }
}

/// Update the map that associates the fully qualified name of a
/// function type with the type itself.
///
/// The per-translation unit type map is updated if no type with this
/// name was already existing in that map.
///
/// If no type with this name did already exist in the per-corpus type
/// map, then that per-corpus type map is updated. Otherwise, that
/// type is erased from that per-corpus map.
///
/// @param scope the scope of the function type.
/// @param fn_type the type to consider.
void
maybe_update_types_lookup_map(const function_type_sptr& fn_type)
{
  if (translation_unit *tu = fn_type->get_translation_unit())
    maybe_update_types_lookup_map<function_type>
      (fn_type, tu->get_types().function_types());

  if (corpus *type_corpus = fn_type->get_corpus())
    {
      maybe_update_types_lookup_map<function_type>
	(fn_type,
	 type_corpus->priv_->get_types().function_types());

      if (corpus *group = fn_type->get_corpus())
	{
	  maybe_update_types_lookup_map<function_type>
	    (fn_type,
	     group->priv_->get_types().function_types());
	}
    }
}

/// Update the map that associates the fully qualified name of a type
/// declaration with the type itself.
///
/// The per-translation unit type map is updated if no type with this
/// name was already existing in that map.
///
/// If no type with this name did already exist in the per-corpus type
/// map, then that per-corpus type map is updated. Otherwise, that
/// type is erased from that per-corpus map.
///
/// @param decl the declaration of the type to consider.
void
maybe_update_types_lookup_map(const decl_base_sptr& decl)
{
  if (!is_type(decl))
    return;

  if (type_decl_sptr basic_type = is_type_decl(decl))
    maybe_update_types_lookup_map(basic_type);
  else if (class_decl_sptr class_type = is_class_type(decl))
    maybe_update_types_lookup_map(class_type);
  else if (union_decl_sptr union_type = is_union_type(decl))
    maybe_update_types_lookup_map(union_type);
  else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
    maybe_update_types_lookup_map(enum_type);
  else if (typedef_decl_sptr typedef_type = is_typedef(decl))
    maybe_update_types_lookup_map(typedef_type);
  else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
    maybe_update_types_lookup_map(qualified_type);
  else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
    maybe_update_types_lookup_map(pointer_type);
  else if (reference_type_def_sptr reference_type = is_reference_type(decl))
    maybe_update_types_lookup_map(reference_type);
  else if (array_type_def_sptr array_type = is_array_type(decl))
    maybe_update_types_lookup_map(array_type);
  else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
    maybe_update_types_lookup_map(subrange_type);
  else
    ABG_ASSERT_NOT_REACHED;
}

/// Update the map that associates the fully qualified name of a type
/// with the type itself.
///
/// The per-translation unit type map is updated if no type with this
/// name was already existing in that map.
///
/// If no type with this name did already exist in the per-corpus type
/// map, then that per-corpus type map is updated. Otherwise, that
/// type is erased from that per-corpus map.
///
/// @param type the type to consider.
void
maybe_update_types_lookup_map(const type_base_sptr& type)
{
  if (decl_base_sptr decl = get_type_declaration(type))
    maybe_update_types_lookup_map(decl);
  else
    ABG_ASSERT_NOT_REACHED;
}

//--------------------------------
// </type and decls lookup stuff>
// ------------------------------

/// In a translation unit, lookup a given type or synthesize it if
/// it's a qualified type.
///
/// So this function first looks the type up in the translation unit.
/// If it's found, then OK, it's returned.  Otherwise, if it's a
/// qualified, reference or pointer or function type (a composite
/// type), lookup the underlying type, synthesize the type we want
/// from it and return it.
///
/// If the underlying types is not not found, then give up and return
/// nil.
///
/// @return the type that was found or the synthesized type.
type_base_sptr
synthesize_type_from_translation_unit(const type_base_sptr& type,
				      translation_unit& tu)
{
  type_base_sptr result;

   result = lookup_type(type, tu);

  if (!result)
    {
      if (qualified_type_def_sptr qual = is_qualified_type(type))
	{
	  type_base_sptr underlying_type =
	    synthesize_type_from_translation_unit(qual->get_underlying_type(),
						  tu);
	  if (underlying_type)
	    {
	      result.reset(new qualified_type_def(underlying_type,
						  qual->get_cv_quals(),
						  qual->get_location()));
	    }
	}
      else if (pointer_type_def_sptr p = is_pointer_type(type))
	{
	  type_base_sptr pointed_to_type =
	    synthesize_type_from_translation_unit(p->get_pointed_to_type(),
						  tu);
	  if (pointed_to_type)
	    {
	      result.reset(new pointer_type_def(pointed_to_type,
						p->get_size_in_bits(),
						p->get_alignment_in_bits(),
						p->get_location()));
	      result->set_environment(pointed_to_type->get_environment());
	    }
	}
      else if (reference_type_def_sptr r = is_reference_type(type))
	{
	  type_base_sptr pointed_to_type =
	    synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
	  if (pointed_to_type)
	    {
	      result.reset(new reference_type_def(pointed_to_type,
						  r->is_lvalue(),
						  r->get_size_in_bits(),
						  r->get_alignment_in_bits(),
						  r->get_location()));
	      result->set_environment(pointed_to_type->get_environment());
	    }
	}
      else if (function_type_sptr f = is_function_type(type))
	result = synthesize_function_type_from_translation_unit(*f, tu);

      if (result)
	{
	  add_decl_to_scope(is_decl(result), tu.get_global_scope());
	  canonicalize(result);
	}
    }

  if (result)
    tu.priv_->synthesized_types_.push_back(result);

  return result;
}

/// In a translation unit, lookup the sub-types that make up a given
/// function type and if the sub-types are all found, synthesize and
/// return a function_type with them.
///
/// This function is like lookup_function_type_in_translation_unit()
/// execept that it constructs the function type from the sub-types
/// found in the translation, rather than just looking for the
/// function types held by the translation unit.  This can be useful
/// if the translation unit doesnt hold the function type we are
/// looking for (i.e, lookup_function_type_in_translation_unit()
/// returned NULL) but we still want to see if the sub-types of the
/// function types are present in the translation unit.
///
/// @param fn_type the function type to consider.
///
/// @param tu the translation unit to look into.
///
/// @return the resulting synthesized function type if all its
/// sub-types have been found, NULL otherwise.
function_type_sptr
synthesize_function_type_from_translation_unit(const function_type& fn_type,
					       translation_unit& tu)
{
  function_type_sptr nil = function_type_sptr();

  environment* env = tu.get_environment();
  ABG_ASSERT(env);

  type_base_sptr return_type = fn_type.get_return_type();
  type_base_sptr result_return_type;
  if (!return_type || env->is_void_type(return_type))
    result_return_type = env->get_void_type();
  else
    result_return_type = synthesize_type_from_translation_unit(return_type, tu);
  if (!result_return_type)
    return nil;

  function_type::parameters parms;
  type_base_sptr parm_type;
  function_decl::parameter_sptr parm;
  for (function_type::parameters::const_iterator i =
	 fn_type.get_parameters().begin();
       i != fn_type.get_parameters().end();
       ++i)
    {
      type_base_sptr t = (*i)->get_type();
      parm_type = synthesize_type_from_translation_unit(t, tu);
      if (!parm_type)
	return nil;
      parm.reset(new function_decl::parameter(parm_type,
					      (*i)->get_index(),
					      (*i)->get_name(),
					      (*i)->get_location(),
					      (*i)->get_variadic_marker(),
					      (*i)->get_is_artificial()));
      parms.push_back(parm);
    }

  class_or_union_sptr class_type;
  const method_type* method = is_method_type(&fn_type);
  if (method)
    {
      class_type = is_class_or_union_type
	(synthesize_type_from_translation_unit(method->get_class_type(), tu));
      ABG_ASSERT(class_type);
    }

  function_type_sptr result_fn_type;

  if (class_type)
    result_fn_type.reset(new method_type(result_return_type,
					 class_type,
					 parms,
					 method->get_is_const(),
					 fn_type.get_size_in_bits(),
					 fn_type.get_alignment_in_bits()));
  else
    result_fn_type.reset(new function_type(result_return_type,
					   parms,
					   fn_type.get_size_in_bits(),
					   fn_type.get_alignment_in_bits()));

  tu.priv_->synthesized_types_.push_back(result_fn_type);
  // The new synthesized type must be in the same environment as its
  // translation unit.
  result_fn_type->set_environment(tu.get_environment());
  tu.bind_function_type_life_time(result_fn_type);

  canonicalize(result_fn_type);
  return result_fn_type;
}

/// Demangle a C++ mangled name and return the resulting string
///
/// @param mangled_name the C++ mangled name to demangle.
///
/// @return the resulting mangled name.
string
demangle_cplus_mangled_name(const string& mangled_name)
{
  if (mangled_name.empty())
    return "";

  size_t l = 0;
  int status = 0;
  char * str = abi::__cxa_demangle(mangled_name.c_str(),
				   NULL, &l, &status);
  string demangled_name = mangled_name;
  if (str)
    {
      ABG_ASSERT(status == 0);
      demangled_name = str;
      free(str);
      str = 0;
    }
  return demangled_name;
}

/// Return either the type given in parameter if it's non-null, or the
/// void type.
///
/// @param t the type to consider.
///
/// @param env the environment to use.  If NULL, just abort the
/// process.
///
/// @return either @p t if it is non-null, or the void type.
type_base_sptr
type_or_void(const type_base_sptr t, const environment* env)
{
  type_base_sptr r;

  if (t)
    r = t;
  else
    {
      ABG_ASSERT(env);
      r = type_base_sptr(env->get_void_type());
    }

  return r;
}

global_scope::~global_scope()
{
}

static bool
maybe_propagate_canonical_type(const type_base& lhs_type,
			       const type_base& rhs_type);

/// Test if two types are eligible to the "Linux Kernel Fast Type
/// Comparison Optimization", a.k.a LKFTCO.
///
/// Two types T1 and T2 (who are presumably of the same name and kind)
/// are eligible to the LKFTCO if they fulfill the following criteria/
///
/// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
/// either class, union or enums.
///
/// 2/ They are defined in the same translation unit.
///
/// @param t1 the first type to consider.
///
/// @param t2 the second type to consider.
///
/// @return true iff t1 and t2 are eligible to the LKFTCO.
static bool
types_defined_same_linux_kernel_corpus_public(const type_base& t1,
					      const type_base& t2)
{
  const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
  string t1_file_path, t2_file_path;

  /// If the t1 (and t2) are classes/unions/enums from the same linux
  /// kernel corpus, let's move on.  Otherwise bail out.
  if (!(t1_corpus && t2_corpus
	&& t1_corpus == t2_corpus
	&& (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
	&& (is_class_or_union_type(&t1)
	    || is_enum_type(&t1))))
    return false;

  class_or_union *c1 = 0, *c2 = 0;
  c1 = is_class_or_union_type(&t1);
  c2 = is_class_or_union_type(&t2);

  // Two anonymous class types with no naming typedefs cannot be
  // eligible to this optimization.
  if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
      || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
    return false;

  // Two anonymous classes with naming typedefs should have the same
  // typedef name.
  if (c1
      && c2
      && c1->get_is_anonymous() && c1->get_naming_typedef()
      && c2->get_is_anonymous() && c2->get_naming_typedef())
    if (c1->get_naming_typedef()->get_name()
	!= c2->get_naming_typedef()->get_name())
      return false;

  // Two anonymous enum types cannot be eligible to this optimization.
  if (const enum_type_decl *e1 = is_enum_type(&t1))
    if (const enum_type_decl *e2 = is_enum_type(&t2))
      if (e1->get_is_anonymous() || e2->get_is_anonymous())
	return false;

  // Look through declaration-only types.  That is, get the associated
  // definition type.
  c1 = look_through_decl_only_class(c1);
  c2 = look_through_decl_only_class(c2);

  if (c1 && c2)
    {
      if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
	{
	  if (c1->get_environment()->decl_only_class_equals_definition())
	    // At least one of classes/union is declaration-only.
	    // Because we are in a context in which a declaration-only
	    // class/union is equal to all definitions of that
	    // class/union, we can assume that the two types are
	    // equal.
	    return true;
	}
    }

  if (t1.get_size_in_bits() != t2.get_size_in_bits())
    return false;

  // Look at the file names of the locations of t1 and t2.  If they
  // are equal, then t1 and t2 are defined in the same file.
  {
    location l;

    if (c1)
      l = c1->get_location();
    else
      l = dynamic_cast<const decl_base&>(t1).get_location();

    unsigned line = 0, col = 0;
    if (l)
      l.expand(t1_file_path, line, col);
    if (c2)
      l = c2->get_location();
    else
      l = dynamic_cast<const decl_base&>(t2).get_location();
    if (l)
      l.expand(t2_file_path, line, col);
  }

  if (t1_file_path.empty() || t2_file_path.empty())
    return false;

  if (t1_file_path == t2_file_path)
    return true;

  return false;
}


/// Compare a type T against a canonical type.
///
/// This function is called during the canonicalization process of the
/// type T.  T is called the "candidate type" because it's in the
/// process of being canonicalized.  Meaning, it's going to be
/// compared to a canonical type C.  If T equals C, then the canonical
/// type of T is C.
///
/// The purpose of this function is to allow the debugging of the
/// canonicalization of T, if that debugging is activated by
/// configuring the libabigail package with
/// --enable-debug-type-canonicalization and by running "abidw
/// --debug-tc".  In that case, T is going to be compared to C twice:
/// once with canonical equality and once with structural equality.
/// The two comparisons must be equal.  Otherwise, the
/// canonicalization process is said to be faulty and this function
/// aborts.
///
/// This is a sub-routine of type_base::get_canonical_type_for.
///
/// @param canonical_type the canonical type to compare the candidate
/// type against.
///
/// @param candidate_type the candidate type to compare against the
/// canonical type.
///
/// @return true iff @p canonical_type equals @p candidate_type.
///
static bool
compare_types_during_canonicalization(const type_base_sptr& canonical_type,
				      const type_base_sptr& candidate_type)
{
#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
  environment *env = canonical_type->get_environment();
  if (env->debug_type_canonicalization_is_on())
    {
      bool canonical_equality = false, structural_equality = false;
      env->priv_->use_canonical_type_comparison_ = true;
      canonical_equality = canonical_type == candidate_type;
      env->priv_->use_canonical_type_comparison_ = false;
      structural_equality = canonical_type == candidate_type;
      if (canonical_equality != structural_equality)
	{
	  std::cerr << "structural & canonical equality different for type: "
		    << canonical_type->get_pretty_representation(true, true)
		    << std::endl;
	  ABG_ASSERT_NOT_REACHED;
	}
      return structural_equality;
    }
#endif //end WITH_DEBUG_TYPE_CANONICALIZATION
  return canonical_type == candidate_type;
}

/// Compute the canonical type for a given instance of @ref type_base.
///
/// Consider two types T and T'.  The canonical type of T, denoted
/// C(T) is a type such as T == T' if and only if C(T) == C(T').  Said
/// otherwise, to compare two types, one just needs to compare their
/// canonical types using pointer equality.  That makes type
/// comparison faster than the structural comparison performed by the
/// abigail::ir::equals() overloads.
///
/// If there is not yet any canonical type for @p t, then @p t is its
/// own canonical type.  Otherwise, this function returns the
/// canonical type of @p t which is the canonical type that has the
/// same hash value as @p t and that structurally equals @p t.  Note
/// that after invoking this function, the life time of the returned
/// canonical time is then equals to the life time of the current
/// process.
///
/// @param t a smart pointer to instance of @ref type_base we want to
/// compute a canonical type for.
///
/// @return the canonical type for the current instance of @ref
/// type_base.
type_base_sptr
type_base::get_canonical_type_for(type_base_sptr t)
{
  if (!t)
    return t;

  environment* env = t->get_environment();
  ABG_ASSERT(env);

  if (is_non_canonicalized_type(t))
    // This type should not be canonicalized!
    return type_base_sptr();

  bool decl_only_class_equals_definition =
    (odr_is_relevant(*t) || env->decl_only_class_equals_definition());

  class_or_union_sptr class_or_union = is_class_or_union_type(t);

  // Look through declaration-only classes when we are dealing with
  // C++ or languages where we assume the "One Definition Rule".  In
  // that context, we assume that a declaration-only non-anonymous
  // class equals all fully defined classes of the same name.
  //
  // Otherwise, all classes, including declaration-only classes are
  // canonicalized and only canonical comparison is going to be used
  // in the system.
  if (decl_only_class_equals_definition)
    if (class_or_union)
      {
	class_or_union = look_through_decl_only_class(class_or_union);
	if (class_or_union->get_is_declaration_only())
	  return type_base_sptr();
	else
	  t = class_or_union;
      }

  class_decl_sptr is_class = is_class_type(t);
  if (t->get_canonical_type())
    return t->get_canonical_type();

  // For classes and union, ensure that an anonymous class doesn't
  // have a linkage name.  If it does in the future, then me must be
  // mindful that the linkage name respects the type identity
  // constraints which states that "if two linkage names are different
  // then the two types are different".
  ABG_ASSERT(!class_or_union
	     || !class_or_union->get_is_anonymous()
	     || class_or_union->get_linkage_name().empty());

  // We want the pretty representation of the type, but for an
  // internal use, not for a user-facing purpose.
  //
  // If two classe types Foo are declared, one as a class and the
  // other as a struct, but are otherwise equivalent, we want their
  // pretty representation to be the same.  Hence the 'internal'
  // argument of ir::get_pretty_representation() is set to true here.
  // So in this case, the pretty representation of Foo is going to be
  // "class Foo", regardless of its struct-ness. This also applies to
  // composite types which would have "class Foo" as a sub-type.
  string repr = t->get_cached_pretty_representation(/*internal=*/true);

  // If 't' already has a canonical type 'inside' its corpus
  // (t_corpus), then this variable is going to contain that canonical
  // type.
  type_base_sptr canonical_type_present_in_corpus;
  environment::canonical_types_map_type& types =
    env->get_canonical_types_map();

  type_base_sptr result;
  environment::canonical_types_map_type::iterator i = types.find(repr);
  if (i == types.end())
    {
      vector<type_base_sptr> v;
      v.push_back(t);
      types[repr] = v;
      result = t;
    }
  else
    {
      vector<type_base_sptr> &v = i->second;
      // Let's compare 't' structurally (i.e, compare its sub-types
      // recursively) against the canonical types of the system. If it
      // equals a given canonical type C, then it means C is the
      // canonical type of 't'.  Otherwise, if 't' is different from
      // all the canonical types of the system, then it means 't' is a
      // canonical type itself.
      for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
	   it != v.rend();
	   ++it)
	{
	  // Before the "*it == it" comparison below is done, let's
	  // perform on-the-fly-canonicalization.  For C types, let's
	  // consider that an unresolved struct declaration 'struct S'
	  // is different from a definition 'struct S'.  This is
	  // because normally, at this point all the declarations of
	  // struct S that are compatible with the definition of
	  // struct S have already been resolved to that definition,
	  // during the DWARF parsing.  The remaining unresolved
	  // declaration are thus considered different.  With this
	  // setup we can properly handle cases of two *different*
	  // struct S being defined in the same binary (in different
	  // translation units), and a third struct S being only
	  // declared as an opaque type in a third translation unit of
	  // its own, with no definition in there.  In that case, the
	  // declaration-only struct S should be left alone and not
	  // resolved to any of the two definitions of struct S.
	  bool saved_decl_only_class_equals_definition =
	    env->decl_only_class_equals_definition();
	  env->do_on_the_fly_canonicalization(true);
	  // Compare types by considering that decl-only classes don't
	  // equal their definition.
	  env->decl_only_class_equals_definition(false);
	  bool equal = (types_defined_same_linux_kernel_corpus_public(**it, *t)
			|| compare_types_during_canonicalization(*it, t));
	  // Restore the state of the on-the-fly-canonicalization and
	  // the decl-only-class-being-equal-to-a-matching-definition
	  // flags.
	  env->do_on_the_fly_canonicalization(false);
	  env->decl_only_class_equals_definition
	    (saved_decl_only_class_equals_definition);
	  if (equal)
	    {
	      result = *it;
	      break;
	    }
	}
#ifdef WITH_DEBUG_SELF_COMPARISON
      if (env->self_comparison_debug_is_on())
	{
	  // So we are debugging the canonicalization process,
	  // possibly via the use of 'abidw --debug-abidiff <binary>'.
	  corpus_sptr corp1, corp2;
	  env->get_self_comparison_debug_inputs(corp1, corp2);
	  if (corp1 && corp2 && t->get_corpus() == corp2.get())
	    {
	      // If 't' comes from the second corpus, then it *must*
	      // be equal to its matching canonical type coming from
	      // the first corpus because the second corpus is the
	      // abixml representation of the first corpus.  In other
	      // words, all types coming from the second corpus must
	      // have canonical types coming from the first corpus.
	      if (result)
		{
		  if (!env->priv_->
		      check_canonical_type_from_abixml_during_self_comp(t,
									result))
		    // The canonical type of the type re-read from abixml
		    // type doesn't match the canonical type that was
		    // initially serialized down.
		    std::cerr << "error: wrong canonical type for '"
			      << repr
			      << "' / type: @"
			      << std::hex
			      << t.get()
			      << "/ canon: @"
			      << result.get()
			      << std::endl;
		}
	      else //!result
		{
		  uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
		  string type_id = env->get_type_id_from_pointer(ptr_val);
		  if (type_id.empty())
		    type_id = "type-id-<not-found>";
		  // We are in the case where 't' is different from all
		  // the canonical types of the same name that come from
		  // the first corpus.
		  //
		  // If 't' indeed comes from the second corpus then this
		  // clearly is a canonicalization failure.
		  //
		  // There was a problem either during the serialization
		  // of 't' into abixml, or during the de-serialization
		  // from abixml into abigail::ir.  Further debugging is
		  // needed to determine what that root cause problem is.
		  //
		  // Note that the first canonicalization problem of this
		  // kind must be fixed before looking at the subsequent
		  // ones, because the later might well just be
		  // consequences of the former.
		  std::cerr << "error: wrong induced canonical type for '"
			    << repr
			    << "' from second corpus"
			    << ", ptr: " << std::hex << t.get()
			    << "type-id: " << type_id
			    << std::endl;
		}
	    }
	}
#endif

      if (!result)
	{
	  v.push_back(t);
	  result = t;
	}
    }

  return result;
}

/// This method is invoked automatically right after the current
/// instance of @ref class_decl has been canonicalized.
void
type_base::on_canonical_type_set()
{}

/// This is a subroutine of the canonicalize() function.
///
/// When the canonical type C of type T has just been computed, there
/// can be cases where T has member functions that C doesn't have.
///
/// This is possible because non virtual member functions are not
/// taken in account when comparing two types.
///
/// In that case, this function updates C so that it contains the
/// member functions.
///
/// There can also be cases where C has a method M which is not linked
/// to any underlying symbol, whereas in T, M is to link to an
/// underlying symbol.  In that case, this function updates M in C so
/// that it's linked to the same underlying symbol as for M in T.
static void
maybe_adjust_canonical_type(const type_base_sptr& canonical,
			    const type_base_sptr& type)
{
  if (!canonical
      // If 'type' is *NOT* a newly canonicalized type ...
      || type->get_naked_canonical_type()
      // ... or if 'type' is it's own canonical type, then get out.
      || type.get() == canonical.get())
    return;

  if (class_decl_sptr cl = is_class_type(type))
    {
      class_decl_sptr canonical_class = is_class_type(canonical);

      if (canonical_class)
	{
	  // Set symbols of member functions that might be missing
	  // theirs.
	  for (class_decl::member_functions::const_iterator i =
		 cl->get_member_functions().begin();
	       i != cl->get_member_functions().end();
	       ++i)
	    if ((*i)->get_symbol())
	      {
		if (method_decl *m = canonical_class->
		    find_member_function((*i)->get_linkage_name()))
		  {
		    elf_symbol_sptr s1 = (*i)->get_symbol();
		    if (s1 && !m->get_symbol())
		      // Method 'm' in the canonical type is not
		      // linked to the underlying symbol of '*i'.
		      // Let's link it now.  have th
		      m->set_symbol(s1);
		  }
		else
		  // There is a member function defined and publicly
		  // exported in the other class, and the canonical
		  // class doesn't have that member function.  Let's
		  // copy that member function to the canonical class
		  // then.
		  copy_member_function (canonical_class, *i);
	      }
	}
    }

  // If an artificial function type equals a non-artfificial one in
  // the system, then the canonical type of both should be deemed
  // non-artificial.  This is important because only non-artificial
  // canonical function types are emitted out into abixml, so if don't
  // do this we risk missing to emit some function types.
  if (is_function_type(type))
    if (type->get_is_artificial() != canonical->get_is_artificial())
      canonical->set_is_artificial(false);
}

/// Compute the canonical type of a given type.
///
/// It means that after invoking this function, comparing the intance
/// instance @ref type_base and another one (on which
/// type_base::enable_canonical_equality() would have been invoked as
/// well) is performed by just comparing the pointer values of the
/// canonical types of both types.  That equality comparison is
/// supposedly faster than structural comparison of the types.
///
/// @param t a smart pointer to the instance of @ref type_base for
/// which to compute the canonical type.  After this call,
/// t->get_canonical_type() will return the newly computed canonical
/// type.
///
/// @return the canonical type computed for @p t.
type_base_sptr
canonicalize(type_base_sptr t)
{
  if (!t)
    return t;

  if (t->get_canonical_type())
    return t->get_canonical_type();

  type_base_sptr canonical = type_base::get_canonical_type_for(t);
  maybe_adjust_canonical_type(canonical, t);

  t->priv_->canonical_type = canonical;
  t->priv_->naked_canonical_type = canonical.get();

  if (class_decl_sptr cl = is_class_type(t))
    if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
      if ((canonical = d->get_canonical_type()))
	{
	  d->priv_->canonical_type = canonical;
	  d->priv_->naked_canonical_type = canonical.get();
	}

  if (canonical)
    if (decl_base_sptr d = is_decl_slow(canonical))
      {
	scope_decl *scope = d->get_scope();
	// Add the canonical type to the set of canonical types
	// belonging to its scope.
	if (scope)
	  {
	    if (is_type(scope))
	      // The scope in question is itself a type (e.g, a class
	      // or union).  Let's call that type ST.  We want to add
	      // 'canonical' to the set of canonical types belonging
	      // to ST.
	      if (type_base_sptr c = is_type(scope)->get_canonical_type())
		// We want to add 'canonical' to set of canonical
		// types belonging to the canonical type of ST.  That
		// way, just looking at the canonical type of ST is
		// enough to get the types that belong to the scope of
		// the class of equivalence of ST.
		scope = is_scope_decl(is_decl(c)).get();
	    scope->get_canonical_types().insert(canonical);
	  }
	// else, if the type doesn't have a scope, it's not meant to be
	// emitted.  This can be the case for the result of the
	// function strip_typedef, for instance.
      }

  t->on_canonical_type_set();
  return canonical;
}


/// Set the definition of this declaration-only @ref decl_base.
///
/// @param d the new definition to set.
void
decl_base::set_definition_of_declaration(const decl_base_sptr& d)
{
  ABG_ASSERT(get_is_declaration_only());
  priv_->definition_of_declaration_ = d;
  if (type_base *t = is_type(this))
    if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
      t->priv_->canonical_type = canonical_type;

  priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
}

/// The constructor of @ref type_base.
///
/// @param s the size of the type, in bits.
///
/// @param a the alignment of the type, in bits.
type_base::type_base(const environment* e, size_t s, size_t a)
  : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
    priv_(new priv(s, a))
{}

/// Getter of the canonical type of the current instance of @ref
/// type_base.
///
/// @return a smart pointer to the canonical type of the current
/// intance of @ref type_base, or an empty smart pointer if the
/// current instance of @ref type_base doesn't have any canonical
/// type.
type_base_sptr
type_base::get_canonical_type() const
{return priv_->canonical_type.lock();}

/// Getter of the canonical type pointer.
///
/// Note that this function doesn't return a smart pointer, but rather
/// the underlying pointer managed by the smart pointer.  So it's as
/// fast as possible.  This getter is to be used in code paths that
/// are proven to be performance hot spots; especially, when comparing
/// sensitive types like class, function, pointers and reference
/// types.  Those are compared extremely frequently and thus, their
/// accessing the canonical type must be fast.
///
/// @return the canonical type pointer, not managed by a smart
/// pointer.
type_base*
type_base::get_naked_canonical_type() const
{return priv_->naked_canonical_type;}

/// Get the pretty representation of the current type.
///
/// The pretty representation is retrieved from a cache.  If the cache
/// is empty, this function computes the pretty representation, put it
/// in the cache and returns it.
///
/// Note that if the type is *NOT* canonicalized, the pretty
/// representation is never cached.
///
/// @param internal if true, then the pretty representation is to be
/// used for purpuses that are internal to the libabigail library
/// itself.  If you don't know what this means, then you probably
/// should set this parameter to "false".
const interned_string&
type_base::get_cached_pretty_representation(bool internal) const
{
  if (internal)
    {
      if (!get_naked_canonical_type() || priv_->internal_cached_repr_.empty())
	{
	  string r = ir::get_pretty_representation(this, internal);
	  priv_->internal_cached_repr_ = get_environment()->intern(r);
	}
      return priv_->internal_cached_repr_;
    }

  if (!get_naked_canonical_type() || priv_->cached_repr_.empty())
    {
      string r = ir::get_pretty_representation(this, internal);
      priv_->cached_repr_ = get_environment()->intern(r);
    }

  return priv_->cached_repr_;
}

/// Compares two instances of @ref type_base.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p is non-null and if the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const type_base& l, const type_base& r, change_kind* k)
{
  bool result = (l.get_size_in_bits() == r.get_size_in_bits()
		 && l.get_alignment_in_bits() == r.get_alignment_in_bits());
  if (!result)
    if (k)
      *k |= LOCAL_TYPE_CHANGE_KIND;
  ABG_RETURN(result);
}

/// Return true iff both type declarations are equal.
///
/// Note that this doesn't test if the scopes of both types are equal.
bool
type_base::operator==(const type_base& other) const
{return equals(*this, other, 0);}

/// Inequality operator.
///
///@param other the instance of @ref type_base to compare the current
/// instance against.
///
/// @return true iff the current instance is different from @p other.
bool
type_base::operator!=(const type_base& other) const
{return !operator==(other);}

/// Setter for the size of the type.
///
/// @param s the new size -- in bits.
void
type_base::set_size_in_bits(size_t s)
{priv_->size_in_bits = s;}

/// Getter for the size of the type.
///
/// @return the size in bits of the type.
size_t
type_base::get_size_in_bits() const
{return priv_->size_in_bits;}

/// Setter for the alignment of the type.
///
/// @param a the new alignment -- in bits.
void
type_base::set_alignment_in_bits(size_t a)
{priv_->alignment_in_bits = a;}

/// Getter for the alignment of the type.
///
/// @return the alignment of the type in bits.
size_t
type_base::get_alignment_in_bits() const
{return priv_->alignment_in_bits;}

/// Default implementation of traversal for types.  This function does
/// nothing.  It must be implemented by every single new type that is
/// written.
///
/// Please look at e.g, class_decl::traverse() for an example of how
/// to implement this.
///
/// @param v the visitor used to visit the type.
bool
type_base::traverse(ir_node_visitor& v)
{
  if (v.type_node_has_been_visited(this))
    return true;

  v.visit_begin(this);
  bool result = v.visit_end(this);
  v.mark_type_node_as_visited(this);

  return result;
}

type_base::~type_base()
{delete priv_;}

// </type_base definitions>

// <integral_type definitions>

/// Bitwise OR operator for integral_type::modifiers_type.
///
/// @param l the left-hand side operand.
///
/// @param r the right-hand side operand.
///
/// @return the result of the bitwise OR.
integral_type::modifiers_type
operator|(integral_type::modifiers_type l, integral_type::modifiers_type r)
{
  return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
						    |static_cast<unsigned>(r));
}

/// Bitwise AND operator for integral_type::modifiers_type.
///
/// @param l the left-hand side operand.
///
/// @param r the right-hand side operand.
///
/// @return the result of the bitwise AND.
integral_type::modifiers_type
operator&(integral_type::modifiers_type l, integral_type::modifiers_type r)
{
  return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
						    &static_cast<unsigned>(r));
}

/// Bitwise |= operator for integral_type::modifiers_type.
///
/// @param l the left-hand side operand.
///
/// @param r the right-hand side operand.
///
/// @return the result of the bitwise |=.
integral_type::modifiers_type&
operator|=(integral_type::modifiers_type& l, integral_type::modifiers_type r)
{
  l = l | r;
  return l;
}

/// Parse a word containing one integral type modifier.
///
/// A word is considered to be a string of characters that doesn't
/// contain any white space.
///
/// @param word the word to parse.  It is considered to be a string of
/// characters that doesn't contain any white space.
///
/// @param modifiers out parameter.  It's set by this function to the
/// parsed modifier iff the function returned true.
///
/// @return true iff @word was successfully parsed.
static bool
parse_integral_type_modifier(const string& word,
			     integral_type::modifiers_type &modifiers)
{
    if (word == "signed")
      modifiers |= integral_type::SIGNED_MODIFIER;
    else if (word == "unsigned")
      modifiers |= integral_type::UNSIGNED_MODIFIER;
    else if (word == "short")
      modifiers |= integral_type::SHORT_MODIFIER;
    else if (word == "long")
      modifiers |= integral_type::LONG_MODIFIER;
    else if (word == "long long")
      modifiers |= integral_type::LONG_LONG_MODIFIER;
    else
      return false;

    return true;
}

/// Parse a base type of an integral type from a string.
///
/// @param type_name the type name to parse.
///
/// @param base out parameter.  This is set to the resulting base type
/// parsed, iff the function returned true.
///
/// @return true iff the function could successfully parse the base
/// type.
static bool
parse_base_integral_type(const string& type_name,
			 integral_type::base_type& base)
{
  if (type_name == "int")
    base = integral_type::INT_BASE_TYPE;
  else if (type_name == "char")
    base = integral_type::CHAR_BASE_TYPE;
  else if (type_name == "bool" || type_name == "_Bool")
    base = integral_type::BOOL_BASE_TYPE;
  else if (type_name == "double")
    base = integral_type::DOUBLE_BASE_TYPE;
  else if (type_name =="float")
    base = integral_type::FLOAT_BASE_TYPE;
  else if (type_name == "char16_t")
    base = integral_type::CHAR16_T_BASE_TYPE;
  else if (type_name == "char32_t")
    base = integral_type::CHAR32_T_BASE_TYPE;
  else if (type_name == "wchar_t")
    base = integral_type::WCHAR_T_BASE_TYPE;
  else
    return false;

  return true;
}

/// Parse an integral type from a string.
///
/// @param type_name the string containing the integral type to parse.
///
/// @param base out parameter.  Is set by this function to the base
/// type of the integral type, iff the function returned true.
///
/// @param modifiers out parameter  If set by this function to the
/// modifier of the integral type, iff the function returned true.
///
/// @return true iff the function could parse an integral type from @p
/// type_name.
static bool
parse_integral_type(const string&			type_name,
		    integral_type::base_type&		base,
		    integral_type::modifiers_type&	modifiers)
{
  string input = type_name;
  string::size_type len = input.length();
  string::size_type cur_pos = 0, prev_pos = 0;
  string cur_word, prev_word;
  bool ok = false;

  while (cur_pos < len)
    {
      prev_pos = cur_pos;
      cur_pos = input.find(' ', prev_pos);
      prev_word = cur_word;
      cur_word = input.substr(prev_pos, cur_pos - prev_pos);

      if (cur_pos < len && isspace(input[cur_pos]))
	do
	  ++cur_pos;
	while (cur_pos < len && isspace(input[cur_pos]));

      if (cur_pos < len
	  && cur_word == "long"
	  && prev_word != "long")
	{
	  prev_pos = cur_pos;
	  cur_pos = input.find(' ', prev_pos);
	  string saved_prev_word = prev_word;
	  prev_word = cur_word;
	  cur_word = input.substr(prev_pos, cur_pos - prev_pos);
	  if (cur_word == "long")
	    cur_word = "long long";
	  else
	    {
	      cur_pos = prev_pos;
	      cur_word = prev_word;
	      prev_word = saved_prev_word;
	    }
	}

      if (!parse_integral_type_modifier(cur_word, modifiers))
	{
	  if (!parse_base_integral_type(cur_word, base))
	    return false;
	  else
	    ok = true;
	}
      else
	ok = true;
    }

  return ok;
}

/// Parse an integral type from a string.
///
/// @param str the string containing the integral type to parse.
///
///@param type the resulting @ref integral_type.  Is set to the result
///of the parse, iff the function returns true.
///
/// @return true iff the function could parse an integral type from @p
/// str.
bool
parse_integral_type(const string& str, integral_type& type)
{
  integral_type::base_type base_type = integral_type::INT_BASE_TYPE;
  integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;

  if (!parse_integral_type(str, base_type, modifiers))
    return false;

  // So this is an integral type.
  integral_type int_type(base_type, modifiers);
  type = int_type;
  return true;
}

/// Default constructor of the @ref integral_type.
integral_type::integral_type()
  : base_(INT_BASE_TYPE),
    modifiers_(NO_MODIFIER)
{}

/// Constructor of the @ref integral_type.
///
/// @param b the base type of the integral type.
///
/// @param m the modifiers of the integral type.
integral_type::integral_type(base_type b, modifiers_type m)
  : base_(b), modifiers_(m)
{}

/// Constructor of the @ref integral_type.
///
/// @param the name of the integral type to parse to initialize the
/// current instance of @ref integral_type.
integral_type::integral_type(const string& type_name)
  : base_(INT_BASE_TYPE),
    modifiers_(NO_MODIFIER)
{
  bool could_parse = parse_integral_type(type_name, base_, modifiers_);
  ABG_ASSERT(could_parse);
}

/// Getter of the base type of the @ref integral_type.
///
/// @return the base type of the @ref integral_type.
integral_type::base_type
integral_type::get_base_type() const
{return base_;}

/// Getter of the modifiers bitmap of the @ref integral_type.
///
/// @return the modifiers bitmap of the @ref integral_type.
integral_type::modifiers_type
integral_type::get_modifiers() const
{return modifiers_;}

/// Equality operator for the @ref integral_type.
///
/// @param other the other integral type to compare against.
///
/// @return true iff @p other equals the current instance of @ref
/// integral_type.
bool
integral_type::operator==(const integral_type&other) const
{return base_ == other.base_ && modifiers_ == other.modifiers_;}

/// Return the string representation of the current instance of @ref
/// integral_type.
///
/// @return the string representation of the current instance of @ref
/// integral_type.
string
integral_type::to_string() const
{
  string result;

  // Look at modifiers ...
  if (modifiers_ & SIGNED_MODIFIER)
    result += "signed ";
  if (modifiers_ & UNSIGNED_MODIFIER)
    result += "unsigned ";
  if (modifiers_ & SHORT_MODIFIER)
    result += "short ";
  if (modifiers_ & LONG_MODIFIER)
    result += "long ";
  if (modifiers_ & LONG_LONG_MODIFIER)
    result += "long long ";

  // ... and look at base types.
  if (base_ == INT_BASE_TYPE)
    result += "int";
  else if (base_ == CHAR_BASE_TYPE)
    result += "char";
  else if (base_ == BOOL_BASE_TYPE)
    result += "bool";
  else if (base_ == DOUBLE_BASE_TYPE)
    result += "double";
  else if (base_ == FLOAT_BASE_TYPE)
    result += "float";
  else if (base_ == CHAR16_T_BASE_TYPE)
    result += "char16_t";
    else if (base_ == CHAR32_T_BASE_TYPE)
    result += "char32_t";
    else if (base_ == WCHAR_T_BASE_TYPE)
    result += "wchar_t";

  return result;
}

/// Convert the current instance of @ref integral_type into its string
/// representation.
///
/// @return the string representation of the current instance of @ref
/// integral_type.
integral_type::operator string() const
{return to_string();}

// </integral_type definitions>

//<type_decl definitions>

/// Constructor.
///
/// @param env the environment we are operating from.
///
/// @param name the name of the type declaration.
///
/// @param size_in_bits the size of the current type_decl, in bits.
///
/// @param alignment_in_bits the alignment of the current typ, in
/// bits.
///
/// @param locus the source location of the current type declaration.
///
/// @param linkage_name the linkage_name of the current type declaration.
///
/// @param vis the visibility of the type declaration.
type_decl::type_decl(const environment* env,
		     const string&	name,
		     size_t		size_in_bits,
		     size_t		alignment_in_bits,
		     const location&	locus,
		     const string&	linkage_name,
		     visibility	vis)

  : type_or_decl_base(env,
		      BASIC_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    decl_base(env, name, locus, linkage_name, vis),
    type_base(env, size_in_bits, alignment_in_bits)
{
  runtime_type_instance(this);

  integral_type::base_type base_type = integral_type::INT_BASE_TYPE;
  integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
  integral_type int_type(base_type, modifiers);
  if (parse_integral_type(name, int_type))
    {
      // Convert the integral_type into its canonical string
      // representation.
      string integral_type_name = int_type;

      // Set the name of this type_decl to the canonical string
      // representation above
      set_name(integral_type_name);
      set_qualified_name(get_name());

      if (!get_linkage_name().empty())
	set_linkage_name(integral_type_name);
    }
}

/// Compares two instances of @ref type_decl.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const type_decl& l, const type_decl& r, change_kind* k)
{
  bool result = equals(static_cast<const decl_base&>(l),
		       static_cast<const decl_base&>(r),
		       k);
  if (!k && !result)
    ABG_RETURN_FALSE;

  result &= equals(static_cast<const type_base&>(l),
		   static_cast<const type_base&>(r),
		   k);
  ABG_RETURN(result);
}

/// Return true if both types equals.
///
/// This operator re-uses the overload that takes a decl_base.
///
/// Note that this does not check the scopes of any of the types.
///
/// @param o the other type_decl to check agains.
bool
type_decl::operator==(const type_base& o) const
{
  const decl_base* other = dynamic_cast<const decl_base*>(&o);
  if (!other)
    return false;
  return *this == *other;
}

/// Return true if both types equals.
///
/// Note that this does not check the scopes of any of the types.
///
/// @param o the other type_decl to check against.
bool
type_decl::operator==(const decl_base& o) const
{
  const type_decl* other = dynamic_cast<const type_decl*>(&o);
  if (!other)
    return false;
  return try_canonical_compare(this, other);
}

/// Return true if both types equals.
///
/// Note that this does not check the scopes of any of the types.
///
/// @param o the other type_decl to check against.
///
/// @return true iff the current isntance equals @p o
bool
type_decl::operator==(const type_decl& o) const
{
  const decl_base& other = o;
  return *this == other;
}

/// Inequality operator.
///
/// @param o the other type to compare against.
///
/// @return true iff the current instance is different from @p o.
bool
type_decl::operator!=(const type_decl& o) const
{return !operator==(o);}

/// Equality operator for @ref type_decl_sptr.
///
/// @param l the first operand to compare.
///
/// @param r the second operand to compare.
///
/// @return true iff @p l equals @p r.
bool
operator==(const type_decl_sptr& l, const type_decl_sptr& r)
{
  if (!!l != !!r)
    return false;
  if (l.get() == r.get())
    return true;
  return *l == *r;
}

/// Inequality operator for @ref type_decl_sptr.
///
/// @param l the first operand to compare.
///
/// @param r the second operand to compare.
///
/// @return true iff @p l is different from @p r.
bool
operator!=(const type_decl_sptr& l, const type_decl_sptr& r)
{return !operator==(l, r);}

/// Get the pretty representation of the current instance of @ref
/// type_decl.
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.
///
/// @param qualified_name if true, names emitted in the pretty
/// representation are fully qualified.
///
/// @return the pretty representatin of the @ref type_decl.
string
type_decl::get_pretty_representation(bool internal,
				     bool qualified_name) const
{
  if (qualified_name)
    return get_qualified_name(internal);
  return get_name();
}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
type_decl::traverse(ir_node_visitor& v)
{
  if (v.type_node_has_been_visited(this))
    return true;

  v.visit_begin(this);
  bool result = v.visit_end(this);
  v.mark_type_node_as_visited(this);

  return result;
}

type_decl::~type_decl()
{}
//</type_decl definitions>

// <scope_type_decl definitions>

/// Constructor.
///
/// @param env the environment we are operating from.
///
/// @param name the name of the type.
///
/// @param size_in_bits the size of the type, in bits.
///
/// @param alignment_in_bits the alignment of the type, in bits.
///
/// @param locus the source location where the type is defined.
///
/// @param vis the visibility of the type.
scope_type_decl::scope_type_decl(const environment*	env,
				 const string&		name,
				 size_t		size_in_bits,
				 size_t		alignment_in_bits,
				 const location&	locus,
				 visibility		vis)
  : type_or_decl_base(env,
		      ABSTRACT_SCOPE_TYPE_DECL
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    decl_base(env, name, locus, "", vis),
    type_base(env, size_in_bits, alignment_in_bits),
    scope_decl(env, name, locus)
{}

/// Compares two instances of @ref scope_type_decl.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const scope_type_decl& l, const scope_type_decl& r, change_kind* k)
{
  bool result = equals(static_cast<const scope_decl&>(l),
		  static_cast<const scope_decl&>(r),
		  k);

  if (!k && !result)
    ABG_RETURN_FALSE;

  result &= equals(static_cast<const type_base&>(l),
		   static_cast<const type_base&>(r),
		   k);

  ABG_RETURN(result);
}

/// Equality operator between two scope_type_decl.
///
/// Note that this function does not consider the scope of the scope
/// types themselves.
///
/// @return true iff both scope types are equal.
bool
scope_type_decl::operator==(const decl_base& o) const
{
  const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
  if (!other)
    return false;
  return try_canonical_compare(this, other);
}

/// Equality operator between two scope_type_decl.
///
/// This re-uses the equality operator that takes a decl_base.
///
/// @param o the other scope_type_decl to compare against.
///
/// @return true iff both scope types are equal.
bool
scope_type_decl::operator==(const type_base& o) const
{
  const decl_base* other = dynamic_cast<const decl_base*>(&o);
  if (!other)
    return false;

  return *this == *other;
}

/// Traverses an instance of @ref scope_type_decl, visiting all the
/// sub-types and decls that it might contain.
///
/// @param v the visitor that is used to visit every IR sub-node of
/// the current node.
///
/// @return true if either
///  - all the children nodes of the current IR node were traversed
///    and the calling code should keep going with the traversing.
///  - or the current IR node is already being traversed.
/// Otherwise, returning false means that the calling code should not
/// keep traversing the tree.
bool
scope_type_decl::traverse(ir_node_visitor& v)
{
  if (visiting())
    return true;

  if (v.type_node_has_been_visited(this))
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      for (scope_decl::declarations::const_iterator i =
	     get_member_decls().begin();
	   i != get_member_decls ().end();
	   ++i)
	if (!(*i)->traverse(v))
	  break;
      visiting(false);
    }

  bool result = v.visit_end(this);
  v.mark_type_node_as_visited(this);

  return result;
}

scope_type_decl::~scope_type_decl()
{}
// </scope_type_decl definitions>

// <namespace_decl>

/// Constructor.
///
/// @param the environment we are operatin from.
///
/// @param name the name of the namespace.
///
/// @param locus the source location where the namespace is defined.
///
/// @param vis the visibility of the namespace.
namespace_decl::namespace_decl(const environment*	env,
			       const string&		name,
			       const location&		locus,
			       visibility		vis)
    // We need to call the constructor of decl_base directly here
    // because it is virtually inherited by scope_decl.  Note that we
    // just implicitely call the default constructor for scope_decl
    // here, as what we really want is to initialize the decl_base
    // subobject.  Wow, virtual inheritance is		useful, but setting it
    // up is ugly.
  : type_or_decl_base(env,
		      NAMESPACE_DECL
		      | ABSTRACT_DECL_BASE
		      | ABSTRACT_SCOPE_DECL),
    decl_base(env, name, locus, "", vis),
    scope_decl(env, name, locus)
{
  runtime_type_instance(this);
}

/// Build and return a copy of the pretty representation of the
/// namespace.
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.
///
/// @param qualified_name if true, names emitted in the pretty
/// representation are fully qualified.
///
/// @return a copy of the pretty representation of the namespace.
string
namespace_decl::get_pretty_representation(bool internal,
					  bool qualified_name) const
{
  string r =
    "namespace " + scope_decl::get_pretty_representation(internal,
							 qualified_name);
  return r;
}

/// Return true iff both namespaces and their members are equal.
///
/// Note that this function does not check if the scope of these
/// namespaces are equal.
bool
namespace_decl::operator==(const decl_base& o) const
{
  const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
  if (!other)
    return false;
  return scope_decl::operator==(*other);
}

/// Test if the current namespace_decl is empty or contains empty
/// namespaces itself.
///
/// @return true iff the current namespace_decl is empty or contains
/// empty itself.
bool
namespace_decl::is_empty_or_has_empty_sub_namespaces() const
{
  if (is_empty())
    return true;

  for (declarations::const_iterator i = get_member_decls().begin();
       i != get_member_decls().end();
       ++i)
    {
      if (!is_namespace(*i))
	return false;

      namespace_decl_sptr ns = is_namespace(*i);
      ABG_ASSERT(ns);

      if (!ns->is_empty_or_has_empty_sub_namespaces())
	return false;
    }

  return true;
}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance and on its
/// member nodes.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
namespace_decl::traverse(ir_node_visitor& v)
{
  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      scope_decl::declarations::const_iterator i;
      for (i = get_member_decls().begin();
	   i != get_member_decls ().end();
	   ++i)
	{
	  ir_traversable_base_sptr t =
	    dynamic_pointer_cast<ir_traversable_base>(*i);
	  if (t)
	    if (!t->traverse (v))
	      break;
	}
      visiting(false);
    }
  return v.visit_end(this);
}

namespace_decl::~namespace_decl()
{
}

// </namespace_decl>

// <qualified_type_def>

/// Type of the private data of qualified_type_def.
class qualified_type_def::priv
{
  friend class qualified_type_def;

  qualified_type_def::CV	cv_quals_;
  // Before the type is canonicalized, this is used as a temporary
  // internal name.
  interned_string		temporary_internal_name_;
  // Once the type is canonicalized, this is used as the internal
  // name.
  interned_string		internal_name_;
  weak_ptr<type_base>		underlying_type_;

  priv()
    : cv_quals_(CV_NONE)
  {}

  priv(qualified_type_def::CV quals,
       type_base_sptr t)
    : cv_quals_(quals),
      underlying_type_(t)
  {}

    priv(qualified_type_def::CV quals)
    : cv_quals_(quals)
  {}
};// end class qualified_type_def::priv

/// Build the name of the current instance of qualified type.
///
/// @param fully_qualified if true, build a fully qualified name.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return a copy of the newly-built name.
string
qualified_type_def::build_name(bool fully_qualified, bool internal) const
{
  type_base_sptr t = get_underlying_type();
  if (!t)
    // The qualified type might temporarily have no underlying type,
    // especially during the construction of the type, while the
    // underlying type is not yet constructed.  In that case, let's do
    // like if the underlying type is the 'void' type.
    t = get_environment()->get_void_type();

  return get_name_of_qualified_type(t, get_cv_quals(),
				    fully_qualified,
				    internal);
}

/// This function is automatically invoked whenever an instance of
/// this type is canonicalized.
///
/// It's an overload of the virtual type_base::on_canonical_type_set.
///
/// We put here what is thus meant to be executed only at the point of
/// type canonicalization.
void
qualified_type_def::on_canonical_type_set()
{clear_qualified_name();}

/// Constructor of the qualified_type_def
///
/// @param type the underlying type
///
/// @param quals a bitfield representing the const/volatile qualifiers
///
/// @param locus the location of the qualified type definition
qualified_type_def::qualified_type_def(type_base_sptr		type,
				       CV			quals,
				       const location&		locus)
  : type_or_decl_base(type->get_environment(),
		      QUALIFIED_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    type_base(type->get_environment(), type->get_size_in_bits(),
	      type->get_alignment_in_bits()),
    decl_base(type->get_environment(), "", locus, "",
	      dynamic_pointer_cast<decl_base>(type)->get_visibility()),
    priv_(new priv(quals, type))
{
  runtime_type_instance(this);
  interned_string name = type->get_environment()->intern(build_name(false));
  set_name(name);
}

/// Constructor of the qualified_type_def
///
/// @param env the environment of the type.
///
/// @param quals a bitfield representing the const/volatile qualifiers
///
/// @param locus the location of the qualified type definition
qualified_type_def::qualified_type_def(environment* env,
				       CV quals,
				       const location& locus)
  : type_or_decl_base(env,
		      QUALIFIED_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    type_base(env, /*size_in_bits=*/0,
	      /*alignment_in_bits=*/0),
    decl_base(env, "", locus, ""),
    priv_(new priv(quals))
{
  runtime_type_instance(this);
  // We don't yet have an underlying type.  So for naming purpose,
  // let's temporarily pretend the underlying type is 'void'.
  interned_string name = env->intern("void");
  set_name(name);
}

/// Get the size of the qualified type def.
///
/// This is an overload for type_base::get_size_in_bits().
///
/// @return the size of the qualified type.
size_t
qualified_type_def::get_size_in_bits() const
{
  size_t s = 0;
  if (type_base_sptr ut = get_underlying_type())
    {
      // We do have the underlying type properly set, so let's make
      // the size of the qualified type match the size of its
      // underlying type.
      s = ut->get_size_in_bits();
      if (s != type_base::get_size_in_bits())
	const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
    }
  return type_base::get_size_in_bits();
}

/// Compares two instances of @ref qualified_type_def.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const qualified_type_def& l, const qualified_type_def& r, change_kind* k)
{
  bool result = true;
  if (l.get_cv_quals() != r.get_cv_quals())
    {
      result = false;
      if (k)
	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }

  if (l.get_underlying_type() != r.get_underlying_type())
    {
      result = false;
      if (k)
	{
	  if (!types_have_similar_structure(l.get_underlying_type().get(),
					    r.get_underlying_type().get()))
	    // Underlying type changes in which the structure of the
	    // type changed are considered local changes to the
	    // qualified type.
	    *k |= LOCAL_TYPE_CHANGE_KIND;
	  else
	    *k |= SUBTYPE_CHANGE_KIND;
	}
      else
	// okay strictly speaking this is not necessary, but I am
	// putting it here to maintenance; that is, so that adding
	// subsequent clauses needed to compare two qualified types
	// later still works.
	ABG_RETURN_FALSE;
    }

  ABG_RETURN(result);
}

/// Equality operator for qualified types.
///
/// Note that this function does not check for equality of the scopes.
///
///@param o the other qualified type to compare against.
///
/// @return true iff both qualified types are equal.
bool
qualified_type_def::operator==(const decl_base& o) const
{
  const qualified_type_def* other =
    dynamic_cast<const qualified_type_def*>(&o);
  if (!other)
    return false;
  return try_canonical_compare(this, other);
}

/// Equality operator for qualified types.
///
/// Note that this function does not check for equality of the scopes.
/// Also, this re-uses the equality operator above that takes a
/// decl_base.
///
///@param o the other qualified type to compare against.
///
/// @return true iff both qualified types are equal.
bool
qualified_type_def::operator==(const type_base& o) const
{
  const decl_base* other = dynamic_cast<const decl_base*>(&o);
  if (!other)
    return false;
  return *this == *other;
}

/// Equality operator for qualified types.
///
/// Note that this function does not check for equality of the scopes.
/// Also, this re-uses the equality operator above that takes a
/// decl_base.
///
///@param o the other qualified type to compare against.
///
/// @return true iff both qualified types are equal.
bool
qualified_type_def::operator==(const qualified_type_def& o) const
{
  const decl_base* other = dynamic_cast<const decl_base*>(&o);
  if (!other)
    return false;
  return *this == *other;
}

/// Implementation for the virtual qualified name builder for @ref
/// qualified_type_def.
///
/// @param qualified_name the output parameter to hold the resulting
/// qualified name.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
void
qualified_type_def::get_qualified_name(interned_string& qualified_name,
				       bool internal) const
{qualified_name = get_qualified_name(internal);}

/// Implementation of the virtual qualified name builder/getter.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the resulting qualified name.
const interned_string&
qualified_type_def::get_qualified_name(bool internal) const
{
  const environment* env = get_environment();
  ABG_ASSERT(env);

  if (!get_canonical_type())
    {
      // The type hasn't been canonicalized yet. We want to return a
      // temporary name that is not cached because the structure of
      // this type (and so its name) can change until its
      // canonicalized.
      if (internal)
	{
	  // We are asked to return a temporary *internal* name.
	  // Lets compute it and return a reference to where it's
	  // stored.
	  priv_->temporary_internal_name_ =
	      env->intern(build_name(true, /*internal=*/true));
	  return priv_->temporary_internal_name_;
	}
      else
	{
	  // We are asked to return a temporary non-internal name.
	    set_temporary_qualified_name
	      (env->intern(build_name(true, /*internal=*/false)));
	  return peek_temporary_qualified_name();
	}
    }
  else
    {
      // The type has already been canonicalized. We want to return
      // the definitive name and cache it.
      if (internal)
	{
	  if (priv_->internal_name_.empty())
	    priv_->internal_name_ =
	      env->intern(build_name(/*qualified=*/true,
				     /*internal=*/true));
	  return priv_->internal_name_;
	}
      else
	{
	  if (peek_qualified_name().empty())
	    set_qualified_name
	      (env->intern(build_name(/*qualified=*/true,
				      /*internal=*/false)));
	  return peek_qualified_name();
	}
    }
}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
qualified_type_def::traverse(ir_node_visitor& v)
{
  if (v.type_node_has_been_visited(this))
    return true;

  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      if (type_base_sptr t = get_underlying_type())
	t->traverse(v);
      visiting(false);
    }
  bool result = v.visit_end(this);
  v.mark_type_node_as_visited(this);
  return result;
}

qualified_type_def::~qualified_type_def()
{
}

/// Getter of the const/volatile qualifier bit field
qualified_type_def::CV
qualified_type_def::get_cv_quals() const
{return priv_->cv_quals_;}

/// Setter of the const/value qualifiers bit field
void
qualified_type_def::set_cv_quals(CV cv_quals)
{priv_->cv_quals_ = cv_quals;}

/// Compute and return the string prefix or suffix representing the
/// qualifiers hold by the current instance of @ref
/// qualified_type_def.
///
/// @return the newly-built cv string.
string
qualified_type_def::get_cv_quals_string_prefix() const
{return get_string_representation_of_cv_quals(priv_->cv_quals_);}

/// Getter of the underlying type
type_base_sptr
qualified_type_def::get_underlying_type() const
{return priv_->underlying_type_.lock();}

/// Setter of the underlying type.
///
/// @param t the new underlying type.
void
qualified_type_def::set_underlying_type(const type_base_sptr& t)
{
  ABG_ASSERT(t);
  priv_->underlying_type_ = t;
  // Now we need to update other properties that depend on the new underlying type.
  set_size_in_bits(t->get_size_in_bits());
  set_alignment_in_bits(t->get_alignment_in_bits());
  interned_string name = get_environment()->intern(build_name(false));
  set_name(name);
  if (scope_decl* s = get_scope())
      {
	// Now that the name has been updated, we need to update the
	// lookup maps accordingly.
	scope_decl::declarations::iterator i;
	if (s->find_iterator_for_member(this, i))
	  maybe_update_types_lookup_map(*i);
	else
	  ABG_ASSERT_NOT_REACHED;
      }
}

/// Non-member equality operator for @ref qualified_type_def
///
/// @param l the left-hand side of the equality operator
///
/// @param r the right-hand side of the equality operator
///
/// @return true iff @p l and @p r equals.
bool
operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
{
  if (l.get() == r.get())
    return true;
  if (!!l != !!r)
    return false;

  return *l == *r;
}

/// Non-member inequality operator for @ref qualified_type_def
///
/// @param l the left-hand side of the equality operator
///
/// @param r the right-hand side of the equality operator
///
/// @return true iff @p l and @p r equals.
bool
operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
{return ! operator==(l, r);}

/// Overloaded bitwise OR operator for cv qualifiers.
qualified_type_def::CV
operator|(qualified_type_def::CV lhs, qualified_type_def::CV rhs)
{
  return static_cast<qualified_type_def::CV>
    (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
}

/// Overloaded bitwise |= operator for cv qualifiers.
qualified_type_def::CV&
operator|=(qualified_type_def::CV& l, qualified_type_def::CV r)
{
  l = l | r;
  return l;
}

/// Overloaded bitwise AND operator for CV qualifiers.
qualified_type_def::CV
operator&(qualified_type_def::CV lhs, qualified_type_def::CV rhs)
{
    return static_cast<qualified_type_def::CV>
    (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
}

/// Overloaded bitwise inverting operator for CV qualifiers.
qualified_type_def::CV
operator~(qualified_type_def::CV q)
{return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}

/// Streaming operator for qualified_type_decl::CV
///
/// @param o the output stream to serialize the cv qualifier to.
///
/// @param cv the cv qualifier to serialize.
///
/// @return the output stream used.
std::ostream&
operator<<(std::ostream& o, qualified_type_def::CV cv)
{
  string str;

  switch (cv)
    {
    case qualified_type_def::CV_NONE:
      str = "none";
      break;
    case qualified_type_def::CV_CONST:
      str = "const";
      break;
    case qualified_type_def::CV_VOLATILE:
      str = "volatile";
      break;
    case qualified_type_def::CV_RESTRICT:
      str = "restrict";
      break;
    }

  o << str;
  return o;
}

// </qualified_type_def>

//<pointer_type_def definitions>

/// Private data structure of the @ref pointer_type_def.
struct pointer_type_def::priv
{
  type_base_wptr pointed_to_type_;
  type_base* naked_pointed_to_type_;
  interned_string internal_qualified_name_;
  interned_string temp_internal_qualified_name_;

  priv(const type_base_sptr& t)
    : pointed_to_type_(type_or_void(t, 0)),
      naked_pointed_to_type_(t.get())
  {}

  priv()
    : naked_pointed_to_type_()
  {}
}; //end struct pointer_type_def

/// This function is automatically invoked whenever an instance of
/// this type is canonicalized.
///
/// It's an overload of the virtual type_base::on_canonical_type_set.
///
/// We put here what is thus meant to be executed only at the point of
/// type canonicalization.
void
pointer_type_def::on_canonical_type_set()
{clear_qualified_name();}


///Constructor of @ref pointer_type_def.
///
/// @param pointed_to the pointed-to type.
///
/// @param size_in_bits the size of the type, in bits.
///
/// @param align_in_bits the alignment of the type, in bits.
///
/// @param locus the source location where the type was defined.
pointer_type_def::pointer_type_def(const type_base_sptr&	pointed_to,
				   size_t			size_in_bits,
				   size_t			align_in_bits,
				   const location&		locus)
  : type_or_decl_base(pointed_to->get_environment(),
		      POINTER_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
    decl_base(pointed_to->get_environment(), "", locus, ""),
    priv_(new priv(pointed_to))
{
  runtime_type_instance(this);
  try
    {
      ABG_ASSERT(pointed_to);
      const environment* env = pointed_to->get_environment();
      decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
      string name = (pto ? pto->get_name() : string("void")) + "*";
      set_name(env->intern(name));
      if (pto)
	set_visibility(pto->get_visibility());
    }
  catch (...)
    {}
}

///Constructor of @ref pointer_type_def.
///
/// @param env the environment of the type.
///
/// @param size_in_bits the size of the type, in bits.
///
/// @param align_in_bits the alignment of the type, in bits.
///
/// @param locus the source location where the type was defined.
pointer_type_def::pointer_type_def(environment* env, size_t size_in_bits,
				   size_t alignment_in_bits,
				   const location& locus)
  : type_or_decl_base(env,
		      POINTER_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    type_base(env, size_in_bits, alignment_in_bits),
    decl_base(env, "", locus, ""),
    priv_(new priv())
{
  runtime_type_instance(this);
  string name = string("void") + "*";
  set_name(env->intern(name));
}

/// Set the pointed-to type of the pointer.
///
/// @param t the new pointed-to type.
void
pointer_type_def::set_pointed_to_type(const type_base_sptr& t)
{
  ABG_ASSERT(t);
  priv_->pointed_to_type_ = t;
  priv_->naked_pointed_to_type_ = t.get();

  try
    {
      const environment* env = t->get_environment();
      ABG_ASSERT(get_environment() == env);
      decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
      string name = (pto ? pto->get_name() : string("void")) + "*";
      set_name(env->intern(name));
      if (pto)
	set_visibility(pto->get_visibility());
    }
  catch (...)
    {}
}

/// Compares two instances of @ref pointer_type_def.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const pointer_type_def& l, const pointer_type_def& r, change_kind* k)
{
  bool result = l.get_pointed_to_type() == r.get_pointed_to_type();
  if (!result)
    if (k)
      {
	if (!types_have_similar_structure(&l, &r))
	  // pointed-to type changes in which the structure of the
	  // type changed are considered local changes to the pointer
	  // type.
	  *k |= LOCAL_TYPE_CHANGE_KIND;
	*k |= SUBTYPE_CHANGE_KIND;
      }

  ABG_RETURN(result);
}

/// Return true iff both instances of pointer_type_def are equal.
///
/// Note that this function does not check for the scopes of the this
/// types.
bool
pointer_type_def::operator==(const decl_base& o) const
{
  const pointer_type_def* other = is_pointer_type(&o);
  if (!other)
    return false;
  return try_canonical_compare(this, other);
}

/// Return true iff both instances of pointer_type_def are equal.
///
/// Note that this function does not check for the scopes of the
/// types.
///
/// @param other the other type to compare against.
///
/// @return true iff @p other equals the current instance.
bool
pointer_type_def::operator==(const type_base& other) const
{
  const decl_base* o = is_decl(&other);
  if (!o)
    return false;
  return *this == *o;
}

/// Return true iff both instances of pointer_type_def are equal.
///
/// Note that this function does not check for the scopes of the
/// types.
///
/// @param other the other type to compare against.
///
/// @return true iff @p other equals the current instance.
bool
pointer_type_def::operator==(const pointer_type_def& other) const
{
  const decl_base& o = other;
  return *this == o;
}

/// Getter of the pointed-to type.
///
/// @return the pointed-to type.
const type_base_sptr
pointer_type_def::get_pointed_to_type() const
{return priv_->pointed_to_type_.lock();}

/// Getter of a naked pointer to the pointed-to type.
///
/// @return a naked pointed to the pointed-to type.
type_base*
pointer_type_def::get_naked_pointed_to_type() const
{return priv_->naked_pointed_to_type_;}

/// Build and return the qualified name of the current instance of
/// @ref pointer_type_def.
///
/// @param qn output parameter.  The resulting qualified name.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
void
pointer_type_def::get_qualified_name(interned_string& qn, bool internal) const
{qn = get_qualified_name(internal);}

/// Build, cache and return the qualified name of the current instance
/// of @ref pointer_type_def.  Subsequent invocations of this function
/// return the cached value.
///
/// Note that this function should work even if the underlying type is
/// momentarily empty.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the resulting qualified name.
const interned_string&
pointer_type_def::get_qualified_name(bool internal) const
{
  type_base* pointed_to_type = get_naked_pointed_to_type();

  if (internal)
    {
      if (get_canonical_type())
	{
	  if (priv_->internal_qualified_name_.empty())
	    if (pointed_to_type)
	      priv_->internal_qualified_name_ =
		get_name_of_pointer_to_type(*pointed_to_type,
					    /*qualified_name=*/true,
					    /*internal=*/true);
	  return priv_->internal_qualified_name_;
	}
      else
	{
	  // As the type hasn't yet been canonicalized, its structure
	  // (and so its name) can change.  So let's invalidate the
	  // cache where we store its name at each invocation of this
	  // function.
	  if (pointed_to_type)
	    priv_->temp_internal_qualified_name_ =
	      get_name_of_pointer_to_type(*pointed_to_type,
					  /*qualified_name=*/true,
					  /*internal=*/true);
	  return priv_->temp_internal_qualified_name_;
	}
    }
  else
    {
      if (get_naked_canonical_type())
	{
	  if (decl_base::peek_qualified_name().empty())
	    set_qualified_name
	      (get_name_of_pointer_to_type(*pointed_to_type,
					   /*qualified_name=*/true,
					   /*internal=*/false));
	  return decl_base::peek_qualified_name();
	}
      else
	{
	  // As the type hasn't yet been canonicalized, its structure
	  // (and so its name) can change.  So let's invalidate the
	  // cache where we store its name at each invocation of this
	  // function.
	  if (pointed_to_type)
	    set_qualified_name
	      (get_name_of_pointer_to_type(*pointed_to_type,
					   /*qualified_name=*/true,
					   /*internal=*/false));
	  return decl_base::peek_qualified_name();
	}
    }
}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
pointer_type_def::traverse(ir_node_visitor& v)
{
  if (v.type_node_has_been_visited(this))
    return true;

  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      if (type_base_sptr t = get_pointed_to_type())
	t->traverse(v);
      visiting(false);
    }

  bool result = v.visit_end(this);
  v.mark_type_node_as_visited(this);
  return result;
}

pointer_type_def::~pointer_type_def()
{}

/// Turn equality of shared_ptr of @ref pointer_type_def into a deep
/// equality; that is, make it compare the pointed to objects too.
///
/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
/// of the equality.
///
/// @param r the shared_ptr of @ref pointer_type_def on
/// right-hand-side of the equality.
///
/// @return true if the @ref pointer_type_def pointed to by the
/// shared_ptrs are equal, false otherwise.
bool
operator==(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
{
  if (l.get() == r.get())
    return true;
  if (!!l != !!r)
    return false;

  return *l == *r;
}

/// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
/// equality; that is, make it compare the pointed to objects too.
///
/// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
/// of the equality.
///
/// @param r the shared_ptr of @ref pointer_type_def on
/// right-hand-side of the equality.
///
/// @return true iff the @ref pointer_type_def pointed to by the
/// shared_ptrs are different.
bool
operator!=(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
{return !operator==(l, r);}

// </pointer_type_def definitions>

// <reference_type_def definitions>

/// This function is automatically invoked whenever an instance of
/// this type is canonicalized.
///
/// It's an overload of the virtual type_base::on_canonical_type_set.
///
/// We put here what is thus meant to be executed only at the point of
/// type canonicalization.
void
reference_type_def::on_canonical_type_set()
{clear_qualified_name();}

/// Constructor of the reference_type_def type.
///
/// @param pointed_to the pointed to type.
///
/// @param lvalue wether the reference is an lvalue reference.  If
/// false, the reference is an rvalue one.
///
/// @param size_in_bits the size of the type, in bits.
///
/// @param align_in_bits the alignment of the type, in bits.
///
/// @param locus the source location of the type.
reference_type_def::reference_type_def(const type_base_sptr	pointed_to,
				       bool			lvalue,
				       size_t			size_in_bits,
				       size_t			align_in_bits,
				       const location&		locus)
  : type_or_decl_base(pointed_to->get_environment(),
		      REFERENCE_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
    decl_base(pointed_to->get_environment(), "", locus, ""),
    is_lvalue_(lvalue)
{
  runtime_type_instance(this);

  try
    {
      decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
      string name;
      if (pto)
	{
	  set_visibility(pto->get_visibility());
	  name = string(pto->get_name()) + "&";
	}
      else
	name = string(get_type_name(is_function_type(pointed_to),
				    /*qualified_name=*/true)) + "&";

      if (!is_lvalue())
	name += "&";
      environment* env = pointed_to->get_environment();
      ABG_ASSERT(env);
      set_name(env->intern(name));

      pointed_to_type_ = type_base_wptr(type_or_void(pointed_to, 0));
    }
  catch (...)
    {}
}

/// Constructor of the reference_type_def type.
///
/// This one creates a type that has no pointed-to type, temporarily.
/// This is useful for cases where the underlying type is not yet
/// available.  It can be set later using
/// reference_type_def::set_pointed_to_type().
///
/// @param env the environment of the type.
///
/// @param lvalue wether the reference is an lvalue reference.  If
/// false, the reference is an rvalue one.
///
/// @param size_in_bits the size of the type, in bits.
///
/// @param align_in_bits the alignment of the type, in bits.
///
/// @param locus the source location of the type.
reference_type_def::reference_type_def(const environment* env, bool lvalue,
				       size_t size_in_bits,
				       size_t alignment_in_bits,
				       const location& locus)
  : type_or_decl_base(env,
		      REFERENCE_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    type_base(env, size_in_bits, alignment_in_bits),
    decl_base(env, "", locus, ""),
    is_lvalue_(lvalue)
{
  runtime_type_instance(this);
  string name = "void&";
  if (!is_lvalue())
    name += "&";
  ABG_ASSERT(env);
  set_name(env->intern(name));
  pointed_to_type_ = type_base_wptr(env->get_void_type());
}

/// Setter of the pointed_to type of the current reference type.
///
/// @param pointed_to the new pointed to type.
void
reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
{
  ABG_ASSERT(pointed_to_type);
  pointed_to_type_ = pointed_to_type;

  decl_base_sptr pto;
  try
    {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
  catch (...)
    {}

  if (pto)
    {
      set_visibility(pto->get_visibility());
      string name = string(pto->get_name()) + "&";
      if (!is_lvalue())
	name += "&";
      environment* env = pto->get_environment();
      ABG_ASSERT(env && env == get_environment());
      set_name(env->intern(name));
    }
}

/// Compares two instances of @ref reference_type_def.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const reference_type_def& l, const reference_type_def& r, change_kind* k)
{
  if (l.is_lvalue() != r.is_lvalue())
    {
      if (k)
	*k |= LOCAL_TYPE_CHANGE_KIND;
      ABG_RETURN_FALSE;
    }

  // Compare the pointed-to-types modulo the typedefs they might have
  bool result = (l.get_pointed_to_type() == r.get_pointed_to_type());
  if (!result)
    if (k)
      {
	if (!types_have_similar_structure(&l, &r))
	  *k |= LOCAL_TYPE_CHANGE_KIND;
	*k |= SUBTYPE_CHANGE_KIND;
      }
  ABG_RETURN(result);
}

/// Equality operator of the @ref reference_type_def type.
///
/// @param o the other instance of @ref reference_type_def to compare
/// against.
///
/// @return true iff the two instances are equal.
bool
reference_type_def::operator==(const decl_base& o) const
{
  const reference_type_def* other =
    dynamic_cast<const reference_type_def*>(&o);
  if (!other)
    return false;
  return try_canonical_compare(this, other);
}

/// Equality operator of the @ref reference_type_def type.
///
/// @param o the other instance of @ref reference_type_def to compare
/// against.
///
/// @return true iff the two instances are equal.
bool
reference_type_def::operator==(const type_base& o) const
{
  const decl_base* other = dynamic_cast<const decl_base*>(&o);
  if (!other)
    return false;
  return *this == *other;
}

/// Equality operator of the @ref reference_type_def type.
///
/// @param o the other instance of @ref reference_type_def to compare
/// against.
///
/// @return true iff the two instances are equal.
bool
reference_type_def::operator==(const reference_type_def& o) const
{
  const decl_base* other = dynamic_cast<const decl_base*>(&o);
  if (!other)
    return false;
  return *this == *other;
}

type_base_sptr
reference_type_def::get_pointed_to_type() const
{return pointed_to_type_.lock();}

bool
reference_type_def::is_lvalue() const
{return is_lvalue_;}

/// Build and return the qualified name of the current instance of the
/// @ref reference_type_def.
///
/// @param qn output parameter.  Is set to the newly-built qualified
/// name of the current instance of @ref reference_type_def.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
void
reference_type_def::get_qualified_name(interned_string& qn, bool internal) const
{qn = get_qualified_name(internal);}

/// Build, cache and return the qualified name of the current instance
/// of the @ref reference_type_def.  Subsequent invocations of this
/// function return the cached value.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the newly-built qualified name of the current instance of
/// @ref reference_type_def.
const interned_string&
reference_type_def::get_qualified_name(bool internal) const
{
  if (peek_qualified_name().empty()
      || !get_canonical_type())
    set_qualified_name(get_name_of_reference_to_type(*get_pointed_to_type(),
						     is_lvalue(),
						     /*qualified_name=*/true,
						     internal));
  return peek_qualified_name();
}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
reference_type_def::traverse(ir_node_visitor& v)
{
  if (v.type_node_has_been_visited(this))
    return true;

  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      if (type_base_sptr t = get_pointed_to_type())
	t->traverse(v);
      visiting(false);
    }

  bool result = v.visit_end(this);
  v.mark_type_node_as_visited(this);
  return result;
}

reference_type_def::~reference_type_def()
{}

/// Turn equality of shared_ptr of @ref reference_type_def into a deep
/// equality; that is, make it compare the pointed to objects too.
///
/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
/// of the equality.
///
/// @param r the shared_ptr of @ref reference_type_def on
/// right-hand-side of the equality.
///
/// @return true if the @ref reference_type_def pointed to by the
/// shared_ptrs are equal, false otherwise.
bool
operator==(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
{
  if (l.get() == r.get())
    return true;
  if (!!l != !!r)
    return false;

  return *l == *r;
}

/// Turn inequality of shared_ptr of @ref reference_type_def into a deep
/// equality; that is, make it compare the pointed to objects too.
///
/// @param l the shared_ptr of @ref reference_type_def on left-hand-side
/// of the equality.
///
/// @param r the shared_ptr of @ref reference_type_def on
/// right-hand-side of the equality.
///
/// @return true iff the @ref reference_type_def pointed to by the
/// shared_ptrs are different.
bool
operator!=(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
{return !operator==(l, r);}

// </reference_type_def definitions>

// <array_type_def definitions>

// <array_type_def::subrange_type>
array_type_def::subrange_type::~subrange_type() = default;

// <array_type_def::subrante_type::bound_value>

/// Default constructor of the @ref
/// array_type_def::subrange_type::bound_value class.
///
/// Constructs an unsigned bound_value of value zero.
array_type_def::subrange_type::bound_value::bound_value()
  : s_(UNSIGNED_SIGNEDNESS)
{
  v_.unsigned_ = 0;
}

/// Initialize an unsigned bound_value with a given value.
///
/// @param v the initial bound value.
array_type_def::subrange_type::bound_value::bound_value(uint64_t v)
  : s_(UNSIGNED_SIGNEDNESS)
{
  v_.unsigned_ = v;
}

/// Initialize a signed bound_value with a given value.
///
/// @param v the initial bound value.
array_type_def::subrange_type::bound_value::bound_value(int64_t v)
  : s_(SIGNED_SIGNEDNESS)
{
  v_.signed_ = v;
}

/// Getter of the signedness (unsigned VS signed) of the bound value.
///
/// @return the signedness of the bound value.
enum array_type_def::subrange_type::bound_value::signedness
array_type_def::subrange_type::bound_value::get_signedness() const
{return s_;}

/// Setter of the signedness (unsigned VS signed) of the bound value.
///
/// @param s the new signedness of the bound value.
void
array_type_def::subrange_type::bound_value::set_signedness(enum signedness s)
{ s_ = s;}

/// Getter of the bound value as a signed value.
///
/// @return the bound value as signed.
int64_t
array_type_def::subrange_type::bound_value::get_signed_value() const
{return v_.signed_;
}

/// Getter of the bound value as an unsigned value.
///
/// @return the bound value as unsigned.
uint64_t
array_type_def::subrange_type::bound_value::get_unsigned_value()
{return v_.unsigned_;}

/// Setter of the bound value as unsigned.
///
/// @param v the new unsigned value.
void
array_type_def::subrange_type::bound_value::set_unsigned(uint64_t v)
{
    s_ = UNSIGNED_SIGNEDNESS;
  v_.unsigned_ = v;
}

/// Setter of the bound value as signed.
///
/// @param v the new signed value.
void
array_type_def::subrange_type::bound_value::set_signed(int64_t v)
{
  s_ = SIGNED_SIGNEDNESS;
  v_.signed_ = v;
}

/// Equality operator of the bound value.
///
/// @param v the other bound value to compare with.
///
/// @return true iff the current bound value equals @p v.
bool
array_type_def::subrange_type::bound_value::operator==(const bound_value& v) const
{
  return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
}

// </array_type_def::subrante_type::bound_value>

struct array_type_def::subrange_type::priv
{
  bound_value		lower_bound_;
  bound_value		upper_bound_;
  type_base_wptr	underlying_type_;
  translation_unit::language language_;
  bool			infinite_;

  priv(bound_value ub,
       translation_unit::language l = translation_unit::LANG_C11)
    : upper_bound_(ub), language_(l), infinite_(false)
  {}

  priv(bound_value lb, bound_value ub,
       translation_unit::language l = translation_unit::LANG_C11)
    : lower_bound_(lb), upper_bound_(ub),
      language_(l), infinite_(false)
  {}

  priv(bound_value lb, bound_value ub, const type_base_sptr &u,
       translation_unit::language l = translation_unit::LANG_C11)
    : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
      language_(l), infinite_(false)
  {}
};

/// Constructor of an array_type_def::subrange_type type.
///
/// @param env the environment this type was created from.
///
/// @param name the name of the subrange type.
///
/// @param lower_bound the lower bound of the array.  This is
/// generally zero (at least for C and C++).
///
/// @param upper_bound the upper bound of the array.
///
/// @param underlying_type the underlying type of the subrange type.
///
/// @param loc the source location where the type is defined.
array_type_def::subrange_type::subrange_type(const environment* env,
					     const string&	name,
					     bound_value	lower_bound,
					     bound_value	upper_bound,
					     const type_base_sptr& utype,
					     const location&	loc,
					     translation_unit::language l)
  : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
    type_base(env,
	      upper_bound.get_unsigned_value()
	      - lower_bound.get_unsigned_value(),
	      0),
    decl_base(env, name, loc, ""),
    priv_(new priv(lower_bound, upper_bound, utype, l))
{
  runtime_type_instance(this);
}

/// Constructor of the array_type_def::subrange_type type.
///
/// @param env the environment this type is being created in.
///
/// @param name the name of the subrange type.
///
/// @param lower_bound the lower bound of the array.  This is
/// generally zero (at least for C and C++).
///
/// @param upper_bound the upper bound of the array.
///
/// @param loc the source location where the type is defined.
///
/// @param l the language that generated this subrange.
array_type_def::subrange_type::subrange_type(const environment* env,
					     const string&	name,
					     bound_value	lower_bound,
					     bound_value	upper_bound,
					     const location&	loc,
					     translation_unit::language l)
  : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
    type_base(env,
	      upper_bound.get_unsigned_value()
	      - lower_bound.get_unsigned_value(), 0),
    decl_base(env, name, loc, ""),
    priv_(new priv(lower_bound, upper_bound, l))
{
  runtime_type_instance(this);
}

/// Constructor of the array_type_def::subrange_type type.
///
/// @param env the environment this type is being created from.
///
/// @param name of the name of type.
///
/// @param upper_bound the upper bound of the array.  The lower bound
/// is considered to be zero.
///
/// @param loc the source location of the type.
///
/// @param the language that generated this type.
array_type_def::subrange_type::subrange_type(const environment* env,
					     const string&	name,
					     bound_value	upper_bound,
					     const location&	loc,
					     translation_unit::language l)
  : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
    type_base(env, upper_bound.get_unsigned_value(), 0),
    decl_base(env, name, loc, ""),
    priv_(new priv(upper_bound, l))
{
  runtime_type_instance(this);
}

/// Getter of the underlying type of the subrange, that is, the type
/// that defines the range.
///
/// @return the underlying type.
type_base_sptr
array_type_def::subrange_type::get_underlying_type() const
{return priv_->underlying_type_.lock();}

/// Setter of the underlying type of the subrange, that is, the type
/// that defines the range.
///
/// @param u the new underlying type.
void
array_type_def::subrange_type::set_underlying_type(const type_base_sptr &u)
{
  ABG_ASSERT(priv_->underlying_type_.expired());
  priv_->underlying_type_ = u;
}

/// Getter of the upper bound of the subrange type.
///
/// @return the upper bound of the subrange type.
int64_t
array_type_def::subrange_type::get_upper_bound() const
{return priv_->upper_bound_.get_signed_value();}

/// Getter of the lower bound of the subrange type.
///
/// @return the lower bound of the subrange type.
int64_t
array_type_def::subrange_type::get_lower_bound() const
{return priv_->lower_bound_.get_signed_value();}

/// Setter of the upper bound of the subrange type.
///
/// @param ub the new value of the upper bound.
void
array_type_def::subrange_type::set_upper_bound(int64_t ub)
{priv_->upper_bound_ = ub;}

/// Setter of the lower bound.
///
/// @param lb the new value of the lower bound.
void
array_type_def::subrange_type::set_lower_bound(int64_t lb)
{priv_->lower_bound_ = lb;}

/// Getter of the length of the subrange type.
///
/// Note that a length of zero means the array has an infinite (or
/// rather a non-known) size.
///
/// @return the length of the subrange type.
uint64_t
array_type_def::subrange_type::get_length() const
{
  if (is_infinite())
    return 0;

  ABG_ASSERT(get_upper_bound() >= get_lower_bound());
  return get_upper_bound() - get_lower_bound() + 1;
}

/// Test if the length of the subrange type is infinite.
///
/// @return true iff the length of the subrange type is infinite.
bool
array_type_def::subrange_type::is_infinite() const
{return priv_->infinite_;}

/// Set the infinite-ness status of the subrange type.
///
/// @param f true iff the length of the subrange type should be set to
/// being infinite.
void
array_type_def::subrange_type::is_infinite(bool f)
{priv_->infinite_ = f;}

/// Getter of the language that generated this type.
///
/// @return the language of this type.
translation_unit::language
array_type_def::subrange_type::get_language() const
{return priv_->language_;}

/// Return a string representation of the sub range.
///
/// @return the string representation of the sub range.
string
array_type_def::subrange_type::as_string() const
{
  std::ostringstream o;

  if (is_ada_language(get_language()))
    {
      type_base_sptr underlying_type = get_underlying_type();
      if (underlying_type)
	o << ir::get_pretty_representation(underlying_type, false) << " ";
      o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
    }
  else if (is_infinite())
    o << "[]";
  else
    o << "["  << get_length() << "]";

  return o.str();
}

/// Return a string representation of a vector of subranges
///
/// @return the string representation of a vector of sub ranges.
string
array_type_def::subrange_type::vector_as_string(const vector<subrange_sptr>& v)
{
  if (v.empty())
    return "[]";

  string r;
  for (vector<subrange_sptr>::const_iterator i = v.begin();
       i != v.end();
       ++i)
    r += (*i)->as_string();

  return r;
}

/// Compares two isntances of @ref array_type_def::subrange_type.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const array_type_def::subrange_type& l,
       const array_type_def::subrange_type& r,
       change_kind* k)
{
  bool result = true;

  if (l.get_lower_bound() != r.get_lower_bound()
      || l.get_upper_bound() != r.get_upper_bound()
      || l.get_name() != r.get_name())
    {
      result = false;
      if (k)
	*k |= LOCAL_TYPE_CHANGE_KIND;
      else
	ABG_RETURN(result);
    }

#if 0
  // If we enable this, we need to update the reporting code too, to
  // report changes about range underlying types too.
  if (l.get_underlying_type() != r.get_underlying_type())
    {
      result = false;
      if (k)
	{
	  if (!types_have_similar_structure(l.get_underlying_type().get(),
					    r.get_underlying_type().get()))
	    *k |= LOCAL_TYPE_CHANGE_KIND;
	  else
	    *k |= SUBTYPE_CHANGE_KIND;
	}
      else
	ABG_RETURN(result);
    }
#endif
  ABG_RETURN(result);
}

/// Equality operator.
///
/// @param o the other subrange to test against.
///
/// @return true iff @p o equals the current instance of
/// array_type_def::subrange_type.
bool
array_type_def::subrange_type::operator==(const decl_base& o) const
{
  const subrange_type* other =
    dynamic_cast<const subrange_type*>(&o);
  if (!other)
    return false;
  return try_canonical_compare(this, other);
}

/// Equality operator.
///
/// @param o the other subrange to test against.
///
/// @return true iff @p o equals the current instance of
/// array_type_def::subrange_type.
bool
array_type_def::subrange_type::operator==(const type_base& o) const
{
  const decl_base* other = dynamic_cast<const decl_base*>(&o);
  if (!other)
    return false;
  return *this == *other;
}

/// Equality operator.
///
/// @param o the other subrange to test against.
///
/// @return true iff @p o equals the current instance of
/// array_type_def::subrange_type.
bool
array_type_def::subrange_type::operator==(const subrange_type& o) const
{
  const type_base &t = o;
  return operator==(t);
}

/// Inequality operator.
///
/// @param o the other subrange to test against.
///
/// @return true iff @p o is different from the current instance of
/// array_type_def::subrange_type.
bool
array_type_def::subrange_type::operator!=(const subrange_type& o) const
{return !operator==(o);}

/// Build a pretty representation for an
/// array_type_def::subrange_type.
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.
///
/// @return a copy of the pretty representation of the current
/// instance of typedef_decl.
string
array_type_def::subrange_type::get_pretty_representation(bool, bool) const
{
  string name = get_name();
  string repr;

  if (name.empty())
    repr += "<anonymous range>";
  else
    repr += "<range " + get_name() + ">";
  repr += as_string();

  return repr;
}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
array_type_def::subrange_type::traverse(ir_node_visitor& v)
{
  if (v.type_node_has_been_visited(this))
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      if (type_base_sptr u = get_underlying_type())
	u->traverse(v);
      visiting(false);
    }

  bool result = v.visit_end(this);
  v.mark_type_node_as_visited(this);
  return result;
}

// </array_type_def::subrange_type>

struct array_type_def::priv
{
  type_base_wptr	element_type_;
  subranges_type	subranges_;
  interned_string	temp_internal_qualified_name_;
  interned_string	internal_qualified_name_;

  priv(type_base_sptr t)
    : element_type_(t)
  {}

  priv(type_base_sptr t, subranges_type subs)
    : element_type_(t), subranges_(subs)
  {}

  priv()
  {}
};

/// Constructor for the type array_type_def
///
/// Note how the constructor expects a vector of subrange
/// objects. Parsing of the array information always entails
/// parsing the subrange info as well, thus the class subrange_type
/// is defined inside class array_type_def and also parsed
/// simultaneously.
///
/// @param e_type the type of the elements contained in the array
///
/// @param subs a vector of the array's subranges(dimensions)
///
/// @param locus the source location of the array type definition.
array_type_def::array_type_def(const type_base_sptr			e_type,
			       const std::vector<subrange_sptr>&	subs,
			       const location&				locus)
  : type_or_decl_base(e_type->get_environment(),
		      ARRAY_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
    decl_base(e_type->get_environment(), locus),
    priv_(new priv(e_type))
{
  runtime_type_instance(this);
  append_subranges(subs);
}

/// Constructor for the type array_type_def
///
/// This constructor builds a temporary array that has no element type
/// associated.  Later when the element type is available, it be set
/// with the array_type_def::set_element_type() member function.
///
/// Note how the constructor expects a vector of subrange
/// objects. Parsing of the array information always entails
/// parsing the subrange info as well, thus the class subrange_type
/// is defined inside class array_type_def and also parsed
/// simultaneously.
///
/// @param env the environment of the array type.
///
/// @param subs a vector of the array's subranges(dimensions)
///
/// @param locus the source location of the array type definition.
array_type_def::array_type_def(environment*				env,
			       const std::vector<subrange_sptr>&	subs,
			       const location&				locus)
  : type_or_decl_base(env,
		      ARRAY_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    type_base(env, 0, 0),
    decl_base(env, locus),
    priv_(new priv)
{
  runtime_type_instance(this);
  append_subranges(subs);
}

/// Update the size of the array.
///
/// This function computes the size of the array and sets it using
/// type_base::set_size_in_bits().
void
array_type_def::update_size()
{
  type_base_sptr e = priv_->element_type_.lock();
  if (e)
    {
      size_t s = e->get_size_in_bits();
      if (s)
	{
	  for (const auto &sub : get_subranges())
	    s *= sub->get_length();

	  const environment* env = e->get_environment();
	  ABG_ASSERT(env);
	  set_size_in_bits(s);
	}
      set_alignment_in_bits(e->get_alignment_in_bits());
    }
}

string
array_type_def::get_subrange_representation() const
{
  string r = subrange_type::vector_as_string(get_subranges());
  return r;
}

/// Get the string representation of an @ref array_type_def.
///
/// @param a the array type to consider.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
static string
get_type_representation(const array_type_def& a, bool internal)
{
  type_base_sptr e_type = a.get_element_type();
  decl_base_sptr d = get_type_declaration(e_type);
  string r;

  if (is_ada_language(a.get_language()))
    {
      std::ostringstream o;
      o << "array ("
	<< a.get_subrange_representation()
	<< ") of "
	<<  e_type ? e_type->get_pretty_representation(internal):string("void");
    }
  else
    {
      if (internal)
	r = (e_type
	     ? get_type_name(e_type,
			     /*qualified=*/true,
			     /*internal=*/true)
	     : string("void"))
	  + a.get_subrange_representation();
      else
	r = (e_type
	     ? get_type_name(e_type, /*qualified=*/false, /*internal=*/false)
	     : string("void"))
	  + a.get_subrange_representation();
    }

  return r;
}

/// Get the pretty representation of the current instance of @ref
/// array_type_def.
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the pretty representation of the ABI artifact.
string
array_type_def::get_pretty_representation(bool internal,
					  bool /*qualified_name*/) const
{return get_type_representation(*this, internal);}

/// Compares two instances of @ref array_type_def.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const array_type_def& l, const array_type_def& r, change_kind* k)
{
  std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
  std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();

  bool result = true;
  if (this_subs.size() != other_subs.size())
    {
      result = false;
      if (k)
	*k |= LOCAL_TYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }

  std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
  for (i = this_subs.begin(), j = other_subs.begin();
       i != this_subs.end() && j != other_subs.end();
       ++i, ++j)
    if (**i != **j)
      {
	result = false;
	if (k)
	  {
	    *k |= LOCAL_TYPE_CHANGE_KIND;
	    break;
	  }
	else
	  ABG_RETURN_FALSE;
      }

  // Compare the element types modulo the typedefs they might have
  if (l.get_element_type() != r.get_element_type())
    {
      result = false;
      if (k)
	*k |= SUBTYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }

  ABG_RETURN(result);
}

/// Test if two variables are equals modulo CV qualifiers.
///
/// @param l the first array of the comparison.
///
/// @param r the second array of the comparison.
///
/// @return true iff @p l equals @p r or, if they are different, the
/// difference between the too is just a matter of CV qualifiers.
bool
equals_modulo_cv_qualifier(const array_type_def* l, const array_type_def* r)
{
  if (l == r)
    return true;

  if (!l || !r)
    ABG_RETURN_FALSE;

  l = is_array_type(peel_qualified_or_typedef_type(l));
  r = is_array_type(peel_qualified_or_typedef_type(r));

  std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
  std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();

  if (this_subs.size() != other_subs.size())
    ABG_RETURN_FALSE;

  std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
  for (i = this_subs.begin(), j = other_subs.begin();
       i != this_subs.end() && j != other_subs.end();
       ++i, ++j)
    if (**i != **j)
      ABG_RETURN_FALSE;

  type_base *first_element_type =
    peel_qualified_or_typedef_type(l->get_element_type().get());
  type_base *second_element_type =
    peel_qualified_or_typedef_type(r->get_element_type().get());

  if (*first_element_type != *second_element_type)
    ABG_RETURN_FALSE;

  return true;
}

/// Get the language of the array.
///
/// @return the language of the array.
translation_unit::language
array_type_def::get_language() const
{
  const std::vector<subrange_sptr>& subranges =
    get_subranges();

  if (subranges.empty())
    return translation_unit::LANG_C11;
  return subranges.front()->get_language();
}

bool
array_type_def::operator==(const decl_base& o) const
{
  const array_type_def* other =
    dynamic_cast<const array_type_def*>(&o);
  if (!other)
    return false;
  return try_canonical_compare(this, other);
}

bool
array_type_def::operator==(const type_base& o) const
{
  const decl_base* other = dynamic_cast<const decl_base*>(&o);
  if (!other)
    return false;
  return *this == *other;
}

/// Getter of the type of an array element.
///
/// @return the type of an array element.
const type_base_sptr
array_type_def::get_element_type() const
{return priv_->element_type_.lock();}

/// Setter of the type of array element.
///
/// Beware that after using this function, one might want to
/// re-compute the canonical type of the array, if one has already
/// been computed.
///
/// The intended use of this method is to permit in-place adjustment
/// of the element type's qualifiers. In particular, the size of the
/// element type should not be changed.
///
/// @param element_type the new element type to set.
void
array_type_def::set_element_type(const type_base_sptr& element_type)
{
  priv_->element_type_ = element_type;
  update_size();
  set_name(get_environment()->intern(get_pretty_representation()));
}

/// Append subranges from the vector @param subs to the current
/// vector of subranges.
void
array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
{

  for (const auto &sub : subs)
    priv_->subranges_.push_back(sub);

  update_size();
  set_name(get_environment()->intern(get_pretty_representation()));
}

/// @return true if one of the sub-ranges of the array is infinite, or
/// if the array has no sub-range at all, also meaning that the size
/// of the array is infinite.
bool
array_type_def::is_infinite() const
{
  if (priv_->subranges_.empty())
    return true;

  for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
	 priv_->subranges_.begin();
       i != priv_->subranges_.end();
       ++i)
    if ((*i)->is_infinite())
      return true;

  return false;
}

int
array_type_def::get_dimension_count() const
{return priv_->subranges_.size();}

/// Build and return the qualified name of the current instance of the
/// @ref array_type_def.
///
/// @param qn output parameter.  Is set to the newly-built qualified
/// name of the current instance of @ref array_type_def.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
void
array_type_def::get_qualified_name(interned_string& qn, bool internal) const
{qn = get_qualified_name(internal);}

/// Compute the qualified name of the array.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the resulting qualified name.
const interned_string&
array_type_def::get_qualified_name(bool internal) const
{
  const environment* env = get_environment();
  ABG_ASSERT(env);

  if (internal)
    {
      if (get_canonical_type())
	{
	  if (priv_->internal_qualified_name_.empty())
	    priv_->internal_qualified_name_ =
	      env->intern(get_type_representation(*this, /*internal=*/true));
	  return priv_->internal_qualified_name_;
	}
      else
	{
	  priv_->temp_internal_qualified_name_ =
	    env->intern(get_type_representation(*this, /*internal=*/true));
	  return priv_->temp_internal_qualified_name_;
	}
    }
  else
    {
      if (get_canonical_type())
	{
	  if (decl_base::peek_qualified_name().empty())
	    set_qualified_name(env->intern(get_type_representation
					   (*this, /*internal=*/false)));
	  return decl_base::peek_qualified_name();
	}
      else
	{
	  set_temporary_qualified_name(env->intern(get_type_representation
						   (*this,
						    /*internal=*/false)));
	  return decl_base::peek_temporary_qualified_name();
	}
    }
}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
array_type_def::traverse(ir_node_visitor& v)
{
  if (v.type_node_has_been_visited(this))
    return true;

  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      if (type_base_sptr t = get_element_type())
	t->traverse(v);
      visiting(false);
    }

  bool result = v.visit_end(this);
  v.mark_type_node_as_visited(this);
  return result;
}

const location&
array_type_def::get_location() const
{return decl_base::get_location();}

/// Get the array's subranges
const std::vector<array_type_def::subrange_sptr>&
array_type_def::get_subranges() const
{return priv_->subranges_;}

array_type_def::~array_type_def()
{}

// </array_type_def definitions>

// <enum_type_decl definitions>

class enum_type_decl::priv
{
  type_base_sptr	underlying_type_;
  enumerators		enumerators_;

  friend class enum_type_decl;

  priv();

public:
  priv(type_base_sptr underlying_type,
       enumerators& enumerators)
    : underlying_type_(underlying_type),
      enumerators_(enumerators)
  {}
}; // end class enum_type_decl::priv

/// Constructor.
///
/// @param name the name of the type declaration.
///
/// @param locus the source location where the type was defined.
///
/// @param underlying_type the underlying type of the enum.
///
/// @param enums the enumerators of this enum type.
///
/// @param linkage_name the linkage name of the enum.
///
/// @param vis the visibility of the enum type.
enum_type_decl::enum_type_decl(const string&	name,
			       const location&	locus,
			       type_base_sptr	underlying_type,
			       enumerators&	enums,
			       const string&	linkage_name,
			       visibility	vis)
  : type_or_decl_base(underlying_type->get_environment(),
		      ENUM_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    type_base(underlying_type->get_environment(),
	      underlying_type->get_size_in_bits(),
	      underlying_type->get_alignment_in_bits()),
    decl_base(underlying_type->get_environment(),
	      name, locus, linkage_name, vis),
    priv_(new priv(underlying_type, enums))
{
  runtime_type_instance(this);
  for (enumerators::iterator e = get_enumerators().begin();
       e != get_enumerators().end();
       ++e)
    e->set_enum_type(this);
}

/// Return the underlying type of the enum.
type_base_sptr
enum_type_decl::get_underlying_type() const
{return priv_->underlying_type_;}

/// @return the list of enumerators of the enum.
const enum_type_decl::enumerators&
enum_type_decl::get_enumerators() const
{return priv_->enumerators_;}

/// @return the list of enumerators of the enum.
enum_type_decl::enumerators&
enum_type_decl::get_enumerators()
{return priv_->enumerators_;}

/// Get the pretty representation of the current instance of @ref
/// enum_type_decl.
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.
///
/// @param qualified_name if true, names emitted in the pretty
/// representation are fully qualified.
///
/// @return the pretty representation of the enum type.
string
enum_type_decl::get_pretty_representation(bool internal,
					  bool qualified_name) const
{
  string r = "enum ";

  if (internal && get_is_anonymous())
    r += get_type_name(this, qualified_name, /*internal=*/true);
  else
    r += decl_base::get_pretty_representation(internal,
					      qualified_name);
  return r;
}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
enum_type_decl::traverse(ir_node_visitor &v)
{
  if (v.type_node_has_been_visited(this))
    return true;

  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      if (type_base_sptr t = get_underlying_type())
	t->traverse(v);
      visiting(false);
    }

  bool result = v.visit_end(this);
  v.mark_type_node_as_visited(this);
  return result;
}

/// Destructor for the enum type declaration.
enum_type_decl::~enum_type_decl()
{}

/// Test if two enums differ, but not by a name change.
///
/// @param l the first enum to consider.
///
/// @param r the second enum to consider.
///
/// @return true iff @p l differs from @p r by anything but a name
/// change.
bool
enum_has_non_name_change(const enum_type_decl& l,
			 const enum_type_decl& r,
			 change_kind* k)
{
  bool result = false;
  if (*l.get_underlying_type() != *r.get_underlying_type())
    {
      result = true;
      if (k)
	*k |= SUBTYPE_CHANGE_KIND;
      else
	return true;
    }

  enum_type_decl::enumerators::const_iterator i, j;
  for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
       i != l.get_enumerators().end() && j != r.get_enumerators().end();
       ++i, ++j)
    if (*i != *j)
      {
	result = true;
	if (k)
	  {
	    *k |= LOCAL_TYPE_CHANGE_KIND;
	    break;
	  }
	else
	  return true;
      }

  if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
    {
      result = true;
      if (k)
	*k |= LOCAL_TYPE_CHANGE_KIND;
      else
	return true;
    }

  enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
  interned_string qn_r = l.get_environment()->intern(r.get_qualified_name());
  interned_string qn_l = l.get_environment()->intern(l.get_qualified_name());
  string n_l = l.get_name();
  string n_r = r.get_name();
  local_r.set_qualified_name(qn_l);
  local_r.set_name(n_l);

  if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
    {
      result = true;
      if (k)
	{
	  if (!l.decl_base::operator==(r))
	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	  if (!l.type_base::operator==(r))
	    *k |= LOCAL_TYPE_CHANGE_KIND;
	}
      else
	{
	  local_r.set_name(n_r);
	  local_r.set_qualified_name(qn_r);
	  return true;
	}
    }
  local_r.set_qualified_name(qn_r);
  local_r.set_name(n_r);

  return result;
}

/// Test if a given enumerator is found present in an enum.
///
/// This is a subroutine of the equals function for enums.
///
/// @param enr the enumerator to consider.
///
/// @param enom the enum to consider.
///
/// @return true iff the enumerator @p enr is present in the enum @p
/// enom.
static bool
is_enumerator_present_in_enum(const enum_type_decl::enumerator &enr,
			      const enum_type_decl &enom)
{
  for (const auto &e : enom.get_enumerators())
    if (e == enr)
      return true;
  return false;
}

/// Check if two enumerators values are equal.
///
/// This function doesn't check if the names of the enumerators are
/// equal or not.
///
/// @param enr the first enumerator to consider.
///
/// @param enl the second enumerator to consider.
///
/// @return true iff @p enr has the same value as @p enl.
static bool
enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
			     const enum_type_decl::enumerator &enl)
{return enr.get_value() == enl.get_value();}

/// Detect if a given enumerator value is present in an enum.
///
/// This function looks inside the enumerators of a given enum and
/// detect if the enum contains at least one enumerator or a given
/// value.  The function also detects if the enumerator value we are
/// looking at is present in the enum with a different name.  An
/// enumerator with the same value but with a different name is named
/// a "redundant enumerator".  The function returns the set of
/// enumerators that are redundant with the value we are looking at.
///
/// @param enr the enumerator to consider.
///
/// @param enom the enum to consider.
///
/// @param redundant_enrs if the function returns true, then this
/// vector is filled with enumerators that are redundant with the
/// value of @p enr.
///
/// @return true iff the function detects that @p enom contains
/// enumerators with the same value as @p enr.
static bool
is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
				    const enum_type_decl &enom,
				    vector<enum_type_decl::enumerator>& redundant_enrs)
{
  bool found = false;
  for (const auto &e : enom.get_enumerators())
    if (enumerators_values_are_equal(e, enr))
      {
	found = true;
	if (e != enr)
	  redundant_enrs.push_back(e);
      }

  return found;
}

/// Check if an enumerator value is redundant in a given enum.
///
/// Given an enumerator value, this function detects if an enum
/// contains at least one enumerator with the the same value but with
/// a different name.
///
/// @param enr the enumerator to consider.
///
/// @param enom the enum to consider.
///
/// @return true iff @p enr is a redundant enumerator in enom.
static bool
is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
			      const enum_type_decl &enom)
{
  vector<enum_type_decl::enumerator> redundant_enrs;
  if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
    {
      if (!redundant_enrs.empty())
	return true;
    }
    return false;
}

/// Compares two instances of @ref enum_type_decl.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const enum_type_decl& l, const enum_type_decl& r, change_kind* k)
{
  bool result = true;
  if (*l.get_underlying_type() != *r.get_underlying_type())
    {
      result = false;
      if (k)
	*k |= SUBTYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }

  if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
    {
      result = false;
      if (k)
	{
	  if (!l.decl_base::operator==(r))
	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	  if (!l.type_base::operator==(r))
	    *k |= LOCAL_TYPE_CHANGE_KIND;
	}
      else
	ABG_RETURN_FALSE;
    }

  // Now compare the enumerators.  Note that the order of declaration
  // of enumerators should not matter in the comparison.
  //
  // Also if an enumerator value is redundant, that shouldn't impact
  // the comparison.
  //
  // In that case, note that the two enums below are considered equal:
  //
  // enum foo
  //     {
  //       e0 = 0;
  //       e1 = 1;
  //       e2 = 2;
  //     };
  //
  //     enum foo
  //     {
  //       e0 = 0;
  //       e1 = 1;
  //       e2 = 2;
  //       e_added = 1; // <-- this value is redundant with the value
  //                    //     of the enumerator e1.
  //     };
  //
  // These two enums are considered equal.

  for(const auto &e : l.get_enumerators())
    if (!is_enumerator_present_in_enum(e, r)
	&& !is_enumerator_value_redundant(e, r))
      {
	result = false;
	if (k)
	  {
	    *k |= LOCAL_TYPE_CHANGE_KIND;
	    break;
	  }
	else
	  ABG_RETURN_FALSE;
      }

  for(const auto &e : r.get_enumerators())
    if (!is_enumerator_present_in_enum(e, l)
	&& !is_enumerator_value_redundant(e, r))
      {
	result = false;
	if (k)
	  {
	    *k |= LOCAL_TYPE_CHANGE_KIND;
	    break;
	  }
	else
	  ABG_RETURN_FALSE;
      }

  ABG_RETURN(result);
}

/// Equality operator.
///
/// @param o the other enum to test against.
///
/// @return true iff @p o equals the current instance of enum type
/// decl.
bool
enum_type_decl::operator==(const decl_base& o) const
{
  const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
  if (!op)
    return false;
  return try_canonical_compare(this, op);
}

/// Equality operator.
///
/// @param o the other enum to test against.
///
/// @return true iff @p o is equals the current instance of enum type
/// decl.
bool
enum_type_decl::operator==(const type_base& o) const
{
  const decl_base* other = dynamic_cast<const decl_base*>(&o);
  if (!other)
    return false;
  return *this == *other;
}

/// Equality operator for @ref enum_type_decl_sptr.
///
/// @param l the first operand to compare.
///
/// @param r the second operand to compare.
///
/// @return true iff @p l equals @p r.
bool
operator==(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
{
  if (!!l != !!r)
    return false;
  if (l.get() == r.get())
    return true;
  decl_base_sptr o = r;
  return *l == *o;
}

/// Inequality operator for @ref enum_type_decl_sptr.
///
/// @param l the first operand to compare.
///
/// @param r the second operand to compare.
///
/// @return true iff @p l equals @p r.
bool
operator!=(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
{return !operator==(l, r);}

/// The type of the private data of an @ref
/// enum_type_decl::enumerator.
class enum_type_decl::enumerator::priv
{
  const environment*	env_;
  interned_string	name_;
  int64_t		value_;
  interned_string	qualified_name_;
  enum_type_decl*	enum_type_;

  friend class	enum_type_decl::enumerator;

public:

  priv()
    : env_(),
      enum_type_()
  {}

  priv(const environment* env,
       const string& name,
       int64_t value,
       enum_type_decl* e = 0)
    : env_(env),
      name_(env ? env->intern(name) : interned_string()),
      value_(value),
      enum_type_(e)
  {}
}; // end class enum_type_def::enumerator::priv

/// Default constructor of the @ref enum_type_decl::enumerator type.
enum_type_decl::enumerator::enumerator()
  : priv_(new priv)
{}

enum_type_decl::enumerator::~enumerator() = default;


/// Constructor of the @ref enum_type_decl::enumerator type.
///
/// @param env the environment we are operating from.
///
/// @param name the name of the enumerator.
///
/// @param value the value of the enumerator.
enum_type_decl::enumerator::enumerator(const environment* env,
				       const string& name,
				       int64_t value)
  : priv_(new priv(env, name, value))
{}

/// Copy constructor of the @ref enum_type_decl::enumerator type.
///
/// @param other enumerator to copy.
enum_type_decl::enumerator::enumerator(const enumerator& other)
  : priv_(new priv(other.get_environment(),
		   other.get_name(),
		   other.get_value(),
		   other.get_enum_type()))
{}

/// Assignment operator of the @ref enum_type_decl::enumerator type.
///
/// @param o
enum_type_decl::enumerator&
enum_type_decl::enumerator::operator=(const enumerator& o)
{
  priv_->env_ = o.get_environment();
  priv_->name_ = o.get_name();
  priv_->value_ = o.get_value();
  priv_->enum_type_ = o.get_enum_type();
  return *this;
}
/// Equality operator
///
/// @param other the enumerator to compare to the current
/// instance of enum_type_decl::enumerator.
///
/// @return true if @p other equals the current instance of
/// enum_type_decl::enumerator.
bool
enum_type_decl::enumerator::operator==(const enumerator& other) const
{
  bool names_equal = true;
  names_equal = (get_name() == other.get_name());
  return names_equal && (get_value() == other.get_value());
}

/// Inequality operator.
///
/// @param other the other instance to compare against.
///
/// @return true iff @p other is different from the current instance.
bool
enum_type_decl::enumerator::operator!=(const enumerator& other) const
{return !operator==(other);}

/// Getter of the environment of this enumerator.
///
/// @return the environment of this enumerator.
const environment*
enum_type_decl::enumerator::get_environment() const
{return priv_->env_;}

/// Getter for the name of the current instance of
/// enum_type_decl::enumerator.
///
/// @return a reference to the name of the current instance of
/// enum_type_decl::enumerator.
const interned_string&
enum_type_decl::enumerator::get_name() const
{return priv_->name_;}

/// Getter for the qualified name of the current instance of
/// enum_type_decl::enumerator.  The first invocation of the method
/// builds the qualified name, caches it and return a reference to the
/// cached qualified name.  Subsequent invocations just return the
/// cached value.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @return the qualified name of the current instance of
/// enum_type_decl::enumerator.
const interned_string&
enum_type_decl::enumerator::get_qualified_name(bool internal) const
{
  if (priv_->qualified_name_.empty())
    {
      const environment* env = priv_->enum_type_->get_environment();
      ABG_ASSERT(env);
      priv_->qualified_name_ =
	env->intern(get_enum_type()->get_qualified_name(internal)
		    + "::"
		    + get_name());
    }
  return priv_->qualified_name_;
}

/// Setter for the name of @ref enum_type_decl::enumerator.
///
/// @param n the new name.
void
enum_type_decl::enumerator::set_name(const string& n)
{
  const environment* env = get_environment();
  ABG_ASSERT(env);
  priv_->name_ = env->intern(n);
}

/// Getter for the value of @ref enum_type_decl::enumerator.
///
/// @return the value of the current instance of
/// enum_type_decl::enumerator.
int64_t
enum_type_decl::enumerator::get_value() const
{return priv_->value_;}

/// Setter for the value of @ref enum_type_decl::enumerator.
///
/// @param v the new value of the enum_type_decl::enumerator.
void
enum_type_decl::enumerator::set_value(int64_t v)
{priv_->value_= v;}

/// Getter for the enum type that this enumerator is for.
///
/// @return the enum type that this enumerator is for.
enum_type_decl*
enum_type_decl::enumerator::get_enum_type() const
{return priv_->enum_type_;}

/// Setter for the enum type that this enumerator is for.
///
/// @param e the new enum type.
void
enum_type_decl::enumerator::set_enum_type(enum_type_decl* e)
{priv_->enum_type_ = e;}
// </enum_type_decl definitions>

// <typedef_decl definitions>

/// Private data structure of the @ref typedef_decl.
struct typedef_decl::priv
{
  type_base_wptr	underlying_type_;
  string		internal_qualified_name_;
  string		temp_internal_qualified_name_;

  priv(const type_base_sptr& t)
    : underlying_type_(t)
  {}
}; // end struct typedef_decl::priv

/// Constructor of the typedef_decl type.
///
/// @param name the name of the typedef.
///
/// @param underlying_type the underlying type of the typedef.
///
/// @param locus the source location of the typedef declaration.
///
/// @param linkage_name the mangled name of the typedef.
///
/// @param vis the visibility of the typedef type.
typedef_decl::typedef_decl(const string&		name,
			   const type_base_sptr	underlying_type,
			   const location&		locus,
			   const string&		linkage_name,
			   visibility vis)
  : type_or_decl_base(underlying_type->get_environment(),
		      TYPEDEF_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    type_base(underlying_type->get_environment(),
	      underlying_type->get_size_in_bits(),
	      underlying_type->get_alignment_in_bits()),
    decl_base(underlying_type->get_environment(),
	      name, locus, linkage_name, vis),
    priv_(new priv(underlying_type))
{
  runtime_type_instance(this);
}

/// Constructor of the typedef_decl type.
///
/// @param name the name of the typedef.
///
/// @param env the environment of the current typedef.
///
/// @param locus the source location of the typedef declaration.
///
/// @param mangled_name the mangled name of the typedef.
///
/// @param vis the visibility of the typedef type.
typedef_decl::typedef_decl(const string& name,
			   environment* env,
			   const location& locus,
			   const string& mangled_name,
			   visibility vis)
  : type_or_decl_base(env,
		      TYPEDEF_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    type_base(env, /*size_in_bits=*/0,
	      /*alignment_in_bits=*/0),
    decl_base(env, name, locus, mangled_name, vis),
    priv_(new priv(nullptr))
{
  runtime_type_instance(this);
}

/// Return the size of the typedef.
///
/// This function looks at the size of the underlying type and ensures
/// that it's the same as the size of the typedef.
///
/// @return the size of the typedef.
size_t
typedef_decl::get_size_in_bits() const
{
  if (!get_underlying_type())
    return 0;
  size_t s = get_underlying_type()->get_size_in_bits();
  if (s != type_base::get_size_in_bits())
    const_cast<typedef_decl*>(this)->set_size_in_bits(s);
  return type_base::get_size_in_bits();
}

/// Return the alignment of the typedef.
///
/// This function looks at the alignment of the underlying type and
/// ensures that it's the same as the alignment of the typedef.
///
/// @return the size of the typedef.
size_t
typedef_decl::get_alignment_in_bits() const
{
  if (!get_underlying_type())
    return 0;
  size_t s = get_underlying_type()->get_alignment_in_bits();
  if (s != type_base::get_alignment_in_bits())
    const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
  return type_base::get_alignment_in_bits();
}

/// Compares two instances of @ref typedef_decl.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const typedef_decl& l, const typedef_decl& r, change_kind* k)
{
  bool result = true;
  if (!equals(static_cast<const decl_base&>(l),
	      static_cast<const decl_base&>(r),
	      k))
    {
      result = false;
      if (k)
	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }

  if (*l.get_underlying_type() != *r.get_underlying_type())
    {
      // Changes to the underlying type of a typedef are considered
      // local, a bit like for pointers.
      result = false;
      if (k)
	*k |= LOCAL_TYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }

  ABG_RETURN(result);
}

/// Equality operator
///
/// @param o the other typedef_decl to test against.
bool
typedef_decl::operator==(const decl_base& o) const
{
  const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
  if (!other)
    return false;
  return try_canonical_compare(this, other);
}

/// Equality operator
///
/// @param o the other typedef_decl to test against.
///
/// @return true if the current instance of @ref typedef_decl equals
/// @p o.
bool
typedef_decl::operator==(const type_base& o) const
{
  const decl_base* other = dynamic_cast<const decl_base*>(&o);
  if (!other)
    return false;
  return *this == *other;
}

/// Build a pretty representation for a typedef_decl.
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.

/// @param qualified_name if true, names emitted in the pretty
/// representation are fully qualified.
///
/// @return a copy of the pretty representation of the current
/// instance of typedef_decl.
string
typedef_decl::get_pretty_representation(bool internal,
					bool qualified_name) const
{

  string result = "typedef ";
  if (qualified_name)
    result += get_qualified_name(internal);
  else
    result += get_name();

  return result;
}

/// Getter of the underlying type of the typedef.
///
/// @return the underlying_type.
type_base_sptr
typedef_decl::get_underlying_type() const
{return priv_->underlying_type_.lock();}

/// Setter ofthe underlying type of the typedef.
///
/// @param t the new underlying type of the typedef.
void
typedef_decl::set_underlying_type(const type_base_sptr& t)
{
  priv_->underlying_type_ = t;
  set_size_in_bits(t->get_size_in_bits());
  set_alignment_in_bits(t->get_alignment_in_bits());
}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
typedef_decl::traverse(ir_node_visitor& v)
{
  if (v.type_node_has_been_visited(this))
    return true;

  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      if (type_base_sptr t = get_underlying_type())
	t->traverse(v);
      visiting(false);
    }

  bool result = v.visit_end(this);
  v.mark_type_node_as_visited(this);
  return result;
}

typedef_decl::~typedef_decl()
{}
// </typedef_decl definitions>

// <var_decl definitions>

struct var_decl::priv
{
  type_base_wptr	type_;
  type_base*		naked_type_;
  decl_base::binding	binding_;
  elf_symbol_sptr	symbol_;
  interned_string	id_;

  priv()
    : naked_type_(),
    binding_(decl_base::BINDING_GLOBAL)
  {}

  priv(type_base_sptr t,
       decl_base::binding b)
    : type_(t),
      naked_type_(t.get()),
      binding_(b)
  {}
}; // end struct var_decl::priv

/// Constructor of the @ref var_decl type.
///
/// @param name the name of the variable declaration
///
/// @param type the type of the variable declaration
///
/// @param locus the source location where the variable was defined.
///
/// @param linkage_name the linkage name of the variable.
///
/// @param vis the visibility of of the variable.
///
/// @param bind the binding kind of the variable.
var_decl::var_decl(const string&	name,
		   type_base_sptr	type,
		   const location&	locus,
		   const string&	linkage_name,
		   visibility		vis,
		   binding		bind)
  : type_or_decl_base(type->get_environment(),
		      VAR_DECL | ABSTRACT_DECL_BASE),
    decl_base(type->get_environment(), name, locus, linkage_name, vis),
    priv_(new priv(type, bind))
{
  runtime_type_instance(this);
}

/// Getter of the type of the variable.
///
/// @return the type of the variable.
const type_base_sptr
var_decl::get_type() const
{return priv_->type_.lock();}

/// Getter of the type of the variable.
///
/// This getter returns a bare pointer, as opposed to a smart pointer.
/// It's to be used on performance sensitive code paths identified by
/// careful profiling.
///
/// @return the type of the variable, as a bare pointer.
const type_base*
var_decl::get_naked_type() const
{return priv_->naked_type_;}

/// Getter of the binding of the variable.
///
/// @return the biding of the variable.
decl_base::binding
var_decl::get_binding() const
{return priv_->binding_;}

/// Setter of the binding of the variable.
///
/// @param b the new binding value.
void
var_decl::set_binding(decl_base::binding b)
{priv_->binding_ = b;}

/// Sets the underlying ELF symbol for the current variable.
///
/// And underlyin$g ELF symbol for the current variable might exist
/// only if the corpus that this variable originates from was
/// constructed from an ELF binary file.
///
/// Note that comparing two variables that have underlying ELF symbols
/// involves comparing their underlying elf symbols.  The decl name
/// for the variable thus becomes irrelevant in the comparison.
///
/// @param sym the new ELF symbol for this variable decl.
void
var_decl::set_symbol(const elf_symbol_sptr& sym)
{
  priv_->symbol_ = sym;
  // The variable id cache that depends on the symbol must be
  // invalidated because the symbol changed.
  priv_->id_ = get_environment()->intern("");
}

/// Gets the the underlying ELF symbol for the current variable,
/// that was set using var_decl::set_symbol().  Please read the
/// documentation for that member function for more information about
/// "underlying ELF symbols".
///
/// @return sym the underlying ELF symbol for this variable decl, if
/// one exists.
const elf_symbol_sptr&
var_decl::get_symbol() const
{return priv_->symbol_;}

/// Create a new var_decl that is a clone of the current one.
///
/// @return the cloned var_decl.
var_decl_sptr
var_decl::clone() const
{
  var_decl_sptr v(new var_decl(get_name(),
			       get_type(),
			       get_location(),
			       get_linkage_name(),
			       get_visibility(),
			       get_binding()));

  v->set_symbol(get_symbol());

  if (is_member_decl(*this))
    {
      class_decl* scope = dynamic_cast<class_decl*>(get_scope());
      scope->add_data_member(v, get_member_access_specifier(*this),
			     get_data_member_is_laid_out(*this),
			     get_member_is_static(*this),
			     get_data_member_offset(*this));
    }
  else
    add_decl_to_scope(v, get_scope());

  return v;
}
/// Setter of the scope of the current var_decl.
///
/// Note that the decl won't hold a reference on the scope.  It's
/// rather the scope that holds a reference on its members.
///
/// @param scope the new scope.
void
var_decl::set_scope(scope_decl* scope)
{
  if (!get_context_rel())
    set_context_rel(new dm_context_rel(scope));
  else
    get_context_rel()->set_scope(scope);
}

/// Compares two instances of @ref var_decl.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const var_decl& l, const var_decl& r, change_kind* k)
{
  bool result = true;

  // First test types of variables.  This should be fast because in
  // the general case, most types should be canonicalized.
  if (*l.get_naked_type() != *r.get_naked_type())
    {
      result = false;
      if (k)
	{
	  if (!types_have_similar_structure(l.get_naked_type(),
					    r.get_naked_type()))
	    *k |= (LOCAL_TYPE_CHANGE_KIND);
	  else
	    *k |= SUBTYPE_CHANGE_KIND;
	}
      else
	ABG_RETURN_FALSE;
    }

  // If there are underlying elf symbols for these variables,
  // compare them.  And then compare the other parts.
  const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
  if (!!s0 != !!s1)
    {
      result = false;
      if (k)
	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }
  else if (s0 && s0 != s1)
    {
      result = false;
      if (k)
	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }
  bool symbols_are_equal = (s0 && s1 && result);

  if (symbols_are_equal)
    {
      // The variables have underlying elf symbols that are equal, so
      // now, let's compare the decl_base part of the variables w/o
      // considering their decl names.
      const environment* env = l.get_environment();
      const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
      const_cast<var_decl&>(l).set_qualified_name(env->intern(""));
      const_cast<var_decl&>(r).set_qualified_name(env->intern(""));
      bool decl_bases_different = !l.decl_base::operator==(r);
      const_cast<var_decl&>(l).set_qualified_name(n1);
      const_cast<var_decl&>(r).set_qualified_name(n2);

      if (decl_bases_different)
	{
	  result = false;
	  if (k)
	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	  else
	    ABG_RETURN_FALSE;
	}
    }
  else
    if (!l.decl_base::operator==(r))
      {
	result = false;
	if (k)
	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	else
	  ABG_RETURN_FALSE;
      }

  const dm_context_rel* c0 =
    dynamic_cast<const dm_context_rel*>(l.get_context_rel());
  const dm_context_rel* c1 =
    dynamic_cast<const dm_context_rel*>(r.get_context_rel());
  ABG_ASSERT(c0 && c1);

  if (*c0 != *c1)
    {
      result = false;
      if (k)
	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }

  ABG_RETURN(result);
}

/// Comparison operator of @ref var_decl.
///
/// @param o the instance of @ref var_decl to compare against.
///
/// @return true iff the current instance of @ref var_decl equals @p o.
bool
var_decl::operator==(const decl_base& o) const
{
  const var_decl* other = dynamic_cast<const var_decl*>(&o);
  if (!other)
    return false;

  return equals(*this, *other, 0);
}

/// Return an ID that tries to uniquely identify the variable inside a
/// program or a library.
///
/// So if the variable has an underlying elf symbol, the ID is the
/// concatenation of the symbol name and its version.  Otherwise, the
/// ID is the linkage name if its non-null.  Otherwise, it's the
/// pretty representation of the variable.
///
/// @return the ID.
interned_string
var_decl::get_id() const
{
  if (priv_->id_.empty())
    {
      string repr = get_name();
      string sym_str;
      if (elf_symbol_sptr s = get_symbol())
	sym_str = s->get_id_string();
      else if (!get_linkage_name().empty())
	sym_str = get_linkage_name();
      const environment* env = get_type()->get_environment();
      ABG_ASSERT(env);
      priv_->id_ = env->intern(repr);
      if (!sym_str.empty())
	priv_->id_ = env->intern(priv_->id_ + "{" + sym_str + "}");
    }
  return priv_->id_;
}

/// Return the hash value for the current instance.
///
/// @return the hash value.
size_t
var_decl::get_hash() const
{
  var_decl::hash hash_var;
  return hash_var(this);
}

/// Get the qualified name of a given variable or data member.
///
///
/// Note that if the current instance of @ref var_decl is an anonymous
/// data member, then the qualified name is actually the flat
/// representation (the definition) of the type of the anonymous data
/// member.  We chose the flat representation because otherwise, the
/// name of an *anonymous* data member is empty, by construction, e.g:
///
///   struct foo {
///     int a;
///     union {
///       char b;
///       char c;
///     }; // <---- this data member is anonymous.
///     int d;
///   }
///
///   The string returned for the anonymous member here is going to be:
///
///     "union {char b; char c}"
///
/// @param internal if true then this is for a purpose to the library,
/// otherwise, it's for being displayed to users.
///
/// @return the resulting qualified name.
const interned_string&
var_decl::get_qualified_name(bool internal) const
{
  if (is_anonymous_data_member(this)
      && decl_base::get_qualified_name().empty())
    {
      // Display the anonymous data member in a way that makes sense.
      string r = get_pretty_representation(internal);
      set_qualified_name(get_environment()->intern(r));
    }

  return decl_base::get_qualified_name(internal);
}

/// Build and return the pretty representation of this variable.
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.
///
/// @param qualified_name if true, names emitted in the pretty
/// representation are fully qualified.
///
/// @return a copy of the pretty representation of this variable.
string
var_decl::get_pretty_representation(bool internal, bool qualified_name) const
{
  string result;

  if (is_member_decl(this) && get_member_is_static(this))
    result = "static ";

  // Detect if the current instance of var_decl is a member of
  // an anonymous class or union.
  bool member_of_anonymous_class = false;
  if (class_or_union* scope = is_at_class_scope(this))
    if (scope->get_is_anonymous())
      member_of_anonymous_class = true;

  if (array_type_def_sptr t = is_array_type(get_type()))
    {
      string name;
      if (member_of_anonymous_class || !qualified_name)
	name = get_name();
      else
	name = get_qualified_name(internal);

      type_base_sptr et = t->get_element_type();
      ABG_ASSERT(et);
      decl_base_sptr decl = get_type_declaration(et);
      ABG_ASSERT(decl);
      result += decl->get_qualified_name(internal)
	+ " " + name + t->get_subrange_representation();
    }
  else
    {
      if (/*The current var_decl is to be used as an anonymous data
	    member.  */
	  get_name().empty())
	{
	  // Display the anonymous data member in a way that
	  // makes sense.
	  result +=
	    get_class_or_union_flat_representation
	    (is_class_or_union_type(get_type()),
	     "", /*one_line=*/true, internal);
	}
      else if (data_member_has_anonymous_type(this))
	{
	  result += get_class_or_union_flat_representation
	    (is_class_or_union_type(get_type()),
	     "", /*one_line=*/true, internal);
	  result += " ";
	  if (member_of_anonymous_class || !qualified_name)
	    // It doesn't make sense to name the member of an
	    // anonymous class or union like:
	    // "__anonymous__::data_member_name".  So let's just use
	    // its non-qualified name.
	    result += get_name();
	  else
	    result += get_qualified_name(internal);
	}
      else
	{
	  result +=
	    get_type_declaration(get_type())->get_qualified_name(internal)
	    + " ";

	  if (member_of_anonymous_class || !qualified_name)
	    // It doesn't make sense to name the member of an
	    // anonymous class or union like:
	    // "__anonymous__::data_member_name".  So let's just use
	    // its non-qualified name.
	    result += get_name();
	  else
	    result += get_qualified_name(internal);
	}
    }
  return result;
}

/// Get a name that is valid even for an anonymous data member.
///
/// If the current @ref var_decl is an anonymous data member, then
/// return its pretty representation. As of now, that pretty
/// representation is actually its flat representation as returned by
/// get_class_or_union_flat_representation().
///
/// Otherwise, just return the name of the current @ref var_decl.
///
/// @param qualified if true, return the qualified name.  This doesn't
/// have an effet if the current @ref var_decl represents an anonymous
/// data member.
string
var_decl::get_anon_dm_reliable_name(bool qualified) const
{
  string name;
  if (is_anonymous_data_member(this))
    // This function is used in the comparison engine to determine
    // which anonymous data member was deleted.  So it's not involved
    // in type comparison or canonicalization.  We don't want to use
    // the 'internal' version of the pretty presentation.
    name = get_pretty_representation(/*internal=*/false, qualified);
  else
    name = get_name();

  return name;
}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
var_decl::traverse(ir_node_visitor& v)
{
  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      if (type_base_sptr t = get_type())
	t->traverse(v);
      visiting(false);
    }
  return v.visit_end(this);
}

var_decl::~var_decl()
{}

// </var_decl definitions>

// <function_type>

/// The type of the private data of the @ref function_type type.
struct function_type::priv
{
  parameters parms_;
  type_base_wptr return_type_;
  interned_string cached_name_;
  interned_string internal_cached_name_;
  interned_string temp_internal_cached_name_;

  priv()
  {}

  priv(const parameters&	parms,
       type_base_sptr		return_type)
    : parms_(parms),
      return_type_(return_type)
  {}

  priv(type_base_sptr return_type)
    : return_type_(return_type)
  {}

  /// Mark a given @ref function_type as being compared.
  ///
  /// @param type the @ref function_type to mark as being compared.
  void
  mark_as_being_compared(const function_type& type) const
  {
    const environment* env = type.get_environment();
    ABG_ASSERT(env);
    env->priv_->fn_types_being_compared_.insert(&type);
  }

  /// If a given @ref function_type was marked as being compared, this
  /// function unmarks it.
  ///
  /// @param type the @ref function_type to mark as *NOT* being
  /// compared.
  void
  unmark_as_being_compared(const function_type& type) const
  {
    const environment* env = type.get_environment();
    ABG_ASSERT(env);
    env->priv_->fn_types_being_compared_.erase(&type);
  }

  /// Tests if a @ref function_type is currently being compared.
  ///
  /// @param type the function type to take into account.
  ///
  /// @return true if @p type is being compared.
  bool
  comparison_started(const function_type& type) const
  {
    const environment* env = type.get_environment();
    ABG_ASSERT(env);
    return env->priv_->fn_types_being_compared_.count(&type);
  }
};// end struc function_type::priv

/// This function is automatically invoked whenever an instance of
/// this type is canonicalized.
///
/// It's an overload of the virtual type_base::on_canonical_type_set.
///
/// We put here what is thus meant to be executed only at the point of
/// type canonicalization.
void
function_type::on_canonical_type_set()
{
  priv_->cached_name_.clear();
  priv_->internal_cached_name_.clear();
}

/// The most straightforward constructor for the function_type class.
///
/// @param return_type the return type of the function type.
///
/// @param parms the list of parameters of the function type.
/// Stricto sensu, we just need a list of types; we are using a list
/// of parameters (where each parameter also carries the name of the
/// parameter and its source location) to try and provide better
/// diagnostics whenever it makes sense.  If it appears that this
/// wasts too many resources, we can fall back to taking just a
/// vector of types here.
///
/// @param size_in_bits the size of this type, in bits.
///
/// @param alignment_in_bits the alignment of this type, in bits.
///
/// @param size_in_bits the size of this type.
function_type::function_type(type_base_sptr	return_type,
			     const parameters&	parms,
			     size_t		size_in_bits,
			     size_t		alignment_in_bits)
  : type_or_decl_base(return_type->get_environment(),
		      FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
    type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
    priv_(new priv(parms, return_type))
{
  runtime_type_instance(this);

  for (parameters::size_type i = 0, j = 1;
       i < priv_->parms_.size();
       ++i, ++j)
    {
      if (i == 0 && priv_->parms_[i]->get_is_artificial())
	// If the first parameter is artificial, then it certainly
	// means that this is a member function, and the first
	// parameter is the implicit this pointer.  In that case, set
	// the index of that implicit parameter to zero.  Otherwise,
	// the index of the first parameter starts at one.
	j = 0;
      priv_->parms_[i]->set_index(j);
    }
}

/// A constructor for a function_type that takes no parameters.
///
/// @param return_type the return type of this function_type.
///
/// @param size_in_bits the size of this type, in bits.
///
/// @param alignment_in_bits the alignment of this type, in bits.
function_type::function_type(type_base_sptr return_type,
			     size_t size_in_bits, size_t alignment_in_bits)
  : type_or_decl_base(return_type->get_environment(),
		      FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
    type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
    priv_(new priv(return_type))
{
  runtime_type_instance(this);
}

/// A constructor for a function_type that takes no parameter and
/// that has no return_type yet.  These missing parts can (and must)
/// be added later.
///
/// @param env the environment we are operating from.
///
/// @param size_in_bits the size of this type, in bits.
///
/// @param alignment_in_bits the alignment of this type, in bits.
function_type::function_type(const environment* env,
			     size_t		size_in_bits,
			     size_t		alignment_in_bits)
  : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
    type_base(env, size_in_bits, alignment_in_bits),
    priv_(new priv)
{
  runtime_type_instance(this);
}

/// Getter for the return type of the current instance of @ref
/// function_type.
///
/// @return the return type.
type_base_sptr
function_type::get_return_type() const
{return priv_->return_type_.lock();}

/// Setter of the return type of the current instance of @ref
/// function_type.
///
/// @param t the new return type to set.
void
function_type::set_return_type(type_base_sptr t)
{priv_->return_type_ = t;}

/// Getter for the set of parameters of the current intance of @ref
/// function_type.
///
/// @return the parameters of the current instance of @ref
/// function_type.
const function_decl::parameters&
function_type::get_parameters() const
{return priv_->parms_;}

/// Get the Ith parameter of the vector of parameters of the current
/// instance of @ref function_type.
///
/// Note that the first parameter is at index 0.  That parameter is
/// the first parameter that comes after the possible implicit "this"
/// parameter, when the current instance @ref function_type is for a
/// member function.  Otherwise, if the current instance of @ref
/// function_type is for a non-member function, the parameter at index
/// 0 is the first parameter of the function.
///
///
/// @param i the index of the parameter to return.  If i is greater
/// than the index of the last parameter, then this function returns
/// an empty parameter (smart) pointer.
///
/// @return the @p i th parameter that is not implicit.
const function_decl::parameter_sptr
function_type::get_parm_at_index_from_first_non_implicit_parm(size_t i) const
{
  parameter_sptr result;
  if (dynamic_cast<const method_type*>(this))
    {
      if (i + 1 < get_parameters().size())
	result = get_parameters()[i + 1];
    }
  else
    {
      if (i < get_parameters().size())
	result = get_parameters()[i];
    }
  return result;
}

/// Setter for the parameters of the current instance of @ref
/// function_type.
///
/// @param p the new vector of parameters to set.
void
function_type::set_parameters(const parameters &p)
{
  priv_->parms_ = p;
  for (parameters::size_type i = 0, j = 1;
       i < priv_->parms_.size();
       ++i, ++j)
    {
      if (i == 0 && priv_->parms_[i]->get_is_artificial())
	// If the first parameter is artificial, then it certainly
	// means that this is a member function, and the first
	// parameter is the implicit this pointer.  In that case, set
	// the index of that implicit parameter to zero.  Otherwise,
	// the index of the first parameter starts at one.
	j = 0;
      priv_->parms_[i]->set_index(j);
    }
}

/// Append a new parameter to the vector of parameters of the current
/// instance of @ref function_type.
///
/// @param parm the parameter to append.
void
function_type::append_parameter(parameter_sptr parm)
{
  parm->set_index(priv_->parms_.size());
  priv_->parms_.push_back(parm);
}

/// Test if the current instance of @ref function_type is for a
/// variadic function.
///
/// A variadic function is a function that takes a variable number of
/// arguments.
///
/// @return true iff the current instance of @ref function_type is for
/// a variadic function.
bool
function_type::is_variadic() const
{
  return (!priv_->parms_.empty()
	 && priv_->parms_.back()->get_variadic_marker());
}

/// Compare two function types.
///
/// In case these function types are actually method types, this
/// function avoids comparing two parameters (of the function types)
/// if the types of the parameters are actually the types of the
/// classes of the method types.  This prevents infinite recursion
/// during the comparison of two classes that are structurally
/// identical.
///
/// This is a subroutine of the equality operator of function_type.
///
/// @param lhs the first function type to consider
///
/// @param rhs the second function type to consider
///
/// @param k a pointer to a bitfield set by the function to give
/// information about the kind of changes carried by @p lhs and @p
/// rhs.  It is set iff @p k is non-null and the function returns
/// false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
///@return true if lhs == rhs, false otherwise.
bool
equals(const function_type& l,
       const function_type& r,
       change_kind* k)
{
#define RETURN(value) return return_comparison_result(l, r, value)

  RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
  mark_types_as_being_compared(l, r);

  bool result = true;

  if (!l.type_base::operator==(r))
    {
      result = false;
      if (k)
	*k |= LOCAL_TYPE_CHANGE_KIND;
      else
	RETURN(result);
    }

  class_or_union* l_class = 0, *r_class = 0;
  if (const method_type* m = dynamic_cast<const method_type*>(&l))
    l_class = m->get_class_type().get();

  if (const method_type* m = dynamic_cast<const method_type*>(&r))
    r_class = m->get_class_type().get();

  // Compare the names of the class of the method

  if (!!l_class != !!r_class)
    {
      result = false;
      if (k)
	*k |= LOCAL_TYPE_CHANGE_KIND;
      else
	RETURN(result);
    }
  else if (l_class
	   && (l_class->get_qualified_name()
	       != r_class->get_qualified_name()))
    {
      result = false;
      if (k)
	*k |= LOCAL_TYPE_CHANGE_KIND;
      else
	RETURN(result);
    }

  // Then compare the return type; Beware if it's t's a class type
  // that is the same as the method class name; we can recurse for
  // ever in that case.

  decl_base* l_return_type_decl =
    get_type_declaration(l.get_return_type()).get();
  decl_base* r_return_type_decl =
    get_type_declaration(r.get_return_type()).get();
  bool compare_result_types = true;
  string l_rt_name = l_return_type_decl
    ? l_return_type_decl->get_qualified_name()
    : string();
  string r_rt_name = r_return_type_decl
    ? r_return_type_decl->get_qualified_name()
    : string();

  if ((l_class && (l_class->get_qualified_name() == l_rt_name))
      ||
      (r_class && (r_class->get_qualified_name() == r_rt_name)))
    compare_result_types = false;

  if (compare_result_types)
    {
      if (l.get_return_type() != r.get_return_type())
	{
	  result = false;
	  if (k)
	    {
	      if (!types_have_similar_structure(l.get_return_type(),
						r.get_return_type()))
		*k |= LOCAL_TYPE_CHANGE_KIND;
	      else
		*k |= SUBTYPE_CHANGE_KIND;
	    }
	  else
	    RETURN(result);
	}
    }
  else
    if (l_rt_name != r_rt_name)
      {
	result = false;
	if (k)
	  *k |= SUBTYPE_CHANGE_KIND;
	else
	  RETURN(result);
      }

  vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
  for (i = l.get_first_parm(), j = r.get_first_parm();
       i != l.get_parameters().end() && j != r.get_parameters().end();
       ++i, ++j)
    {
      if (**i != **j)
	{
	  result = false;
	  if (k)
	    {
	      if (!types_have_similar_structure((*i)->get_type(),
						(*j)->get_type()))
		*k |= LOCAL_TYPE_CHANGE_KIND;
	      else
		*k |= SUBTYPE_CHANGE_KIND;
	    }
	  else
	    RETURN(result);
	}
    }

  if ((i != l.get_parameters().end()
       || j != r.get_parameters().end()))
    {
      result = false;
      if (k)
	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
      else
	RETURN(result);
    }

  RETURN(result);
#undef RETURN
}

/// Get the first parameter of the function.
///
/// If the function is a non-static member function, the parameter
/// returned is the first one following the implicit 'this' parameter.
///
/// @return the first non implicit parameter of the function.
function_type::parameters::const_iterator
function_type::get_first_non_implicit_parm() const
{
  if (get_parameters().empty())
    return get_parameters().end();

  bool is_method = dynamic_cast<const method_type*>(this);

  parameters::const_iterator i = get_parameters().begin();

  if (is_method)
    ++i;

  return i;
}

/// Get the first parameter of the function.
///
/// Note that if the function is a non-static member function, the
/// parameter returned is the implicit 'this' parameter.
///
/// @return the first parameter of the function.
function_type::parameters::const_iterator
function_type::get_first_parm() const
{return get_parameters().begin();}

/// Get the name of the current @ref function_type.
///
/// The name is retrieved from a cache.  If the cache is empty, this
/// function computes the name of the type, stores it in the cache and
/// returns it.  Subsequent invocation of the function are going to
/// just hit the cache.
///
/// Note that if the type is *NOT* canonicalized then function type
/// name is never cached.
///
/// @param internal if true then it means the function type name is
/// going to be used for purposes that are internal to libabigail
/// itself.  If you don't know what this is then you probably should
/// set this parameter to 'false'.
///
/// @return the name of the function type.
const interned_string&
function_type::get_cached_name(bool internal) const
{
  if (internal)
    {
      if (get_naked_canonical_type())
	{
	  if (priv_->internal_cached_name_.empty())
	    priv_->internal_cached_name_ =
	      get_function_type_name(this, /*internal=*/true);
	  return priv_->internal_cached_name_;
	}
      else
	{
	  priv_->temp_internal_cached_name_ =
	    get_function_type_name(this,
				   /*internal=*/true);
	  return priv_->temp_internal_cached_name_;
	}
    }
  else
    {
      if (get_naked_canonical_type())
	{
	  if (priv_->cached_name_.empty())
	    priv_->cached_name_ =
	      get_function_type_name(this, /*internal=*/false);
	  return priv_->cached_name_;
	}
      else
	{
	  priv_->cached_name_ =
	    get_function_type_name(this, /*internal=*/false);
	  return priv_->cached_name_;
	}
    }
}

/// Equality operator for function_type.
///
/// @param o the other function_type to compare against.
///
/// @return true iff the two function_type are equal.
bool
function_type::operator==(const type_base& other) const
{
  const function_type* o = dynamic_cast<const function_type*>(&other);
  if (!o)
    return false;
  return try_canonical_compare(this, o);
}

/// Return a copy of the pretty representation of the current @ref
/// function_type.
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.
///
/// @return a copy of the pretty representation of the current @ref
/// function_type.
string
function_type::get_pretty_representation(bool internal,
					 bool /*qualified_name*/) const
{return ir::get_pretty_representation(this, internal);}

/// Traverses an instance of @ref function_type, visiting all the
/// sub-types and decls that it might contain.
///
/// @param v the visitor that is used to visit every IR sub-node of
/// the current node.
///
/// @return true if either
///  - all the children nodes of the current IR node were traversed
///    and the calling code should keep going with the traversing.
///  - or the current IR node is already being traversed.
/// Otherwise, returning false means that the calling code should not
/// keep traversing the tree.
bool
function_type::traverse(ir_node_visitor& v)
{
  // TODO: should we allow the walker to avoid visiting function type
  // twice?  I think that if we do, then ir_node_visitor needs an
  // option to specifically disallow this feature for function types.

  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      bool keep_going = true;

      if (type_base_sptr t = get_return_type())
	{
	  if (!t->traverse(v))
	    keep_going = false;
	}

      if (keep_going)
	for (parameters::const_iterator i = get_parameters().begin();
	     i != get_parameters().end();
	     ++i)
	  if (type_base_sptr parm_type = (*i)->get_type())
	    if (!parm_type->traverse(v))
	      break;

      visiting(false);
    }
  return v.visit_end(this);
}

function_type::~function_type()
{}
// </function_type>

// <method_type>

struct method_type::priv
{
  class_or_union_wptr class_type_;
  bool is_const;

  priv()
    : is_const()
  {}
}; // end struct method_type::priv

/// Constructor for instances of method_type.
///
/// Instances of method_decl must be of type method_type.
///
/// @param return_type the type of the return value of the method.
///
/// @param class_type the base type of the method type.  That is, the
/// type of the class the method belongs to.
///
/// @param p the vector of the parameters of the method.
///
/// @param is_const whether this method type is for a const method.
/// Note that const-ness is a property of the method *type* and of the
/// relationship between a method *declaration* and its scope.
///
/// @param size_in_bits the size of an instance of method_type,
/// expressed in bits.
///
/// @param alignment_in_bits the alignment of an instance of
/// method_type, expressed in bits.
method_type::method_type (type_base_sptr return_type,
			  class_or_union_sptr class_type,
			  const std::vector<function_decl::parameter_sptr>& p,
			  bool is_const,
			  size_t size_in_bits,
			  size_t alignment_in_bits)
  : type_or_decl_base(class_type->get_environment(),
		      METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
    type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
    function_type(return_type, p, size_in_bits, alignment_in_bits),
    priv_(new priv)
{
  runtime_type_instance(this);
  set_class_type(class_type);
  set_is_const(is_const);
}

/// Constructor of instances of method_type.
///
///Instances of method_decl must be of type method_type.
///
/// @param return_type the type of the return value of the method.
///
/// @param class_type the type of the class the method belongs to.
/// The actual (dynamic) type of class_type must be a pointer
/// class_type.  We are setting it to pointer to type_base here to
/// help client code that is compiled without rtti and thus cannot
/// perform dynamic casts.
///
/// @param p the vector of the parameters of the method type.
///
/// @param is_const whether this method type is for a const method.
/// Note that const-ness is a property of the method *type* and of the
/// relationship between a method *declaration* and its scope.
///
/// @param size_in_bits the size of an instance of method_type,
/// expressed in bits.
///
/// @param alignment_in_bits the alignment of an instance of
/// method_type, expressed in bits.
method_type::method_type(type_base_sptr return_type,
			 type_base_sptr class_type,
			 const std::vector<function_decl::parameter_sptr>& p,
			 bool is_const,
			 size_t size_in_bits,
			 size_t alignment_in_bits)
  : type_or_decl_base(class_type->get_environment(),
		      METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
    type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
    function_type(return_type, p, size_in_bits, alignment_in_bits),
    priv_(new priv)
{
  runtime_type_instance(this);
  set_class_type(is_class_type(class_type));
  set_is_const(is_const);
}

/// Constructor of the qualified_type_def
///
/// @param env the environment we are operating from.
///
/// @param size_in_bits the size of the type, expressed in bits.
///
/// @param alignment_in_bits the alignment of the type, expressed in bits
method_type::method_type(const environment*	env,
			 size_t		size_in_bits,
			 size_t		alignment_in_bits)
  : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
    type_base(env, size_in_bits, alignment_in_bits),
    function_type(env, size_in_bits, alignment_in_bits),
    priv_(new priv)
{
  runtime_type_instance(this);
}

/// Constructor of instances of method_type.
///
/// When constructed with this constructor, and instane of method_type
/// must set a return type using method_type::set_return_type
///
/// @param class_typ the base type of the method type.  That is, the
/// type of the class (or union) the method belongs to.
///
/// @param size_in_bits the size of an instance of method_type,
/// expressed in bits.
///
/// @param alignment_in_bits the alignment of an instance of
/// method_type, expressed in bits.
method_type::method_type(class_or_union_sptr class_type,
			 bool is_const,
			 size_t size_in_bits,
			 size_t alignment_in_bits)
  : type_or_decl_base(class_type->get_environment(),
		      METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
    type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
    function_type(class_type->get_environment(),
		  size_in_bits,
		  alignment_in_bits),
    priv_(new priv)
{
  runtime_type_instance(this);
  set_class_type(class_type);
  set_is_const(is_const);
}

/// Get the class type this method belongs to.
///
/// @return the class type.
class_or_union_sptr
method_type::get_class_type() const
{return class_or_union_sptr(priv_->class_type_);}

/// Sets the class type of the current instance of method_type.
///
/// The class type is the type of the class the method belongs to.
///
/// @param t the new class type to set.
void
method_type::set_class_type(const class_or_union_sptr& t)
{
  if (!t)
    return;

  priv_->class_type_ = t;
}

/// Return a copy of the pretty representation of the current @ref
/// method_type.
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.
///
/// @return a copy of the pretty representation of the current @ref
/// method_type.
string
method_type::get_pretty_representation(bool internal,
				       bool /*qualified_name*/) const
{return ir::get_pretty_representation(*this, internal);}

/// Setter of the "is-const" property of @ref method_type.
///
/// @param the new value of the "is-const" property.
void
method_type::set_is_const(bool f)
{priv_->is_const = f;}

/// Getter of the "is-const" property of @ref method_type.
///
/// @return true iff the "is-const" property was set.
bool
method_type::get_is_const() const
{return priv_->is_const;}

/// The destructor of method_type
method_type::~method_type()
{}

// </method_type>

// <function_decl definitions>

struct function_decl::priv
{
  bool			declared_inline_;
  decl_base::binding	binding_;
  function_type_wptr	type_;
  function_type*	naked_type_;
  elf_symbol_sptr	symbol_;
  interned_string id_;

  priv()
    : declared_inline_(false),
      binding_(decl_base::BINDING_GLOBAL),
      naked_type_()
  {}

  priv(function_type_sptr t,
       bool declared_inline,
       decl_base::binding binding)
    : declared_inline_(declared_inline),
      binding_(binding),
      type_(t),
      naked_type_(t.get())
  {}

  priv(function_type_sptr t,
       bool declared_inline,
       decl_base::binding binding,
       elf_symbol_sptr s)
    : declared_inline_(declared_inline),
      binding_(binding),
      type_(t),
      naked_type_(t.get()),
      symbol_(s)
  {}
}; // end sruct function_decl::priv

/// Constructor of the @ref function_decl.
///
/// @param name the name of the function.
///
/// @param function_type the type of the function.
///
/// @param declared_inline wether the function is declared inline.
///
/// @param locus the source location of the function.
///
/// @param mangled_name the linkage name of the function.
///
/// @param vis the visibility of the function.
///
/// @param bind the binding of the function.
function_decl::function_decl(const string& name,
			     function_type_sptr function_type,
			     bool declared_inline,
			     const location& locus,
			     const string& mangled_name,
			     visibility vis,
			     binding bind)
  : type_or_decl_base(function_type->get_environment(),
		      FUNCTION_DECL | ABSTRACT_DECL_BASE),
    decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
    priv_(new priv(function_type, declared_inline, bind))
{
  runtime_type_instance(this);
}

/// Constructor of the function_decl type.
///
/// This flavour of constructor is for when the pointer to the
/// instance of function_type that the client code has is presented as
/// a pointer to type_base.  In that case, this constructor saves the
/// client code from doing a dynamic_cast to get the function_type
/// pointer.
///
/// @param name the name of the function declaration.
///
/// @param fn_type the type of the function declaration.  The dynamic
/// type of this parameter should be 'pointer to function_type'
///
/// @param declared_inline whether this function was declared inline
///
/// @param locus the source location of the function declaration.
///
/// @param linkage_name the mangled name of the function declaration.
///
/// @param vis the visibility of the function declaration.
///
/// @param bind  the kind of the binding of the function
/// declaration.
function_decl::function_decl(const string&	name,
			     type_base_sptr	fn_type,
			     bool		declared_inline,
			     const location&	locus,
			     const string&	linkage_name,
			     visibility	vis,
			     binding		bind)
  : type_or_decl_base(fn_type->get_environment(),
		      FUNCTION_DECL | ABSTRACT_DECL_BASE),
    decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
    priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
		   declared_inline,
		   bind))
{
  runtime_type_instance(this);
}

/// Get the pretty representation of the current instance of @ref function_decl.
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.
///
/// @return the pretty representation for a function.
string
function_decl::get_pretty_representation(bool internal,
					 bool /*qualified_name*/) const
{
  const method_decl* mem_fn =
    dynamic_cast<const method_decl*>(this);

  string result = mem_fn ? "method ": "function ";

  if (mem_fn
      && is_member_function(mem_fn)
      && get_member_function_is_virtual(mem_fn))
    result += "virtual ";

  decl_base_sptr type;
  if ((mem_fn
       && is_member_function(mem_fn)
       && (get_member_function_is_dtor(*mem_fn)
	   || get_member_function_is_ctor(*mem_fn))))
    /*cdtors do not have return types.  */;
  else
    type = mem_fn
      ? get_type_declaration(mem_fn->get_type()->get_return_type())
      : get_type_declaration(get_type()->get_return_type());

  if (type)
    result += type->get_qualified_name(internal) + " ";

  result += get_pretty_representation_of_declarator(internal);

  return result;
}

/// Compute and return the pretty representation for the part of the
/// function declaration that starts at the declarator.  That is, the
/// return type and the other specifiers of the beginning of the
/// function's declaration ar omitted.
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.
///
/// @return the pretty representation for the part of the function
/// declaration that starts at the declarator.
string
function_decl::get_pretty_representation_of_declarator (bool internal) const
{
  const method_decl* mem_fn =
    dynamic_cast<const method_decl*>(this);

  string result;

  if (mem_fn)
    {
      result += mem_fn->get_type()->get_class_type()->get_qualified_name()
	+ "::" + mem_fn->get_name();
    }
  else
    result += get_qualified_name();

  result += "(";

  parameters::const_iterator i = get_parameters().begin(),
    end = get_parameters().end();

  // Skip the first parameter if this is a method.
  if (mem_fn && i != end)
    ++i;
  parameter_sptr parm;
  parameter_sptr first_parm;
  if (i != end)
    first_parm = *i;
  for (; i != end; ++i)
    {
      parm = *i;
      if (parm.get() != first_parm.get())
	result += ", ";
      if (parm->get_variadic_marker()
	  || get_environment()->is_variadic_parameter_type(parm->get_type()))
	result += "...";
      else
	{
	  decl_base_sptr type_decl = get_type_declaration(parm->get_type());
	  result += type_decl->get_qualified_name(internal);
	}
    }
  result += ")";

  if (mem_fn
      &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
	 || is_method_type(mem_fn->get_type())->get_is_const()))
    result += " const";

  return result;
}

/// Getter for the first non-implicit parameter of a function decl.
///
/// If the function is a non-static member function, the parameter
/// returned is the first one following the implicit 'this' parameter.
///
/// @return the first non implicit parm.
function_decl::parameters::const_iterator
function_decl::get_first_non_implicit_parm() const
{
  if (get_parameters().empty())
    return get_parameters().end();

  bool is_method = dynamic_cast<const method_decl*>(this);

  parameters::const_iterator i = get_parameters().begin();
  if (is_method)
    ++i;

  return i;
}

/// Return the type of the current instance of @ref function_decl.
///
/// It's either a function_type or method_type.
/// @return the type of the current instance of @ref function_decl.
const shared_ptr<function_type>
function_decl::get_type() const
{return priv_->type_.lock();}

/// Fast getter of the type of the current instance of @ref function_decl.
///
/// Note that this function returns the underlying pointer managed by
/// the smart pointer returned by function_decl::get_type().  It's
/// faster than function_decl::get_type().  This getter is to be used
/// in code paths that are proven to be performance hot spots;
/// especially (for instance) when comparing function types.  Those
/// are compared extremely frequently when libabigail is used to
/// handle huge binaries with a lot of functions.
///
/// @return the type of the current instance of @ref function_decl.
const function_type*
function_decl::get_naked_type() const
{return priv_->naked_type_;}

void
function_decl::set_type(const function_type_sptr& fn_type)
{
  priv_->type_ = fn_type;
  priv_->naked_type_ = fn_type.get();
}

/// This sets the underlying ELF symbol for the current function decl.
///
/// And underlyin$g ELF symbol for the current function decl might
/// exist only if the corpus that this function decl originates from
/// was constructed from an ELF binary file.
///
/// Note that comparing two function decls that have underlying ELF
/// symbols involves comparing their underlying elf symbols.  The decl
/// name for the function thus becomes irrelevant in the comparison.
///
/// @param sym the new ELF symbol for this function decl.
void
function_decl::set_symbol(const elf_symbol_sptr& sym)
{
  priv_->symbol_ = sym;
  // The function id cache that depends on the symbol must be
  // invalidated because the symbol changed.
  priv_->id_ = get_environment()->intern("");
}

/// Gets the the underlying ELF symbol for the current variable,
/// that was set using function_decl::set_symbol().  Please read the
/// documentation for that member function for more information about
/// "underlying ELF symbols".
///
/// @return sym the underlying ELF symbol for this function decl, if
/// one exists.
const elf_symbol_sptr&
function_decl::get_symbol() const
{return priv_->symbol_;}

bool
function_decl::is_declared_inline() const
{return priv_->declared_inline_;}

decl_base::binding
function_decl::get_binding() const
{return priv_->binding_;}

/// @return the return type of the current instance of function_decl.
const shared_ptr<type_base>
function_decl::get_return_type() const
{return get_type()->get_return_type();}

/// @return the parameters of the function.
const std::vector<shared_ptr<function_decl::parameter> >&
function_decl::get_parameters() const
{return get_type()->get_parameters();}

/// Append a parameter to the type of this function.
///
/// @param parm the parameter to append.
void
function_decl::append_parameter(shared_ptr<parameter> parm)
{get_type()->append_parameter(parm);}

/// Append a vector of parameters to the type of this function.
///
/// @param parms the vector of parameters to append.
void
function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
{
  for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
       i != parms.end();
       ++i)
    get_type()->append_parameter(*i);
}

/// Create a new instance of function_decl that is a clone of the
/// current one.
///
/// @return the new clone.
function_decl_sptr
function_decl::clone() const
{
  function_decl_sptr f;
  if (is_member_function(*this))
    {
      method_decl_sptr
	m(new method_decl(get_name(),
				      get_type(),
				      is_declared_inline(),
				      get_location(),
				      get_linkage_name(),
				      get_visibility(),
				      get_binding()));
      class_or_union* scope = is_class_or_union_type(get_scope());
      ABG_ASSERT(scope);
      scope->add_member_function(m, get_member_access_specifier(*this),
				 get_member_function_is_virtual(*this),
				 get_member_function_vtable_offset(*this),
				 get_member_is_static(*this),
				 get_member_function_is_ctor(*this),
				 get_member_function_is_dtor(*this),
				 get_member_function_is_const(*this));
      f = m;
    }
  else
    {
      f.reset(new function_decl(get_name(),
				get_type(),
				is_declared_inline(),
				get_location(),
				get_linkage_name(),
				get_visibility(),
				get_binding()));
      add_decl_to_scope(f, get_scope());
    }
  f->set_symbol(get_symbol());

  return f;
}

/// Compares two instances of @ref function_decl.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const function_decl& l, const function_decl& r, change_kind* k)
{
  bool result = true;

  // Compare function types
  const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
  if (t0 == t1 || *t0 == *t1)
    ; // the types are equal, let's move on to compare the other
      // properties of the functions.
  else
    {
      result = false;
      if (k)
	{
	  if (!types_have_similar_structure(t0, t1))
	    *k |= LOCAL_TYPE_CHANGE_KIND;
	  else
	    *k |= SUBTYPE_CHANGE_KIND;
	}
      else
	ABG_RETURN_FALSE;
    }

  const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
  if (!!s0 != !!s1)
    {
      result = false;
      if (k)
	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }
  else if (s0 && s0 != s1)
    {
      if (!elf_symbols_alias(s0, s1))
	{
	  result = false;
	  if (k)
	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	  else
	    ABG_RETURN_FALSE;
	}
    }
  bool symbols_are_equal = (s0 && s1 && result);

  if (symbols_are_equal)
    {
      // The functions have underlying elf symbols that are equal,
      // so now, let's compare the decl_base part of the functions
      // w/o considering their decl names.
      interned_string n1 = l.get_name(), n2 = r.get_name();
      interned_string ln1 = l.get_linkage_name(), ln2 = r.get_linkage_name();
      const_cast<function_decl&>(l).set_name("");
      const_cast<function_decl&>(l).set_linkage_name("");
      const_cast<function_decl&>(r).set_name("");
      const_cast<function_decl&>(r).set_linkage_name("");

      bool decl_bases_different = !l.decl_base::operator==(r);

      const_cast<function_decl&>(l).set_name(n1);
      const_cast<function_decl&>(l).set_linkage_name(ln1);
      const_cast<function_decl&>(r).set_name(n2);
      const_cast<function_decl&>(r).set_linkage_name(ln2);

      if (decl_bases_different)
	{
	  result = false;
	  if (k)
	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	  else
	    ABG_RETURN_FALSE;
	}
    }
  else
    if (!l.decl_base::operator==(r))
      {
	result = false;
	if (k)
	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	else
	  ABG_RETURN_FALSE;
      }

  // Compare the remaining properties
  if (l.is_declared_inline() != r.is_declared_inline()
      || l.get_binding() != r.get_binding())
    {
      result = false;
      if (k)
	*k |= LOCAL_NON_TYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }

  if (is_member_function(l) != is_member_function(r))
    {
      result = false;
      if (k)
	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
      else
	ABG_RETURN_FALSE;
    }

  if (is_member_function(l) && is_member_function(r))
    {
      if (!((get_member_function_is_ctor(l)
	     == get_member_function_is_ctor(r))
	    && (get_member_function_is_dtor(l)
		== get_member_function_is_dtor(r))
	    && (get_member_is_static(l)
		== get_member_is_static(r))
	    && (get_member_function_is_const(l)
		== get_member_function_is_const(r))
	    && (get_member_function_is_virtual(l)
		== get_member_function_is_virtual(r))
	    && (get_member_function_vtable_offset(l)
		== get_member_function_vtable_offset(r))))
	{
	  result = false;
	  if (k)
	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	  else
	    ABG_RETURN_FALSE;
	}
    }

  ABG_RETURN(result);
}

/// Comparison operator for @ref function_decl.
///
/// @param other the other instance of @ref function_decl to compare
/// against.
///
/// @return true iff the current instance of @ref function_decl equals
/// @p other.
bool
function_decl::operator==(const decl_base& other) const
{
  const function_decl* o = dynamic_cast<const function_decl*>(&other);
  if (!o)
    return false;
  return equals(*this, *o, 0);
}

/// Return true iff the function takes a variable number of
/// parameters.
///
/// @return true if the function taks a variable number
/// of parameters.
bool
function_decl::is_variadic() const
{
  return (!get_parameters().empty()
	  && get_parameters().back()->get_variadic_marker());
}

/// The virtual implementation of 'get_hash' for a function_decl.
///
/// This allows decl_base::get_hash to work for function_decls.
///
/// @return the hash value for function decl.
size_t
function_decl::get_hash() const
{
  function_decl::hash hash_fn;
  return hash_fn(*this);
}

/// Return an ID that tries to uniquely identify the function inside a
/// program or a library.
///
/// So if the function has an underlying elf symbol, the ID is the
/// concatenation of the symbol name and its version.  Otherwise, the
/// ID is the linkage name if its non-null.  Otherwise, it's the
/// pretty representation of the function.
///
/// @return the ID.
interned_string
function_decl::get_id() const
{
  if (priv_->id_.empty())
    {
      const environment* env = get_type()->get_environment();
      if (elf_symbol_sptr s = get_symbol())
	{
	  if (s->has_aliases())
	    // The symbol has several aliases, so let's use a scheme
	    // that allows all aliased functions to have different
	    // IDs.
	    priv_->id_ = env->intern(get_name() + "/" + s->get_id_string());
	  else
	    // Let's use the full symbol name with its version as ID.
	    priv_->id_ = env->intern(s->get_id_string());
	}
      else if (!get_linkage_name().empty())
	priv_->id_= env->intern(get_linkage_name());
      else
	priv_->id_ = env->intern(get_pretty_representation());
    }
  return priv_->id_;
}

/// Test if two function declarations are aliases.
///
/// Two functions declarations are aliases if their symbols are
/// aliases, in the ELF sense.
///
/// @param f1 the first function to consider.
///
/// @param f2 the second function to consider.
///
/// @return true iff @p f1 is an alias of @p f2
bool
function_decls_alias(const function_decl& f1, const function_decl& f2)
{
  elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();

  if (!s1 || !s2)
    return false;

  return elf_symbols_alias(s1, s2);
}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
function_decl::traverse(ir_node_visitor& v)
{
  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      if (type_base_sptr t = get_type())
	t->traverse(v);
      visiting(false);
    }
  return v.visit_end(this);
}

/// Destructor of the @ref function_decl type.
function_decl::~function_decl()
{delete priv_;}

/// A deep comparison operator for a shared pointer to @ref function_decl
///
/// This function compares to shared pointers to @ref function_decl by
/// looking at the pointed-to instances of @ref function_dec
/// comparing them too.  If the two pointed-to objects are equal then
/// this function returns true.
///
/// @param l the left-hand side argument of the equality operator.
///
/// @param r the right-hand side argument of the equality operator.
///
/// @return true iff @p l equals @p r.
bool
operator==(const function_decl_sptr& l, const function_decl_sptr& r)
{
  if (l.get() == r.get())
    return true;
  if (!!l != !!r)
    return false;

  return *l == *r;
}

/// A deep inequality operator for smart pointers to functions.
///
/// @param l the left-hand side argument of the inequality operator.
///
/// @pram r the right-hand side argument of the inequality operator.
///
/// @return true iff @p is not equal to @p r.
bool
operator!=(const function_decl_sptr& l, const function_decl_sptr& r)
{return !operator==(l, r);}

// <function_decl definitions>

// <function_decl::parameter definitions>

struct function_decl::parameter::priv
{
  type_base_wptr	type_;
  unsigned		index_;
  bool			variadic_marker_;

  priv()
    : index_(),
      variadic_marker_()
  {}

  priv(type_base_sptr type,
       unsigned index,
       bool variadic_marker)
    : type_(type),
      index_(index),
      variadic_marker_(variadic_marker)
  {}
};// end struct function_decl::parameter::priv

function_decl::parameter::parameter(const type_base_sptr	type,
				    unsigned			index,
				    const string&		name,
				    const location&		loc,
				    bool			is_variadic)
  : type_or_decl_base(type->get_environment(),
		      FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
    decl_base(type->get_environment(), name, loc),
    priv_(new priv(type, index, is_variadic))
{
  runtime_type_instance(this);
}

function_decl::parameter::parameter(const type_base_sptr	type,
				    unsigned			index,
				    const string&		name,
				    const location&		loc,
				    bool			is_variadic,
				    bool			is_artificial)
  : type_or_decl_base(type->get_environment(),
		      FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
    decl_base(type->get_environment(), name, loc),
    priv_(new priv(type, index, is_variadic))
{
  runtime_type_instance(this);
  set_is_artificial(is_artificial);
}

function_decl::parameter::parameter(const type_base_sptr	type,
				    const string&		name,
				    const location&		loc,
				    bool			is_variadic,
				    bool			is_artificial)
  : type_or_decl_base(type->get_environment(),
		      FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
    decl_base(type->get_environment(), name, loc),
    priv_(new priv(type, 0, is_variadic))
{
  runtime_type_instance(this);
  set_is_artificial(is_artificial);
}

function_decl::parameter::parameter(const type_base_sptr	type,
				    unsigned			index,
				    bool			variad)
  : type_or_decl_base(type->get_environment(),
		      FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
    decl_base(type->get_environment(), "", location()),
    priv_(new priv(type, index, variad))
{
  runtime_type_instance(this);
}

function_decl::parameter::~parameter() = default;

const type_base_sptr
function_decl::parameter::get_type()const
{return priv_->type_.lock();}

/// @return a copy of the type name of the parameter.
interned_string
function_decl::parameter::get_type_name() const
{
  const environment* env = get_environment();
  ABG_ASSERT(env);

  type_base_sptr t = get_type();
  string str;
  if (get_variadic_marker() || env->is_variadic_parameter_type(t))
    str = "...";
  else
    {
	ABG_ASSERT(t);
	str = abigail::ir::get_type_name(t);
    }
  return env->intern(str);
}

/// @return a copy of the pretty representation of the type of the
/// parameter.
const string
function_decl::parameter::get_type_pretty_representation() const
{
  type_base_sptr t = get_type();
  string str;
  if (get_variadic_marker()
      || get_environment()->is_variadic_parameter_type(t))
    str = "...";
  else
    {
	ABG_ASSERT(t);
	str += get_type_declaration(t)->get_pretty_representation();
    }
  return str;
}

/// Get a name uniquely identifying the parameter in the function.
///
///@return the unique parm name id.
interned_string
function_decl::parameter::get_name_id() const
{
  const environment* env = get_environment();
  ABG_ASSERT(env);

  std::ostringstream o;
  o << "parameter-" << get_index();

  return env->intern(o.str());
}

unsigned
function_decl::parameter::get_index() const
{return priv_->index_;}

void
function_decl::parameter::set_index(unsigned i)
{priv_->index_ = i;}


bool
function_decl::parameter::get_variadic_marker() const
{return priv_->variadic_marker_;}

/// Compares two instances of @ref function_decl::parameter.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const function_decl::parameter& l,
       const function_decl::parameter& r,
       change_kind* k)
{
  bool result = true;

  if ((l.get_variadic_marker() != r.get_variadic_marker())
      || (l.get_index() != r.get_index())
      || (!!l.get_type() != !!r.get_type()))
    {
      result = false;
      if (k)
	{
	  if (l.get_index() != r.get_index())
	    *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	  if (l.get_variadic_marker() != r.get_variadic_marker()
	      || !!l.get_type() != !!r.get_type())
	    *k |= LOCAL_TYPE_CHANGE_KIND;
	}
      else
	ABG_RETURN_FALSE;
    }

  type_base_sptr l_type = l.get_type();
  type_base_sptr r_type = r.get_type();
  if (l_type != r_type)
    {
      result = false;
      if (k)
	{
	  if (!types_have_similar_structure(l_type, r_type))
	    *k |= LOCAL_TYPE_CHANGE_KIND;
	  else
	    *k |= SUBTYPE_CHANGE_KIND;
	}
      else
	ABG_RETURN_FALSE;
    }

  ABG_RETURN(result);
}

bool
function_decl::parameter::operator==(const parameter& o) const
{return equals(*this, o, 0);}

bool
function_decl::parameter::operator==(const decl_base& o) const
{
  const function_decl::parameter* p =
    dynamic_cast<const function_decl::parameter*>(&o);
  if (!p)
    return false;
  return function_decl::parameter::operator==(*p);
}

/// Non-member equality operator for @ref function_decl::parameter.
///
/// @param l the left-hand side of the equality operator
///
/// @param r the right-hand side of the equality operator
///
/// @return true iff @p l and @p r equals.
bool
operator==(const function_decl::parameter_sptr& l,
	   const function_decl::parameter_sptr& r)
{
  if (!!l != !!r)
    return false;
  if (!l)
    return true;
  return *l == *r;
}

/// Non-member inequality operator for @ref function_decl::parameter.
///
/// @param l the left-hand side of the equality operator
///
/// @param r the right-hand side of the equality operator
///
/// @return true iff @p l and @p r different.
bool
operator!=(const function_decl::parameter_sptr& l,
	   const function_decl::parameter_sptr& r)
{return !operator==(l, r);}

/// Traverse the diff sub-tree under the current instance
/// function_decl.
///
/// @param v the visitor to invoke on each diff node of the sub-tree.
///
/// @return true if the traversing has to keep going on, false
/// otherwise.
bool
function_decl::parameter::traverse(ir_node_visitor& v)
{
  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      if (type_base_sptr t = get_type())
	t->traverse(v);
      visiting(false);
    }
  return v.visit_end(this);
}

/// Get the hash of a decl.  If the hash hasn't been computed yet,
/// compute it ans store its value; otherwise, just return the hash.
///
/// @return the hash of the decl.
size_t
function_decl::parameter::get_hash() const
{
  function_decl::parameter::hash hash_fn_parm;
  return hash_fn_parm(this);
}

/// Compute the qualified name of the parameter.
///
/// @param internal set to true if the call is intended for an
/// internal use (for technical use inside the library itself), false
/// otherwise.  If you don't know what this is for, then set it to
/// false.
///
/// @param qn the resulting qualified name.
void
function_decl::parameter::get_qualified_name(interned_string& qualified_name,
					     bool /*internal*/) const
{qualified_name = get_name();}

/// Compute and return a copy of the pretty representation of the
/// current function parameter.
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.
///
/// @return a copy of the textual representation of the current
/// function parameter.
string
function_decl::parameter::get_pretty_representation(bool internal,
						    bool /*qualified_name*/) const
{
  const environment* env = get_environment();
  ABG_ASSERT(env);

  string type_repr;
  type_base_sptr t = get_type();
  if (!t)
    type_repr = "void";
  else if (env->is_variadic_parameter_type(t))
    type_repr = "...";
  else
    type_repr = ir::get_pretty_representation(t, internal);

  string result = type_repr;
  string parm_name = get_name_id();

  if (!parm_name.empty())
    result += " " + parm_name;

  return result;
}

// </function_decl::parameter definitions>

// <class_or_union definitions>

/// A Constructor for instances of @ref class_or_union
///
/// @param env the environment we are operating from.
///
/// @param name the identifier of the class.
///
/// @param size_in_bits the size of an instance of @ref
/// class_or_union, expressed in bits
///
/// @param align_in_bits the alignment of an instance of @ref class_or_union,
/// expressed in bits.
///
/// @param locus the source location of declaration point this class.
///
/// @param vis the visibility of instances of @ref class_or_union.
///
/// @param mem_types the vector of member types of this instance of
/// @ref class_or_union.
///
/// @param data_members the vector of data members of this instance of
/// @ref class_or_union.
///
/// @param member_fns the vector of member functions of this instance
/// of @ref class_or_union.
class_or_union::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& mem_types,
			       data_members& data_members,
			       member_functions& member_fns)
  : type_or_decl_base(env,
		      ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE
		      | ABSTRACT_SCOPE_TYPE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(env, name, locus, name, vis),
    type_base(env, size_in_bits, align_in_bits),
    scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
    priv_(new priv(mem_types, data_members, member_fns))
{
  for (member_types::iterator i = mem_types.begin();
       i != mem_types.end();
       ++i)
    if (!has_scope(get_type_declaration(*i)))
      add_decl_to_scope(get_type_declaration(*i), this);

  for (data_members::iterator i = data_members.begin();
       i != data_members.end();
       ++i)
    if (!has_scope(*i))
      add_decl_to_scope(*i, this);

  for (member_functions::iterator i = member_fns.begin();
       i != member_fns.end();
       ++i)
    if (!has_scope(static_pointer_cast<decl_base>(*i)))
      add_decl_to_scope(*i, this);
}

/// A constructor for instances of @ref class_or_union.
///
/// @param env the environment we are operating from.
///
/// @param name the name of the class.
///
/// @param size_in_bits the size of an instance of @ref
/// class_or_union, expressed in bits
///
/// @param align_in_bits the alignment of an instance of @ref class_or_union,
/// expressed in bits.
///
/// @param locus the source location of declaration point this class.
///
/// @param vis the visibility of instances of @ref class_or_union.
class_or_union::class_or_union(const environment* env, const string& name,
			       size_t size_in_bits, size_t align_in_bits,
			       const location& locus, visibility vis)
  : type_or_decl_base(env,
		      ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE
		      | ABSTRACT_SCOPE_TYPE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(env, name, locus, name, vis),
    type_base(env, size_in_bits, align_in_bits),
    scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
    priv_(new priv)
{}

/// Constructor of the @ref class_or_union type.
///
/// @param env the @ref environment we are operating from.
///
/// @param name the name of the @ref class_or_union.
///
/// @param is_declaration_only a boolean saying whether the instance
/// represents a declaration only, or not.
class_or_union::class_or_union(const environment* env, const string& name,
			       bool is_declaration_only)
  : type_or_decl_base(env,
		      ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE
		      | ABSTRACT_SCOPE_TYPE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(env, name, location(), name),
    type_base(env, 0, 0),
    scope_type_decl(env, name, 0, 0, location()),
    priv_(new priv)
{
  set_is_declaration_only(is_declaration_only);
}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the member nodes of the translation
/// unit during the traversal.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
class_or_union::traverse(ir_node_visitor& v)
{
  if (v.type_node_has_been_visited(this))
    return true;

  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      bool stop = false;

      if (!stop)
	for (data_members::const_iterator i = get_data_members().begin();
	     i != get_data_members().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }

      if (!stop)
	for (member_functions::const_iterator i= get_member_functions().begin();
	     i != get_member_functions().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }

      if (!stop)
	for (member_types::const_iterator i = get_member_types().begin();
	     i != get_member_types().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }

      if (!stop)
	for (member_function_templates::const_iterator i =
	       get_member_function_templates().begin();
	     i != get_member_function_templates().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }

      if (!stop)
	for (member_class_templates::const_iterator i =
	       get_member_class_templates().begin();
	     i != get_member_class_templates().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }
      visiting(false);
    }

  bool result = v.visit_end(this);
  v.mark_type_node_as_visited(this);
  return result;
}

/// Destrcutor of the @ref class_or_union type.
class_or_union::~class_or_union()
{delete priv_;}

/// Add a member declaration to the current instance of class_or_union.
/// The member declaration can be either a member type, data member,
/// member function, or member template.
///
/// @param d the member declaration to add.
decl_base_sptr
class_or_union::add_member_decl(const decl_base_sptr& d)
{return insert_member_decl(d, get_member_decls().end());}

/// Remove a given decl from the current @ref class_or_union scope.
///
/// Note that only type declarations are supported by this method for
/// now.  Support for the other kinds of declaration is left as an
/// exercise for the interested reader of the code.
///
/// @param decl the declaration to remove from this @ref
/// class_or_union scope.
void
class_or_union::remove_member_decl(decl_base_sptr decl)
{
  type_base_sptr t = is_type(decl);

  // For now we want to support just removing types from classes.  For
  // other kinds of IR node, we need more work.
  ABG_ASSERT(t);

  remove_member_type(t);
}

/// Fixup the members of the type of an anonymous data member.
///
/// Walk all data members of (the type of) a given anonymous data
/// member and set a particular property of the relationship between
/// each data member and its containing type.
///
/// That property records the fact that the data member belongs to the
/// anonymous data member we consider.
///
/// In the future, if there are other properties of this relationship
/// to set in this manner, they ought to be added here.
///
/// @param anon_dm the anonymous data member to consider.
void
class_or_union::maybe_fixup_members_of_anon_data_member(var_decl_sptr& anon_dm)
{
  class_or_union * anon_dm_type =
    anonymous_data_member_to_class_or_union(anon_dm.get());
  if (!anon_dm_type)
    return;

  for (class_or_union::data_members::const_iterator it =
	 anon_dm_type->get_non_static_data_members().begin();
       it != anon_dm_type->get_non_static_data_members().end();
       ++it)
    {
      dm_context_rel *rel =
	dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
      ABG_ASSERT(rel);
      rel->set_anonymous_data_member(anon_dm.get());
    }
}

/// Insert a member type.
///
/// @param t the type to insert in the @ref class_or_union type.
///
/// @param an iterator right before which @p t has to be inserted.
void
class_or_union::insert_member_type(type_base_sptr t,
				   declarations::iterator before)
{
  decl_base_sptr d = get_type_declaration(t);
  ABG_ASSERT(d);
  ABG_ASSERT(!has_scope(d));

  priv_->member_types_.push_back(t);
  scope_decl::insert_member_decl(d, before);
}

/// Add a member type to the current instance of class_or_union.
///
/// @param t the member type to add.  It must not have been added to a
/// scope, otherwise this will violate an ABG_ASSERTion.
void
class_or_union::add_member_type(type_base_sptr t)
{insert_member_type(t, get_member_decls().end());}

/// Add a member type to the current instance of class_or_union.
///
/// @param t the type to be added as a member type to the current
/// instance of class_or_union.  An instance of class_or_union::member_type
/// will be created out of @p t and and added to the the class.
///
/// @param a the access specifier for the member type to be created.
type_base_sptr
class_or_union::add_member_type(type_base_sptr t, access_specifier a)
{
  decl_base_sptr d = get_type_declaration(t);
  ABG_ASSERT(d);
  ABG_ASSERT(!is_member_decl(d));
  add_member_type(t);
  set_member_access_specifier(d, a);
  return t;
}

/// Remove a member type from the current @ref class_or_union scope.
///
/// @param t the type to remove.
void
class_or_union::remove_member_type(type_base_sptr t)
{
  for (member_types::iterator i = priv_->member_types_.begin();
       i != priv_->member_types_.end();
       ++i)
    {
      if (*((*i)) == *t)
	{
	  priv_->member_types_.erase(i);
	  return;
	}
    }
}

/// Getter of the alignment of the @ref class_or_union type.
///
/// If this @ref class_or_union is a declaration of a definition that
/// is elsewhere, then the size of the definition is returned.
///
/// @return the alignment of the @ref class_or_union type.
size_t
class_or_union::get_alignment_in_bits() const
{
  if (get_is_declaration_only() && get_definition_of_declaration())
    return is_class_or_union_type
      (get_definition_of_declaration())->get_alignment_in_bits();

   return type_base::get_alignment_in_bits();
}

/// Setter of the alignment of the class type.
///
/// If this class is a declaration of a definition that is elsewhere,
/// then the new alignment is set to the definition.
///
/// @param s the new alignment.
void
class_or_union::set_alignment_in_bits(size_t a)
{
  if (get_is_declaration_only() && get_definition_of_declaration())
    is_class_or_union_type
      (get_definition_of_declaration()) ->set_alignment_in_bits(a);
  else
    type_base::set_alignment_in_bits(a);
}

/// Setter of the size of the @ref class_or_union type.
///
/// If this @ref class_or_union is a declaration of a definition that
/// is elsewhere, then the new size is set to the definition.
///
/// @param s the new size.
void
class_or_union::set_size_in_bits(size_t s)
{
  if (get_is_declaration_only() && get_definition_of_declaration())
    is_class_or_union_type
      (get_definition_of_declaration())->set_size_in_bits(s);
  else
    type_base::set_size_in_bits(s);
}

/// Getter of the size of the @ref class_or_union type.
///
/// If this @ref class_or_union is a declaration of a definition that
/// is elsewhere, then the size of the definition is returned.
///
/// @return the size of the @ref class_or_union type.
size_t
class_or_union::get_size_in_bits() const
{
  if (get_is_declaration_only() && get_definition_of_declaration())
    return is_class_or_union_type
      (get_definition_of_declaration())->get_size_in_bits();

  return type_base::get_size_in_bits();
}

/// Get the member types of this @ref class_or_union.
///
/// @return a vector of the member types of this ref class_or_union.
const class_or_union::member_types&
class_or_union::get_member_types() const
{return priv_->member_types_;}

/// Get the number of anonymous member classes contained in this
/// class.
///
/// @return the number of anonymous member classes contained in this
/// class.
size_t
class_or_union::get_num_anonymous_member_classes() const
{
  int result = 0;
  for (member_types::const_iterator it = get_member_types().begin();
       it != get_member_types().end();
       ++it)
    if (class_decl_sptr t = is_class_type(*it))
      if (t->get_is_anonymous())
	++result;

  return result;
}

/// Get the number of anonymous member unions contained in this class.
///
/// @return the number of anonymous member unions contained in this
/// class.
size_t
class_or_union::get_num_anonymous_member_unions() const
{
  int result = 0;
  for (member_types::const_iterator it = get_member_types().begin();
       it != get_member_types().end();
       ++it)
    if (union_decl_sptr t = is_union_type(*it))
      if (t->get_is_anonymous())
	++result;

  return result;
}

/// Get the number of anonymous member enums contained in this class.
///
/// @return the number of anonymous member enums contained in this
/// class.
size_t
class_or_union::get_num_anonymous_member_enums() const
{
  int result = 0;
  for (member_types::const_iterator it = get_member_types().begin();
       it != get_member_types().end();
       ++it)
    if (enum_type_decl_sptr t = is_enum_type(*it))
      if (t->get_is_anonymous())
	++result;

  return result;
}

/// Find a member type of a given name, inside the current @ref
/// class_or_union.
///
/// @param name the name of the member type to look for.
///
/// @return a pointer to the @ref type_base that represents the member
/// type of name @p name, for the current class.
type_base_sptr
class_or_union::find_member_type(const string& name) const
{
  for (member_types::const_iterator i = get_member_types().begin();
       i != get_member_types().end();
       ++i)
    if (get_type_name(*i, /*qualified*/false) == name)
      return *i;
  return type_base_sptr();
}

/// Add a data member to the current instance of class_or_union.
///
/// @param v a var_decl to add as a data member.  A proper
/// class_or_union::data_member is created from @p v and added to the
/// class_or_union.  This var_decl should not have been already added
/// to a scope.
///
/// @param access the access specifier for the data member.
///
/// @param is_laid_out whether the data member was laid out.  That is,
/// if its offset has been computed.  In the pattern of a class
/// template for instance, this would be set to false.
///
/// @param is_static whether the data memer is static.
///
/// @param offset_in_bits if @p is_laid_out is true, this is the
/// offset of the data member, expressed (oh, surprise) in bits.
void
class_or_union::add_data_member(var_decl_sptr v, access_specifier access,
				bool is_laid_out, bool is_static,
				size_t offset_in_bits)
{
  ABG_ASSERT(!has_scope(v));

  priv_->data_members_.push_back(v);
  scope_decl::add_member_decl(v);
  set_data_member_is_laid_out(v, is_laid_out);
  set_data_member_offset(v, offset_in_bits);
  set_member_access_specifier(v, access);
  set_member_is_static(v, is_static);

  if (!is_static)
    {
      // If this is a non-static variable, add it to the set of
      // non-static variables, if it's not only in there.
      bool is_already_in = false;
      for (data_members::const_iterator i =
	     priv_->non_static_data_members_.begin();
	   i != priv_->non_static_data_members_.end();
	   ++i)
	if (*i == v)
	  {
	    is_already_in = true;
	    break;
	  }
      if (!is_already_in)
	priv_->non_static_data_members_.push_back(v);
    }

  // If v is an anonymous data member, then fixup its data members.
  // For now, the only thing the fixup does is to make the data
  // members of the anonymous data member be aware of their containing
  // anonymous data member.  That is helpful to compute the absolute
  // bit offset of each of the members of the anonymous data member.
  maybe_fixup_members_of_anon_data_member(v);
}

/// Get the data members of this @ref class_or_union.
///
/// @return a vector of the data members of this @ref class_or_union.
const class_or_union::data_members&
class_or_union::get_data_members() const
{return priv_->data_members_;}

/// Find a data member of a given name in the current @ref class_or_union.
///
/// @param name the name of the data member to find in the current
/// @ref class_or_union.
///
/// @return a pointer to the @ref var_decl that represents the data
/// member to find inside the current @ref class_or_union.
const var_decl_sptr
class_or_union::find_data_member(const string& name) const
{
  for (data_members::const_iterator i = get_data_members().begin();
       i != get_data_members().end();
       ++i)
    if ((*i)->get_name() == name)
      return *i;

  // We haven't found a data member with the name 'name'.  Let's look
  // closer again, this time in our anonymous data members.
  for (data_members::const_iterator i = get_data_members().begin();
       i != get_data_members().end();
       ++i)
    if (is_anonymous_data_member(*i))
      {
	class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
	ABG_ASSERT(type);
	if (var_decl_sptr data_member = type->find_data_member(name))
	  return data_member;
      }

  return var_decl_sptr();
}

/// Find an anonymous data member in the class.
///
/// @param v the anonymous data member to find.
///
/// @return the anonymous data member found, or nil if none was found.
const var_decl_sptr
class_or_union::find_anonymous_data_member(const var_decl_sptr& v) const
{
  if (!v->get_name().empty())
    return var_decl_sptr();

  for (data_members::const_iterator it = get_non_static_data_members().begin();
       it != get_non_static_data_members().end();
       ++it)
    {
      if (is_anonymous_data_member(*it))
	if ((*it)->get_pretty_representation(/*internal=*/false, true)
	    == v->get_pretty_representation(/*internal=*/false, true))
	  return *it;
    }

  return var_decl_sptr();
}

/// Find a given data member.
///
/// This function takes a @ref var_decl as an argument.  If it has a
/// non-empty name, then it tries to find a data member which has the
/// same name as the argument.
///
/// If it has an empty name, then the @ref var_decl is considered as
/// an anonymous data member.  In that case, this function tries to
/// find an anonymous data member which type equals that of the @ref
/// var_decl argument.
///
/// @param v this carries either the name of the data member we need
/// to look for, or the type of the anonymous data member we are
/// looking for.
const var_decl_sptr
class_or_union::find_data_member(const var_decl_sptr& v) const
{
  if (!v)
    return var_decl_sptr();

  if (v->get_name().empty())
    return find_anonymous_data_member(v);

  return find_data_member(v->get_name());
}


/// Get the non-static data memebers of this @ref class_or_union.
///
/// @return a vector of the non-static data members of this @ref
/// class_or_union.
const class_or_union::data_members&
class_or_union::get_non_static_data_members() const
{return priv_->non_static_data_members_;}

/// Add a member function.
///
/// @param f the new member function to add.
///
/// @param a the access specifier to use for the new member function.
///
/// @param is_static whether the new member function is static.
///
/// @param is_ctor whether the new member function is a constructor.
///
/// @param is_dtor whether the new member function is a destructor.
///
/// @param is_const whether the new member function is const.
void
class_or_union::add_member_function(method_decl_sptr f,
				    access_specifier a,
				    bool is_static, bool is_ctor,
				    bool is_dtor, bool is_const)
{
  ABG_ASSERT(!has_scope(f));

  scope_decl::add_member_decl(f);

  set_member_function_is_ctor(f, is_ctor);
  set_member_function_is_dtor(f, is_dtor);
  set_member_access_specifier(f, a);
  set_member_is_static(f, is_static);
  set_member_function_is_const(f, is_const);

  priv_->member_functions_.push_back(f);

  // Update the map of linkage name -> member functions.  It's useful,
  // so that class_or_union::find_member_function() can function.
  if (!f->get_linkage_name().empty())
    priv_->mem_fns_map_[f->get_linkage_name()] = f;
}

/// Get the member functions of this @ref class_or_union.
///
/// @return a vector of the member functions of this @ref
/// class_or_union.
const class_or_union::member_functions&
class_or_union::get_member_functions() const
{return priv_->member_functions_;}

/// Find a method, using its linkage name as a key.
///
/// @param linkage_name the linkage name of the method to find.
///
/// @return the method found, or nil if none was found.
const method_decl*
class_or_union::find_member_function(const string& linkage_name) const
{
  return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
}

/// Find a method, using its linkage name as a key.
///
/// @param linkage_name the linkage name of the method to find.
///
/// @return the method found, or nil if none was found.
method_decl*
class_or_union::find_member_function(const string& linkage_name)
{
  string_mem_fn_sptr_map_type::const_iterator i =
    priv_->mem_fns_map_.find(linkage_name);
  if (i == priv_->mem_fns_map_.end())
    return 0;
  return i->second.get();
}

/// Find a method, using its linkage name as a key.
///
/// @param linkage_name the linkage name of the method to find.
///
/// @return the method found, or nil if none was found.
method_decl_sptr
class_or_union::find_member_function_sptr(const string& linkage_name)
{
  string_mem_fn_sptr_map_type::const_iterator i =
    priv_->mem_fns_map_.find(linkage_name);
  if (i == priv_->mem_fns_map_.end())
    return 0;
  return i->second;
}

/// Find a method (member function) using its signature (pretty
/// representation) as a key.
///
/// @param s the signature of the method.
///
/// @return the method found, or nil if none was found.
const method_decl*
class_or_union::find_member_function_from_signature(const string& s) const
{
  return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
}

/// Find a method (member function) using its signature (pretty
/// representation) as a key.
///
/// @param s the signature of the method.
///
/// @return the method found, or nil if none was found.
method_decl*
class_or_union::find_member_function_from_signature(const string& s)
{
  string_mem_fn_ptr_map_type::const_iterator i =
    priv_->signature_2_mem_fn_map_.find(s);
  if (i == priv_->signature_2_mem_fn_map_.end())
    return 0;
  return i->second;
}

/// Get the member function templates of this class.
///
/// @return a vector of the member function templates of this class.
const member_function_templates&
class_or_union::get_member_function_templates() const
{return priv_->member_function_templates_;}

/// Get the member class templates of this class.
///
/// @return a vector of the member class templates of this class.
const member_class_templates&
class_or_union::get_member_class_templates() const
{return priv_->member_class_templates_;}

/// Append a member function template to the @ref class_or_union.
///
/// @param m the member function template to append.
void
class_or_union::add_member_function_template(member_function_template_sptr m)
{
  decl_base* c = m->as_function_tdecl()->get_scope();
  /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
  /// error message or something like a structured error.
  priv_->member_function_templates_.push_back(m);
  if (!c)
    scope_decl::add_member_decl(m->as_function_tdecl());
}

/// Append a member class template to the @ref class_or_union.
///
/// @param m the member function template to append.
void
class_or_union::add_member_class_template(member_class_template_sptr m)
{
  decl_base* c = m->as_class_tdecl()->get_scope();
  /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
  /// error message or something like a structured error.
  m->set_scope(this);
  priv_->member_class_templates_.push_back(m);
  if (!c)
    scope_decl::add_member_decl(m->as_class_tdecl());
}

///@return true iff the current instance has no member.
bool
class_or_union::has_no_member() const
{
  return (priv_->member_types_.empty()
	  && priv_->data_members_.empty()
	  && priv_->member_functions_.empty()
	  && priv_->member_function_templates_.empty()
	  && priv_->member_class_templates_.empty());
}

/// Insert a data member to this @ref class_or_union type.
///
/// @param d the data member to insert.
///
/// @param before an iterator to the point before which to insert the
/// the data member, in the coontainer that contains all the data
/// members.
decl_base_sptr
class_or_union::insert_member_decl(decl_base_sptr d,
				   declarations::iterator before)
{
  if (type_base_sptr t = dynamic_pointer_cast<type_base>(d))
    insert_member_type(t, before);
  else if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
    {
      add_data_member(v, public_access,
		      /*is_laid_out=*/false,
		      /*is_static=*/true,
		      /*offset_in_bits=*/0);
      d = v;
    }
  else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
    add_member_function(f, public_access,
			/*is_static=*/false,
			/*is_ctor=*/false,
			/*is_dtor=*/false,
			/*is_const=*/false);
  else if (member_function_template_sptr f =
	   dynamic_pointer_cast<member_function_template>(d))
    add_member_function_template(f);
  else if (member_class_template_sptr c =
	   dynamic_pointer_cast<member_class_template>(d))
    add_member_class_template(c);
  else
    scope_decl::add_member_decl(d);

  return d;
}

/// Equality operator.
///
/// @param other the other @ref class_or_union to compare against.
///
/// @return true iff @p other equals the current @ref class_or_union.
bool
class_or_union::operator==(const decl_base& other) const
{
  const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
  if (!op)
    return false;

  // If this is a decl-only type (and thus with no canonical type),
  // use the canonical type of the definition, if any.
  const class_or_union *l = 0;
  if (get_is_declaration_only())
    l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
  if (l == 0)
    l = this;

  // Likewise for the other class.
  const class_or_union *r = 0;
  if (op->get_is_declaration_only())
    r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
  if (r == 0)
    r = op;

  return try_canonical_compare(l, r);
}

/// Equality operator.
///
/// @param other the other @ref class_or_union to compare against.
///
/// @return true iff @p other equals the current @ref class_or_union.
bool
class_or_union::operator==(const type_base& other) const
{
  const decl_base* o = dynamic_cast<const decl_base*>(&other);
  if (!o)
    return false;
  return *this == *o;
}

/// Equality operator.
///
/// @param other the other @ref class_or_union to compare against.
///
/// @return true iff @p other equals the current @ref class_or_union.
bool
class_or_union::operator==(const class_or_union& other) const
{
  const decl_base& o = other;
  return class_or_union::operator==(o);
}

/// Compares two instances of @ref class_or_union.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff it's non-null and if the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const class_or_union& l, const class_or_union& r, change_kind* k)
{
#define RETURN(value) return return_comparison_result(l, r, value);

  // if one of the classes is declaration-only, look through it to
  // get its definition.
  bool l_is_decl_only = l.get_is_declaration_only();
  bool r_is_decl_only = r.get_is_declaration_only();
  if (l_is_decl_only || r_is_decl_only)
    {
      const class_or_union* def1 = l_is_decl_only
	? is_class_or_union_type(l.get_naked_definition_of_declaration())
	: &l;

      const class_or_union* def2 = r_is_decl_only
	? is_class_or_union_type(r.get_naked_definition_of_declaration())
	: &r;

      if (!def1 || !def2)
	{
	  if (!l.get_is_anonymous()
	      && !r.get_is_anonymous()
	      && l_is_decl_only && r_is_decl_only
	      && comparison::filtering::is_decl_only_class_with_size_change(l, r))
	    // The two decl-only classes differ from their size.  A
	    // true decl-only class should not have a size property to
	    // begin with.  This comes from a DWARF oddity and can
	    // results in a false positive, so let's not consider that
	    // change.
	    return true;

	  if ((l.get_environment()->decl_only_class_equals_definition()
	       || ((odr_is_relevant(l) && !def1)
		   || (odr_is_relevant(r) && !def2)))
	      && !is_anonymous_or_typedef_named(l)
	      && !is_anonymous_or_typedef_named(r))
	    {
	      const interned_string& q1 = l.get_scoped_name();
	      const interned_string& q2 = r.get_scoped_name();
	      if (q1 == q2)
		// Not using RETURN(true) here, because that causes
		// performance issues.  We don't need to do
		// l.priv_->unmark_as_being_compared({l,r}) here because
		// we haven't marked l or r as being compared yet, and
		// doing so has a peformance cost that shows up on
		// performance profiles for *big* libraries.
		return true;
	      else
		{
		  if (k)
		    *k |= LOCAL_TYPE_CHANGE_KIND;
		  // Not using RETURN(true) here, because that causes
		  // performance issues.  We don't need to do
		  // l.priv_->unmark_as_being_compared({l,r}) here because
		  // we haven't marked l or r as being compared yet, and
		  // doing so has a peformance cost that shows up on
		  // performance profiles for *big* libraries.
		  ABG_RETURN_FALSE;
		}
	    }
	  else // A decl-only class is considered different from a
	       // class definition of the same name.
	    {
	      if (!!def1 != !!def2)
		{
		  if (k)
		    *k |= LOCAL_TYPE_CHANGE_KIND;
		  ABG_RETURN_FALSE;
		}

	      // both definitions are empty
	      if (!(l.decl_base::operator==(r)
		       && l.type_base::operator==(r)))
		{
		  if (k)
		    *k |= LOCAL_TYPE_CHANGE_KIND;
		  ABG_RETURN_FALSE;
		}

	      return true;
	    }
	}

      RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);

      mark_types_as_being_compared(l, r);

      bool val = *def1 == *def2;
      if (!val)
	if (k)
	  *k |= LOCAL_TYPE_CHANGE_KIND;
      RETURN(val);
    }

  // No need to go further if the classes have different names or
  // different size / alignment.
  if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
    {
      if (k)
	*k |= LOCAL_TYPE_CHANGE_KIND;
      ABG_RETURN_FALSE;
    }

  if (types_defined_same_linux_kernel_corpus_public(l, r))
    return true;

  RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);

  mark_types_as_being_compared(l, r);

  bool result = true;

  //compare data_members
  {
    if (l.get_non_static_data_members().size()
	!= r.get_non_static_data_members().size())
      {
	result = false;
	if (k)
	  *k |= LOCAL_TYPE_CHANGE_KIND;
	else
	  RETURN(result);
      }

    for (class_or_union::data_members::const_iterator
	   d0 = l.get_non_static_data_members().begin(),
	   d1 = r.get_non_static_data_members().begin();
	 (d0 != l.get_non_static_data_members().end()
	  && d1 != r.get_non_static_data_members().end());
	 ++d0, ++d1)
      if (**d0 != **d1)
	{
	  result = false;
	  if (k)
	    {
	      // Report any representation change as being local.
	      if (!types_have_similar_structure((*d0)->get_type(),
						(*d1)->get_type())
		  || (*d0)->get_type() == (*d1)->get_type())
		*k |= LOCAL_TYPE_CHANGE_KIND;
	      else
		*k |= SUBTYPE_CHANGE_KIND;
	    }
	  else
	    RETURN(result);
	}
  }

  // Do not compare member functions.  DWARF does not necessarily
  // all the member functions, be they virtual or not, in all
  // translation units.  So we cannot have a clear view of them, per
  // class

  // compare member function templates
  {
    if (l.get_member_function_templates().size()
	!= r.get_member_function_templates().size())
      {
	result = false;
	if (k)
	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	else
	  RETURN(result);
      }

    for (member_function_templates::const_iterator
	   fn_tmpl_it0 = l.get_member_function_templates().begin(),
	   fn_tmpl_it1 = r.get_member_function_templates().begin();
	 fn_tmpl_it0 != l.get_member_function_templates().end()
	   &&  fn_tmpl_it1 != r.get_member_function_templates().end();
	 ++fn_tmpl_it0, ++fn_tmpl_it1)
      if (**fn_tmpl_it0 != **fn_tmpl_it1)
	{
	  result = false;
	  if (k)
	    {
	      *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	      break;
	    }
	  else
	    RETURN(result);
	}
  }

  // compare member class templates
  {
    if (l.get_member_class_templates().size()
	!= r.get_member_class_templates().size())
      {
	result = false;
	if (k)
	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	else
	  RETURN(result);
      }

    for (member_class_templates::const_iterator
	   cl_tmpl_it0 = l.get_member_class_templates().begin(),
	   cl_tmpl_it1 = r.get_member_class_templates().begin();
	 cl_tmpl_it0 != l.get_member_class_templates().end()
	   &&  cl_tmpl_it1 != r.get_member_class_templates().end();
	 ++cl_tmpl_it0, ++cl_tmpl_it1)
      if (**cl_tmpl_it0 != **cl_tmpl_it1)
	{
	  result = false;
	  if (k)
	    {
	      *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	      break;
	    }
	  else
	    RETURN(result);
	}
  }

  RETURN(result);
#undef RETURN
}


/// Copy a method of a @ref class_or_union into a new @ref
/// class_or_union.
///
/// @param t the @ref class_or_union into which the method is to be copied.
///
/// @param method the method to copy into @p t.
///
/// @return the resulting newly copied method.
method_decl_sptr
copy_member_function(const class_or_union_sptr& t,
		     const method_decl_sptr& method)
{return copy_member_function(t, method.get());}


/// Copy a method of a @ref class_or_union into a new @ref
/// class_or_union.
///
/// @param t the @ref class_or_union into which the method is to be copied.
///
/// @param method the method to copy into @p t.
///
/// @return the resulting newly copied method.
method_decl_sptr
copy_member_function(const class_or_union_sptr& t, const method_decl* method)
{
  ABG_ASSERT(t);
  ABG_ASSERT(method);

  method_type_sptr old_type = method->get_type();
  ABG_ASSERT(old_type);
  method_type_sptr new_type(new method_type(old_type->get_return_type(),
					    t,
					    old_type->get_parameters(),
					    old_type->get_is_const(),
					    old_type->get_size_in_bits(),
					    old_type->get_alignment_in_bits()));
  new_type->set_environment(t->get_environment());
  keep_type_alive(new_type);

  method_decl_sptr
    new_method(new method_decl(method->get_name(),
			       new_type,
			       method->is_declared_inline(),
			       method->get_location(),
			       method->get_linkage_name(),
			       method->get_visibility(),
			       method->get_binding()));
  new_method->set_symbol(method->get_symbol());

  if (class_decl_sptr class_type = is_class_type(t))
    class_type->add_member_function(new_method,
				    get_member_access_specifier(*method),
				    get_member_function_is_virtual(*method),
				    get_member_function_vtable_offset(*method),
				    get_member_is_static(*method),
				    get_member_function_is_ctor(*method),
				    get_member_function_is_dtor(*method),
				    get_member_function_is_const(*method));
  else
    t->add_member_function(new_method,
			   get_member_access_specifier(*method),
			   get_member_is_static(*method),
			   get_member_function_is_ctor(*method),
			   get_member_function_is_dtor(*method),
			   get_member_function_is_const(*method));
  return new_method;
}

// </class_or_union definitions>

/// @defgroup OnTheFlyCanonicalization On-the-fly Canonicalization
/// @{
///
/// This optimization is also known as "canonical type propagation".
/// 
/// During the canonicalization of a type T (which doesn't yet have a
/// canonical type), T is compared structurally (member-wise) against
/// a type C which already has a canonical type.  The comparison
/// expression is C == T.
///
/// During that structural comparison, if a subtype of C (which also
/// already has a canonical type) is structurally compared to a
/// subtype of T (which doesn't yet have a canonical type) and if they
/// are equal, then we can deduce that the canonical type of the
/// subtype of C is the canonical type of the subtype of C.
///
/// Thus, we can canonicalize the sub-type of the T, during the
/// canonicalization of T itself.  That canonicalization of the
/// sub-type of T is what we call the "on-the-fly canonicalization".
/// It's on the fly because it happens during a comparison -- which
/// itself happens during the canonicalization of T.
///
/// For now this on-the-fly canonicalization only happens when
/// comparing @ref class_decl and @ref function_type.
///
/// Note however that there is a case when a type is *NOT* eligible to
/// this canonical type propagation optimization.
///
/// The reason why a type is deemed NON-eligible to the canonical type
/// propagation optimization is that it "depends" on recursively
/// present type.  Let me explain.
///
/// Suppose we have a type T that has sub-types named ST0 and ST1.
/// Suppose ST1 itself has a sub-type that is T itself.  In this case,
/// we say that T is a recursive type, because it has T (itself) as
/// one of its sub-types:
///
///   T
///   +-- ST0
///   |
///   +-- ST1
///   |    +
///   |    |
///   |    +-- T
///   |
///   +-- ST2
///
/// ST1 is said to "depend" on T because it has T as a sub-type.  But
/// because T is recursive, then ST1 is said to depend on a recursive
/// type.  Notice however that ST0 does not depend on any recursive
/// type.
///
/// Now suppose we are comparing T to a type T' that has the same
/// structure with sub-types ST0', ST1' and ST2'.  During the
/// comparison of ST1 against ST1', their sub-type T is compared
/// against T'.  Because T (resp. T') is a recursive type that is
/// already being compared, the comparison of T against T' (as a
/// subtypes of ST1 and ST1') returns true, meaning they are
/// considered equal.  This is done so that we don't enter an infinite
/// recursion.
///
/// That means ST1 is also deemed equal to ST1'.  If we are in the
/// course of the canonicalization of T' and thus if T (as well as as
/// all of its sub-types) is already canonicalized, then the canonical
/// type propagation optimization will make us propagate the canonical
/// type of ST1 onto ST1'.  So the canonical type of ST1' will be
/// equal to the canonical type of ST1 as a result of that
/// optmization.
///
/// But then, later down the road, when ST2 is compared against ST2',
/// let's suppose that we find out that they are different. Meaning
/// that ST2 != ST2'.  This means that T != T', i.e, the
/// canonicalization of T' failed for now.  But most importantly, it
/// means that the propagation of the canonical type of ST1 to ST1'
/// must now be invalidated.  Meaning, ST1' must now be considered as
/// not having any canonical type.
///
/// In other words, during type canonicalization, if ST1' depends on a
/// recursive type T', its propagated canonical type must be
/// invalidated (set to nullptr) if T' appears to be different from T,
/// a.k.a, the canonicalization of T' temporarily failed.
///
/// This means that any sub-type that depends on recursive types and
/// that has been the target of the canonical type propagation
/// optimization must be tracked.  If the dependant recursive type
/// fails its canonicalization, then the sub-type being compared must
/// have its propagated canonical type cleared.  In other words, its
/// propagated canonical type must be cancelled.
///
/// @}


/// If on-the-fly canonicalization is turned on, then this function
/// sets the canonical type of its second parameter to the canonical
/// type of the first parameter.
///
/// @param lhs_type the type which canonical type to propagate.
///
/// @param rhs_type the type which canonical type to set.
static bool
maybe_propagate_canonical_type(const type_base& lhs_type,
			       const type_base& rhs_type)
{
  if (const environment *env = lhs_type.get_environment())
    if (env->do_on_the_fly_canonicalization())
      if (type_base_sptr canonical_type = lhs_type.get_canonical_type())
	if (!rhs_type.get_canonical_type())
	  if (env->priv_->propagate_ct(lhs_type, rhs_type))
	    return true;
  return false;
}

// <class_decl definitions>

static void
sort_virtual_member_functions(class_decl::member_functions& mem_fns);

/// The private data for the class_decl type.
struct class_decl::priv
{
  base_specs					bases_;
  unordered_map<string, base_spec_sptr>	bases_map_;
  member_functions				virtual_mem_fns_;
  virtual_mem_fn_map_type			virtual_mem_fns_map_;
  bool						is_struct_;

  priv()
    : is_struct_(false)
  {}

  priv(bool is_struct, class_decl::base_specs& bases)
    : bases_(bases),
      is_struct_(is_struct)
  {
  }

  priv(bool is_struct)
    : is_struct_(is_struct)
  {}
};// end struct class_decl::priv

/// A Constructor for instances of \ref class_decl
///
/// @param env the environment we are operating from.
///
/// @param name the identifier of the class.
///
/// @param size_in_bits the size of an instance of class_decl, expressed
/// in bits
///
/// @param align_in_bits the alignment of an instance of class_decl,
/// expressed in bits.
///
/// @param locus the source location of declaration point this class.
///
/// @param vis the visibility of instances of class_decl.
///
/// @param bases the vector of base classes for this instance of class_decl.
///
/// @param mbrs the vector of member types of this instance of
/// class_decl.
///
/// @param data_mbrs the vector of data members of this instance of
/// class_decl.
///
/// @param mbr_fns the vector of member functions of this instance of
/// class_decl.
class_decl::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& mbr_types,
		       data_members& data_mbrs,
		       member_functions& mbr_fns)
  : type_or_decl_base(env,
		      CLASS_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE
		      | ABSTRACT_SCOPE_TYPE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(env, name, locus, name, vis),
    type_base(env, size_in_bits, align_in_bits),
    class_or_union(env, name, size_in_bits, align_in_bits,
		   locus, vis, mbr_types, data_mbrs, mbr_fns),
    priv_(new priv(is_struct, bases))
{
  runtime_type_instance(this);
}

/// A Constructor for instances of @ref class_decl
///
/// @param env the environment we are operating from.
///
/// @param name the identifier of the class.
///
/// @param size_in_bits the size of an instance of class_decl, expressed
/// in bits
///
/// @param align_in_bits the alignment of an instance of class_decl,
/// expressed in bits.
///
/// @param locus the source location of declaration point this class.
///
/// @param vis the visibility of instances of class_decl.
///
/// @param bases the vector of base classes for this instance of class_decl.
///
/// @param mbrs the vector of member types of this instance of
/// class_decl.
///
/// @param data_mbrs the vector of data members of this instance of
/// class_decl.
///
/// @param mbr_fns the vector of member functions of this instance of
/// class_decl.
///
/// @param is_anonymous whether the newly created instance is
/// anonymous.
class_decl::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& mbr_types, data_members& data_mbrs,
		       member_functions& mbr_fns, bool is_anonymous)
  : type_or_decl_base(env,
		      CLASS_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE
		      | ABSTRACT_SCOPE_TYPE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(env, name, locus,
	      // If the class is anonymous then by default it won't
	      // have a linkage name.  Also, the anonymous class does
	      // have an internal-only unique name that is generally
	      // not taken into account when comparing classes; such a
	      // unique internal-only name, when used as a linkage
	      // name might introduce spurious comparison false
	      // negatives.
	      /*linkage_name=*/is_anonymous ? string() : name,
	      vis),
    type_base(env, size_in_bits, align_in_bits),
    class_or_union(env, name, size_in_bits, align_in_bits,
		   locus, vis, mbr_types, data_mbrs, mbr_fns),
    priv_(new priv(is_struct, bases))
{
  runtime_type_instance(this);
  set_is_anonymous(is_anonymous);
}

/// A constructor for instances of class_decl.
///
/// @param env the environment we are operating from.
///
/// @param name the name of the class.
///
/// @param size_in_bits the size of an instance of class_decl, expressed
/// in bits
///
/// @param align_in_bits the alignment of an instance of class_decl,
/// expressed in bits.
///
/// @param locus the source location of declaration point this class.
///
/// @param vis the visibility of instances of class_decl.
class_decl::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)
  : type_or_decl_base(env,
		      CLASS_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE
		      | ABSTRACT_SCOPE_TYPE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(env, name, locus, name, vis),
    type_base(env, size_in_bits, align_in_bits),
    class_or_union(env, name, size_in_bits, align_in_bits,
		   locus, vis),
    priv_(new priv(is_struct))
{
  runtime_type_instance(this);
}

/// A constructor for instances of @ref class_decl.
///
/// @param env the environment we are operating from.
///
/// @param name the name of the class.
///
/// @param size_in_bits the size of an instance of class_decl, expressed
/// in bits
///
/// @param align_in_bits the alignment of an instance of class_decl,
/// expressed in bits.
///
/// @param locus the source location of declaration point this class.
///
/// @param vis the visibility of instances of class_decl.
///
/// @param is_anonymous whether the newly created instance is
/// anonymous.
class_decl:: 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)
  : type_or_decl_base(env,
		      CLASS_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE
		      | ABSTRACT_SCOPE_TYPE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(env, name, locus,
	      // If the class is anonymous then by default it won't
	      // have a linkage name.  Also, the anonymous class does
	      // have an internal-only unique name that is generally
	      // not taken into account when comparing classes; such a
	      // unique internal-only name, when used as a linkage
	      // name might introduce spurious comparison false
	      // negatives.
	      /*linkage_name=*/ is_anonymous ? string() : name,
	      vis),
    type_base(env, size_in_bits, align_in_bits),
    class_or_union(env, name, size_in_bits, align_in_bits,
		   locus, vis),
  priv_(new priv(is_struct))
{
  runtime_type_instance(this);
  set_is_anonymous(is_anonymous);
}

/// A constuctor for instances of class_decl that represent a
/// declaration without definition.
///
/// @param env the environment we are operating from.
///
/// @param name the name of the class.
///
/// @param is_declaration_only a boolean saying whether the instance
/// represents a declaration only, or not.
class_decl::class_decl(const environment* env, const string& name,
		       bool is_struct, bool is_declaration_only)
  : type_or_decl_base(env,
		      CLASS_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE
		      | ABSTRACT_SCOPE_TYPE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(env, name, location(), name),
    type_base(env, 0, 0),
    class_or_union(env, name, is_declaration_only),
    priv_(new priv(is_struct))
{
  runtime_type_instance(this);
}

/// This method is invoked automatically right after the current
/// instance of @ref class_decl has been canonicalized.
///
/// Currently, the only thing it does is to sort the virtual member
/// functions vector.
void
class_decl::on_canonical_type_set()
{
  sort_virtual_mem_fns();

  for (class_decl::virtual_mem_fn_map_type::iterator i =
	 priv_->virtual_mem_fns_map_.begin();
       i != priv_->virtual_mem_fns_map_.end();
       ++i)
    sort_virtual_member_functions(i->second);
}

/// Set the "is-struct" flag of the class.
///
/// @param f the new value of the flag.
void
class_decl::is_struct(bool f)
{priv_->is_struct_ = f;}

/// Test if the class is a struct.
///
/// @return true iff the class is a struct.
bool
class_decl::is_struct() const
{return priv_->is_struct_;}

/// Add a base specifier to this class.
///
/// @param b the new base specifier.
void
class_decl::add_base_specifier(base_spec_sptr b)
{
  ABG_ASSERT(get_environment());
  ABG_ASSERT(b->get_environment() == get_environment());
  priv_->bases_.push_back(b);
  priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
  if (const environment* env = get_environment())
    b->set_environment(env);
}

/// Get the base specifiers for this class.
///
/// @return a vector of the base specifiers.
const class_decl::base_specs&
class_decl::get_base_specifiers() const
{return priv_->bases_;}

/// Find a base class of a given qualified name for the current class.
///
/// @param qualified_name the qualified name of the base class to look for.
///
/// @return a pointer to the @ref class_decl that represents the base
/// class of name @p qualified_name, if found.
class_decl_sptr
class_decl::find_base_class(const string& qualified_name) const
{
  unordered_map<string, base_spec_sptr>::iterator i =
    priv_->bases_map_.find(qualified_name);

  if (i != priv_->bases_map_.end())
    return i->second->get_base_class();

  return class_decl_sptr();
}

/// Get the virtual member functions of this class.
///
/// @param return a vector of the virtual member functions of this
/// class.
const class_decl::member_functions&
class_decl::get_virtual_mem_fns() const
{return priv_->virtual_mem_fns_;}

/// Get the map that associates a virtual table offset to the virtual
/// member functions with that virtual table offset.
///
/// Usually, there should be a 1:1 mapping between a given vtable
/// offset and virtual member functions of that vtable offset.  But
/// because of some implementation details, there can be several C++
/// destructor functions that are *generated* by compilers, for a
/// given destructor that is defined in the source code.  If the
/// destructor is virtual then those generated functions have some
/// DWARF attributes in common with the constructor that the user
/// actually defined in its source code.  Among those attributes are
/// the vtable offset of the destructor.
///
/// @return the map that associates a virtual table offset to the
/// virtual member functions with that virtual table offset.
const class_decl::virtual_mem_fn_map_type&
class_decl::get_virtual_mem_fns_map() const
{return priv_->virtual_mem_fns_map_;}

/// Sort the virtual member functions by their virtual index.
void
class_decl::sort_virtual_mem_fns()
{sort_virtual_member_functions(priv_->virtual_mem_fns_);}

/// Getter of the pretty representation of the current instance of
/// @ref class_decl.
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.
///
/// @param qualified_name if true, names emitted in the pretty
/// representation are fully qualified.
///
/// @return the pretty representaion for a class_decl.
string
class_decl::get_pretty_representation(bool internal,
				      bool qualified_name) const
{
  string cl = "class ";
  if (!internal && is_struct())
    cl = "struct ";

  // When computing the pretty representation for internal purposes,
  // if an anonymous class is named by a typedef, then consider that
  // it has a name, which is the typedef name.
  if (get_is_anonymous())
    {
      if (internal)
	return cl + get_type_name(this, qualified_name, /*internal=*/true);
      return get_class_or_union_flat_representation(this, "",
						    /*one_line=*/true,
						    internal);

    }

  string result = cl;
  if (qualified_name)
    result += get_qualified_name(internal);
  else
    result += get_name();

  return result;
}

decl_base_sptr
class_decl::insert_member_decl(decl_base_sptr d,
			       declarations::iterator before)
{
  if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
    add_member_function(f, public_access,
			/*is_virtual=*/false,
			/*vtable_offset=*/0,
			/*is_static=*/false,
			/*is_ctor=*/false,
			/*is_dtor=*/false,
			/*is_const=*/false);
  else
    d = class_or_union::insert_member_decl(d, before);

  return d;
}

/// The private data structure of class_decl::base_spec.
struct class_decl::base_spec::priv
{
  class_decl_wptr	base_class_;
  long			offset_in_bits_;
  bool			is_virtual_;

  priv(const class_decl_sptr& cl,
       long offset_in_bits,
       bool is_virtual)
    : base_class_(cl),
      offset_in_bits_(offset_in_bits),
      is_virtual_(is_virtual)
  {}
};

/// Constructor for base_spec instances.
///
/// @param base the base class to consider
///
/// @param a the access specifier of the base class.
///
/// @param offset_in_bits if positive or null, represents the offset
/// of the base in the layout of its containing type..  If negative,
/// means that the current base is not laid out in its containing type.
///
/// @param is_virtual if true, means that the current base class is
/// virtual in it's containing type.
class_decl::base_spec::base_spec(const class_decl_sptr& base,
				 access_specifier a,
				 long offset_in_bits,
				 bool is_virtual)
  : type_or_decl_base(base->get_environment(),
		      ABSTRACT_DECL_BASE),
    decl_base(base->get_environment(), base->get_name(), base->get_location(),
	      base->get_linkage_name(), base->get_visibility()),
    member_base(a),
    priv_(new priv(base, offset_in_bits, is_virtual))
{
  runtime_type_instance(this);
}

/// Get the base class referred to by the current base class
/// specifier.
///
/// @return the base class.
class_decl_sptr
class_decl::base_spec::get_base_class() const
{return priv_->base_class_.lock();}

/// Getter of the "is-virtual" proprerty of the base class specifier.
///
/// @return true iff this specifies a virtual base class.
bool
class_decl::base_spec::get_is_virtual() const
{return priv_->is_virtual_;}

/// Getter of the offset of the base.
///
/// @return the offset of the base.
long
class_decl::base_spec::get_offset_in_bits() const
{return priv_->offset_in_bits_;}

/// Calculate the hash value for a class_decl::base_spec.
///
/// @return the hash value.
size_t
class_decl::base_spec::get_hash() const
{
  base_spec::hash h;
  return h(*this);
}

/// Traverses an instance of @ref class_decl::base_spec, visiting all
/// the sub-types and decls that it might contain.
///
/// @param v the visitor that is used to visit every IR sub-node of
/// the current node.
///
/// @return true if either
///  - all the children nodes of the current IR node were traversed
///    and the calling code should keep going with the traversing.
///  - or the current IR node is already being traversed.
/// Otherwise, returning false means that the calling code should not
/// keep traversing the tree.
bool
class_decl::base_spec::traverse(ir_node_visitor& v)
{
  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      get_base_class()->traverse(v);
      visiting(false);
    }

  return v.visit_end(this);
}

/// Constructor for base_spec instances.
///
/// Note that this constructor is for clients that don't support RTTI
/// and that have a base class of type_base, but of dynamic type
/// class_decl.
///
/// @param base the base class to consider.  Must be a pointer to an
/// instance of class_decl
///
/// @param a the access specifier of the base class.
///
/// @param offset_in_bits if positive or null, represents the offset
/// of the base in the layout of its containing type..  If negative,
/// means that the current base is not laid out in its containing type.
///
/// @param is_virtual if true, means that the current base class is
/// virtual in it's containing type.
class_decl::base_spec::base_spec(const type_base_sptr& base,
				 access_specifier a,
				 long offset_in_bits,
				 bool is_virtual)
  : type_or_decl_base(base->get_environment(),
		      ABSTRACT_DECL_BASE),
    decl_base(base->get_environment(), get_type_declaration(base)->get_name(),
	      get_type_declaration(base)->get_location(),
	      get_type_declaration(base)->get_linkage_name(),
	      get_type_declaration(base)->get_visibility()),
    member_base(a),
    priv_(new priv(dynamic_pointer_cast<class_decl>(base),
		   offset_in_bits,
		   is_virtual))
{
  runtime_type_instance(this);
}

class_decl::base_spec::~base_spec() = default;

/// Compares two instances of @ref class_decl::base_spec.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const class_decl::base_spec& l,
       const class_decl::base_spec& r,
       change_kind* k)
{
  if (!l.member_base::operator==(r))
    {
      if (k)
	*k |= LOCAL_TYPE_CHANGE_KIND;
      ABG_RETURN_FALSE;
    }

  return (*l.get_base_class() == *r.get_base_class());
}

/// Comparison operator for @ref class_decl::base_spec.
///
/// @param other the instance of @ref class_decl::base_spec to compare
/// against.
///
/// @return true if the current instance of @ref class_decl::base_spec
/// equals @p other.
bool
class_decl::base_spec::operator==(const decl_base& other) const
{
  const class_decl::base_spec* o =
    dynamic_cast<const class_decl::base_spec*>(&other);

  if (!o)
    return false;

  return equals(*this, *o, 0);
}

/// Comparison operator for @ref class_decl::base_spec.
///
/// @param other the instance of @ref class_decl::base_spec to compare
/// against.
///
/// @return true if the current instance of @ref class_decl::base_spec
/// equals @p other.
bool
class_decl::base_spec::operator==(const member_base& other) const
{
  const class_decl::base_spec* o =
    dynamic_cast<const class_decl::base_spec*>(&other);
  if (!o)
    return false;

  return operator==(static_cast<const decl_base&>(*o));
}

mem_fn_context_rel::~mem_fn_context_rel()
{
}

/// A constructor for instances of method_decl.
///
/// @param name the name of the method.
///
/// @param type the type of the method.
///
/// @param declared_inline whether the method was
/// declared inline or not.
///
/// @param locus the source location of the method.
///
/// @param linkage_name the mangled name of the method.
///
/// @param vis the visibility of the method.
///
/// @param bind the binding of the method.
method_decl::method_decl(const string&		name,
			 method_type_sptr	type,
			 bool			declared_inline,
			 const location&	locus,
			 const string&		linkage_name,
			 visibility		vis,
			 binding		bind)
  : type_or_decl_base(type->get_environment(),
		      METHOD_DECL
		      | ABSTRACT_DECL_BASE
		      |FUNCTION_DECL),
    decl_base(type->get_environment(), name, locus, linkage_name, vis),
    function_decl(name, static_pointer_cast<function_type>(type),
		  declared_inline, locus, linkage_name, vis, bind)
{
  runtime_type_instance(this);
  set_context_rel(new mem_fn_context_rel(0));
  set_member_function_is_const(*this, type->get_is_const());
}

/// A constructor for instances of method_decl.
///
/// @param name the name of the method.
///
/// @param type the type of the method.  Must be an instance of
/// method_type.
///
/// @param declared_inline whether the method was
/// declared inline or not.
///
/// @param locus the source location of the method.
///
/// @param linkage_name the mangled name of the method.
///
/// @param vis the visibility of the method.
///
/// @param bind the binding of the method.
method_decl::method_decl(const string&		name,
			 function_type_sptr	type,
			 bool			declared_inline,
			 const location&	locus,
			 const string&		linkage_name,
			 visibility		vis,
			 binding		bind)
  : type_or_decl_base(type->get_environment(),
		      METHOD_DECL
		      | ABSTRACT_DECL_BASE
		      | FUNCTION_DECL),
    decl_base(type->get_environment(), name, locus, linkage_name, vis),
    function_decl(name, static_pointer_cast<function_type>
		  (dynamic_pointer_cast<method_type>(type)),
		  declared_inline, locus, linkage_name, vis, bind)
{
  runtime_type_instance(this);
  set_context_rel(new mem_fn_context_rel(0));
}

/// A constructor for instances of method_decl.
///
/// @param name the name of the method.
///
/// @param type the type of the method.  Must be an instance of
/// method_type.
///
/// @param declared_inline whether the method was
/// declared inline or not.
///
/// @param locus the source location of the method.
///
/// @param linkage_name the mangled name of the method.
///
/// @param vis the visibility of the method.
///
/// @param bind the binding of the method.
method_decl::method_decl(const string&		name,
			 type_base_sptr	type,
			 bool			declared_inline,
			 const location&	locus,
			 const string&		linkage_name,
			 visibility		vis,
			 binding		bind)
  : type_or_decl_base(type->get_environment(),
		      METHOD_DECL
		      | ABSTRACT_DECL_BASE
		      | FUNCTION_DECL),
    decl_base(type->get_environment(), name, locus, linkage_name, vis),
    function_decl(name, static_pointer_cast<function_type>
		  (dynamic_pointer_cast<method_type>(type)),
		  declared_inline, locus, linkage_name, vis, bind)
{
  runtime_type_instance(this);
  set_context_rel(new mem_fn_context_rel(0));
}

/// Set the linkage name of the method.
///
/// @param l the new linkage name of the method.
void
method_decl::set_linkage_name(const string& l)
{
  decl_base::set_linkage_name(l);
  // Update the linkage_name -> member function map of the containing
  // class declaration.
  if (!l.empty())
    {
      method_type_sptr t = get_type();
      class_or_union_sptr cl = t->get_class_type();
      method_decl_sptr m(this, sptr_utils::noop_deleter());
      cl->priv_->mem_fns_map_[l] = m;
    }
}

method_decl::~method_decl()
{}

const method_type_sptr
method_decl::get_type() const
{
  method_type_sptr result;
  if (function_decl::get_type())
    result = dynamic_pointer_cast<method_type>(function_decl::get_type());
  return result;
}

/// Set the containing class of a method_decl.
///
/// @param scope the new containing class_decl.
void
method_decl::set_scope(scope_decl* scope)
{
  if (!get_context_rel())
    set_context_rel(new mem_fn_context_rel(scope));
  else
    get_context_rel()->set_scope(scope);
}

/// Equality operator for @ref method_decl_sptr.
///
/// This is a deep equality operator, as it compares the @ref
/// method_decl that is pointed-to by the smart pointer.
///
/// @param l the left-hand side argument of the equality operator.
///
/// @param r the righ-hand side argument of the equality operator.
///
/// @return true iff @p l equals @p r.
bool
operator==(const method_decl_sptr& l, const method_decl_sptr& r)
{
  if (l.get() == r.get())
    return true;
  if (!!l != !!r)
    return false;

  return *l == *r;
}

/// Inequality operator for @ref method_decl_sptr.
///
/// This is a deep equality operator, as it compares the @ref
/// method_decl that is pointed-to by the smart pointer.
///
/// @param l the left-hand side argument of the equality operator.
///
/// @param r the righ-hand side argument of the equality operator.
///
/// @return true iff @p l differs from @p r.
bool
operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
{return !operator==(l, r);}

/// Test if a function_decl is actually a method_decl.
///
///@param d the @ref function_decl to consider.
///
/// @return the method_decl sub-object of @p d if inherits
/// a method_decl type.
method_decl*
is_method_decl(const type_or_decl_base *d)
{
  return dynamic_cast<method_decl*>
    (const_cast<type_or_decl_base*>(d));
}

/// Test if a function_decl is actually a method_decl.
///
///@param d the @ref function_decl to consider.
///
/// @return the method_decl sub-object of @p d if inherits
/// a method_decl type.
method_decl*
is_method_decl(const type_or_decl_base&d)
{return is_method_decl(&d);}

/// Test if a function_decl is actually a method_decl.
///
///@param d the @ref function_decl to consider.
///
/// @return the method_decl sub-object of @p d if inherits
/// a method_decl type.
method_decl_sptr
is_method_decl(const type_or_decl_base_sptr& d)
{return dynamic_pointer_cast<method_decl>(d);}

/// A "less than" functor to sort a vector of instances of
/// method_decl that are virtual.
struct virtual_member_function_less_than
{
  /// The less than operator.  First, it sorts the methods by their
  /// vtable index.  If they have the same vtable index, it sorts them
  /// by the name of their ELF symbol.  If they don't have elf
  /// symbols, it sorts them by considering their pretty
  /// representation.
  ///
  ///  Note that this method expects virtual methods.
  ///
  /// @param f the first method to consider.
  ///
  /// @param s the second method to consider.
  ///
  /// @return true if method @p is less than method @s.
  bool
  operator()(const method_decl& f,
	     const method_decl& s)
  {
    ABG_ASSERT(get_member_function_is_virtual(f));
    ABG_ASSERT(get_member_function_is_virtual(s));

    ssize_t f_offset = get_member_function_vtable_offset(f);
    ssize_t s_offset = get_member_function_vtable_offset(s);
    if (f_offset != s_offset) return f_offset < s_offset;

    string fn, sn;

    // If the functions have symbols, then compare their symbol-id
    // string.
    elf_symbol_sptr f_sym = f.get_symbol();
    elf_symbol_sptr s_sym = s.get_symbol();
    if ((!f_sym) != (!s_sym)) return !f_sym;
    if (f_sym && s_sym)
      {
	fn = f_sym->get_id_string();
	sn = s_sym->get_id_string();
	if (fn != sn) return fn < sn;
      }

    // Try the linkage names (important for destructors).
    fn = f.get_linkage_name();
    sn = s.get_linkage_name();
    if (fn != sn) return fn < sn;

    // None of the functions have symbols or linkage names that
    // distinguish them, so compare their pretty representation.
    fn = f.get_pretty_representation();
    sn = s.get_pretty_representation();
    if (fn != sn) return fn < sn;

    /// If it's just the file paths that are different then sort them
    /// too.
    string fn_filepath, sn_filepath;
    unsigned line = 0, column = 0;
    location fn_loc = f.get_location(), sn_loc = s.get_location();
    if (fn_loc)
      fn_loc.expand(fn_filepath, line, column);
    if (sn_loc)
      sn_loc.expand(sn_filepath, line, column);
    return fn_filepath < sn_filepath;
  }

  /// The less than operator.  First, it sorts the methods by their
  /// vtable index.  If they have the same vtable index, it sorts them
  /// by the name of their ELF symbol.  If they don't have elf
  /// symbols, it sorts them by considering their pretty
  /// representation.
  ///
  ///  Note that this method expects to take virtual methods.
  ///
  /// @param f the first method to consider.
  ///
  /// @param s the second method to consider.
  bool
  operator()(const method_decl_sptr f,
	     const method_decl_sptr s)
  {return operator()(*f, *s);}
}; // end struct virtual_member_function_less_than

/// Sort a vector of instances of virtual member functions.
///
/// @param mem_fns the vector of member functions to sort.
static void
sort_virtual_member_functions(class_decl::member_functions& mem_fns)
{
  virtual_member_function_less_than lt;
  std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
}

/// Add a member function to the current instance of @ref class_or_union.
///
/// @param f a method_decl to add to the current class.  This function
/// should not have been already added to a scope.
///
/// @param access the access specifier for the member function to add.
///
/// @param is_virtual if this is true then it means the function @p f
/// is a virtual function.  That also means that the current instance
/// of @ref class_or_union is actually an instance of @ref class_decl.
///
/// @param vtable_offset the offset of the member function in the
/// virtual table.  This parameter is taken into account only if @p
/// is_virtual is true.
///
/// @param is_static whether the member function is static.
///
/// @param is_ctor whether the member function is a constructor.
///
/// @param is_dtor whether the member function is a destructor.
///
/// @param is_const whether the member function is const.
void
class_or_union::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)
{
  add_member_function(f, a, is_static, is_ctor,
		      is_dtor, is_const);

  if (class_decl* klass = is_class_type(this))
    {
      set_member_function_is_virtual(f, is_virtual);
      if (is_virtual)
	{
	  set_member_function_vtable_offset(f, vtable_offset);
	  sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
	}
    }
}

/// When a virtual member function has seen its virtualness set by
/// set_member_function_is_virtual(), this function ensures that the
/// member function is added to the specific vectors and maps of
/// virtual member function of its class.
///
/// @param method the method to fixup.
void
fixup_virtual_member_function(method_decl_sptr method)
{
  if (!method || !get_member_function_is_virtual(method))
    return;

  class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());

  class_decl::member_functions::const_iterator m;
  for (m = klass->priv_->virtual_mem_fns_.begin();
       m != klass->priv_->virtual_mem_fns_.end();
       ++m)
    if (m->get() == method.get())
      break;
  if (m == klass->priv_->virtual_mem_fns_.end())
    klass->priv_->virtual_mem_fns_.push_back(method);

  // Build or udpate the map that associates a vtable offset to the
  // number of virtual member functions that "point" to it.
  ssize_t voffset = get_member_function_vtable_offset(method);
  if (voffset == -1)
    return;

  class_decl::virtual_mem_fn_map_type::iterator i =
    klass->priv_->virtual_mem_fns_map_.find(voffset);
  if (i == klass->priv_->virtual_mem_fns_map_.end())
    {
      class_decl::member_functions virtual_mem_fns_at_voffset;
      virtual_mem_fns_at_voffset.push_back(method);
      klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
    }
  else
    {
      for (m = i->second.begin() ; m != i->second.end(); ++m)
	if (m->get() == method.get())
	  break;
      if (m == i->second.end())
	i->second.push_back(method);
    }
}

/// Return true iff the class has no entity in its scope.
bool
class_decl::has_no_base_nor_member() const
{return priv_->bases_.empty() && has_no_member();}

/// Test if the current instance of @ref class_decl has virtual member
/// functions.
///
/// @return true iff the current instance of @ref class_decl has
/// virtual member functions.
bool
class_decl::has_virtual_member_functions() const
{return !get_virtual_mem_fns().empty();}

/// Test if the current instance of @ref class_decl has at least one
/// virtual base.
///
/// @return true iff the current instance of @ref class_decl has a
/// virtual member function.
bool
class_decl::has_virtual_bases() const
{
  for (base_specs::const_iterator b = get_base_specifiers().begin();
       b != get_base_specifiers().end();
       ++b)
    if ((*b)->get_is_virtual()
	|| (*b)->get_base_class()->has_virtual_bases())
      return true;

  return false;
}

/// Test if the current instance has a vtable.
///
/// This is only valid for a C++ program.
///
/// Basically this function checks if the class has either virtual
/// functions, or virtual bases.
bool
class_decl::has_vtable() const
{
  if (has_virtual_member_functions()
      || has_virtual_bases())
    return true;
  return false;
}

/// Get the highest vtable offset of all the virtual methods of the
/// class.
///
/// @return the highest vtable offset of all the virtual methods of
/// the class.
ssize_t
class_decl::get_biggest_vtable_offset() const
{
  ssize_t offset = -1;
  for (class_decl::virtual_mem_fn_map_type::const_iterator e =
	 get_virtual_mem_fns_map().begin();
       e != get_virtual_mem_fns_map().end();
       ++e)
    if (e->first > offset)
      offset = e->first;

  return offset;
}

/// Return the hash value for the current instance.
///
/// @return the hash value.
size_t
class_decl::get_hash() const
{
  class_decl::hash hash_class;
  return hash_class(this);
}

/// Test if two methods are equal without taking their symbol or
/// linkage name into account.
///
/// @param f the first method.
///
/// @param s the second method.
///
/// @return true iff @p f equals @p s without taking their linkage
/// name or symbol into account.
static bool
methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
				const method_decl_sptr& s)
{
  method_decl_sptr first = f, second = s;
  elf_symbol_sptr saved_first_elf_symbol =
    first->get_symbol();
  elf_symbol_sptr saved_second_elf_symbol =
    second->get_symbol();
  interned_string saved_first_linkage_name =
    first->get_linkage_name();
  interned_string saved_second_linkage_name =
    second->get_linkage_name();

  first->set_symbol(elf_symbol_sptr());
  first->set_linkage_name("");
  second->set_symbol(elf_symbol_sptr());
  second->set_linkage_name("");

  bool equal = *first == *second;

  first->set_symbol(saved_first_elf_symbol);
  first->set_linkage_name(saved_first_linkage_name);
  second->set_symbol(saved_second_elf_symbol);
  second->set_linkage_name(saved_second_linkage_name);

  return equal;
}

/// Test if a given method is equivalent to at least of other method
/// that is in a vector of methods.
///
/// Note that "equivalent" here means being equal without taking the
/// linkage name or the symbol of the methods into account.
///
/// This is a sub-routine of the 'equals' function that compares @ref
/// class_decl.
///
/// @param method the method to compare.
///
/// @param fns the vector of functions to compare @p method against.
///
/// @return true iff @p is equivalent to at least one method in @p
/// fns.
static bool
method_matches_at_least_one_in_vector(const method_decl_sptr& method,
				      const class_decl::member_functions& fns)
{
  for (class_decl::member_functions::const_iterator i = fns.begin();
       i != fns.end();
       ++i)
    // Note that the comparison must be done in this order: method ==
    //  *i This is to keep the consistency of the comparison.  It's
    //  important especially when doing type canonicalization.  The
    //  already canonicalize type is the left operand, and the type
    //  being canonicalized is the right operand.  This comes from the
    // code in type_base::get_canonical_type_for().
    if (methods_equal_modulo_elf_symbol(method, *i))
      return true;

  return false;
}

/// Cancel the canonical type that was propagated.
///
/// If we are in the process of comparing a type for the purpose of
/// canonicalization, and if that type has been the target of the
/// canonical type propagation optimization, then clear the propagated
/// canonical type.  See @ref OnTheFlyCanonicalization for more about
/// the canonical type  optimization
///
/// @param t the type to consider.
static bool
maybe_cancel_propagated_canonical_type(const class_or_union& t)
{
  const environment* env = t.get_environment();
  if (env && env->do_on_the_fly_canonicalization())
    if (is_type(&t)->priv_->canonical_type_propagated())
      {
	is_type(&t)->priv_->clear_propagated_canonical_type();
	env->priv_->remove_from_types_with_non_confirmed_propagated_ct(&t);
	return true;
      }
  return false;
}

/// Compares two instances of @ref class_decl.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const class_decl& l, const class_decl& r, change_kind* k)
{
  // if one of the classes is declaration-only then we take a fast
  // path here.
  if (l.get_is_declaration_only() || r.get_is_declaration_only())
    return equals(static_cast<const class_or_union&>(l),
		  static_cast<const class_or_union&>(r),
		  k);

  RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(static_cast<const class_or_union&>(l),
					   static_cast<const class_or_union&>(r));

  bool result = true;
  if (!equals(static_cast<const class_or_union&>(l),
	      static_cast<const class_or_union&>(r),
	      k))
    {
      result = false;
      if (!k)
	return result;
    }

  mark_types_as_being_compared(static_cast<const class_or_union&>(l),
			       static_cast<const class_or_union&>(r));

#define RETURN(value)							 \
  return return_comparison_result(static_cast<const class_or_union&>(l), \
				  static_cast<const class_or_union&>(r), \
				  value);

  // If comparing the class_or_union 'part' of the type led to
  // canonical type propagation, then cancel that because it's too
  // early to do that at this point.  We still need to compare bases
  // virtual members.
  maybe_cancel_propagated_canonical_type(r);

  // Compare bases.
    if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
      {
	result = false;
	if (k)
	  *k |= LOCAL_TYPE_CHANGE_KIND;
	else
	  RETURN(result);
      }

    for (class_decl::base_specs::const_iterator
	   b0 = l.get_base_specifiers().begin(),
	   b1 = r.get_base_specifiers().begin();
	 (b0 != l.get_base_specifiers().end()
	 && b1 != r.get_base_specifiers().end());
	 ++b0, ++b1)
      if (*b0 != *b1)
	{
	  result = false;
	  if (k)
	    {
	      if (!types_have_similar_structure((*b0)->get_base_class().get(),
						(*b1)->get_base_class().get()))
		*k |= LOCAL_TYPE_CHANGE_KIND;
	      else
		*k |= SUBTYPE_CHANGE_KIND;
	      break;
	    }
	  RETURN(result);
	}

    // Compare virtual member functions

    // We look at the map that associates a given vtable offset to a
    // vector of virtual member functions that point to that offset.
    //
    // This is because there are cases where several functions can
    // point to the same virtual table offset.
    //
    // This is usually the case for virtual destructors.  Even though
    // there can be only one virtual destructor declared in source
    // code, there are actually potentially up to three generated
    // functions for that destructor.  Some of these generated
    // functions can be clones of other functions that are among those
    // generated ones.  In any cases, they all have the same
    // properties, including the vtable offset property.

    // So, there should be the same number of different vtable
    // offsets, the size of two maps must be equals.
    if (l.get_virtual_mem_fns_map().size()
	!= r.get_virtual_mem_fns_map().size())
      {
	result = false;
	if (k)
	  *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	else
	  RETURN(result);
      }

    // Then, each virtual member function of a given vtable offset in
    // the first class type, must match an equivalent virtual member
    // function of a the same vtable offset in the second class type.
    //
    // By "match", I mean that the two virtual member function should
    // be equal if we don't take into account their symbol name or
    // their linkage name.  This is because two destructor functions
    // clones (for instance) might have different linkage name, but
    // are still equivalent if their other properties are the same.
    for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
	   l.get_virtual_mem_fns_map().begin();
	 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
	 ++first_v_fn_entry)
      {
	unsigned voffset = first_v_fn_entry->first;
	const class_decl::member_functions& first_vfns =
	  first_v_fn_entry->second;

	const class_decl::virtual_mem_fn_map_type::const_iterator
	  second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);

	if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
	  {
	    result = false;
	    if (k)
	      *k |= LOCAL_NON_TYPE_CHANGE_KIND;
	    RETURN(result);
	  }

	const class_decl::member_functions& second_vfns =
	  second_v_fn_entry->second;

	bool matches = false;
	for (class_decl::member_functions::const_iterator i =
	       first_vfns.begin();
	     i != first_vfns.end();
	     ++i)
	  if (method_matches_at_least_one_in_vector(*i, second_vfns))
	    {
	      matches = true;
	      break;
	    }

	if (!matches)
	  {
	    result = false;
	    if (k)
	      *k |= SUBTYPE_CHANGE_KIND;
	    else
	      RETURN(result);
	  }
      }

  RETURN(result);
#undef RETURN
}

/// Copy a method of a class into a new class.
///
/// @param klass the class into which the method is to be copied.
///
/// @param method the method to copy into @p klass.
///
/// @return the resulting newly copied method.
method_decl_sptr
copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}

/// Copy a method of a class into a new class.
///
/// @param klass the class into which the method is to be copied.
///
/// @param method the method to copy into @p klass.
///
/// @return the resulting newly copied method.
method_decl_sptr
copy_member_function(const class_decl_sptr& clazz, const method_decl* f)
{return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}

/// Comparison operator for @ref class_decl.
///
/// @param other the instance of @ref class_decl to compare against.
///
/// @return true iff the current instance of @ref class_decl equals @p
/// other.
bool
class_decl::operator==(const decl_base& other) const
{
  const class_decl* op = is_class_type(&other);
  if (!op)
    return false;

  // If this is a decl-only type (and thus with no canonical type),
  // use the canonical type of the definition, if any.
  const class_decl *l = 0;
  if (get_is_declaration_only())
    l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
  if (l == 0)
    l = this;

  ABG_ASSERT(l);

  // Likewise for the other type.
  const class_decl *r = 0;
  if (op->get_is_declaration_only())
    r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
  if (r == 0)
    r = op;

  ABG_ASSERT(r);

  return try_canonical_compare(l, r);
}

/// Equality operator for class_decl.
///
/// Re-uses the equality operator that takes a decl_base.
///
/// @param other the other class_decl to compare against.
///
/// @return true iff the current instance equals the other one.
bool
class_decl::operator==(const type_base& other) const
{
  const decl_base* o = is_decl(&other);
  if (!o)
    return false;
  return *this == *o;
}

/// Comparison operator for @ref class_decl.
///
/// @param other the instance of @ref class_decl to compare against.
///
/// @return true iff the current instance of @ref class_decl equals @p
/// other.
bool
class_decl::operator==(const class_decl& other) const
{
  const decl_base& o = other;
  return *this == o;
}

/// Turn equality of shared_ptr of class_decl into a deep equality;
/// that is, make it compare the pointed to objects too.
///
/// @param l the shared_ptr of class_decl on left-hand-side of the
/// equality.
///
/// @param r the shared_ptr of class_decl on right-hand-side of the
/// equality.
///
/// @return true if the class_decl pointed to by the shared_ptrs are
/// equal, false otherwise.
bool
operator==(const class_decl_sptr& l, const class_decl_sptr& r)
{
  if (l.get() == r.get())
    return true;
  if (!!l != !!r)
    return false;

  return *l == *r;
}

/// Turn inequality of shared_ptr of class_decl into a deep equality;
/// that is, make it compare the pointed to objects too.
///
/// @param l the shared_ptr of class_decl on left-hand-side of the
/// equality.
///
/// @param r the shared_ptr of class_decl on right-hand-side of the
/// equality.
///
/// @return true if the class_decl pointed to by the shared_ptrs are
/// different, false otherwise.
bool
operator!=(const class_decl_sptr& l, const class_decl_sptr& r)
{return !operator==(l, r);}

/// Turn equality of shared_ptr of class_or_union into a deep
/// equality; that is, make it compare the pointed to objects too.
///
/// @param l the left-hand-side operand of the operator
///
/// @param r the right-hand-side operand of the operator.
///
/// @return true iff @p l equals @p r.
bool
operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
{
  if (l.get() == r.get())
    return true;
  if (!!l != !!r)
    return false;

  return *l == *r;
}

/// Turn inequality of shared_ptr of class_or_union into a deep
/// equality; that is, make it compare the pointed to objects too.
///
/// @param l the left-hand-side operand of the operator
///
/// @param r the right-hand-side operand of the operator.
///
/// @return true iff @p l is different from @p r.
bool
operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
{return !operator==(l, r);}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance and on its
/// members.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
class_decl::traverse(ir_node_visitor& v)
{
  if (v.type_node_has_been_visited(this))
    return true;

  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      bool stop = false;

      for (base_specs::const_iterator i = get_base_specifiers().begin();
	   i != get_base_specifiers().end();
	   ++i)
	{
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }
	}

      if (!stop)
	for (data_members::const_iterator i = get_data_members().begin();
	     i != get_data_members().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }

      if (!stop)
	for (member_functions::const_iterator i= get_member_functions().begin();
	     i != get_member_functions().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }

      if (!stop)
	for (member_types::const_iterator i = get_member_types().begin();
	     i != get_member_types().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }

      if (!stop)
	for (member_function_templates::const_iterator i =
	       get_member_function_templates().begin();
	     i != get_member_function_templates().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }

      if (!stop)
	for (member_class_templates::const_iterator i =
	       get_member_class_templates().begin();
	     i != get_member_class_templates().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }
      visiting(false);
    }

  bool result = v.visit_end(this);
  v.mark_type_node_as_visited(this);
  return result;
}

/// Destructor of the @ref class_decl type.
class_decl::~class_decl()
{delete priv_;}

context_rel::~context_rel()
{}

bool
member_base::operator==(const member_base& o) const
{
  return (get_access_specifier() == o.get_access_specifier()
	  && get_is_static() == o.get_is_static());
}

/// Equality operator for smart pointers to @ref
/// class_decl::base_specs.
///
/// This compares the pointed-to objects.
///
/// @param l the first instance to consider.
///
/// @param r the second instance to consider.
///
/// @return true iff @p l equals @p r.
bool
operator==(const class_decl::base_spec_sptr& l,
	   const class_decl::base_spec_sptr& r)
{
  if (l.get() == r.get())
    return true;
  if (!!l != !!r)
    return false;

  return *l == static_cast<const decl_base&>(*r);
}

/// Inequality operator for smart pointers to @ref
/// class_decl::base_specs.
///
/// This compares the pointed-to objects.
///
/// @param l the first instance to consider.
///
/// @param r the second instance to consider.
///
/// @return true iff @p l is different from @p r.
bool
operator!=(const class_decl::base_spec_sptr& l,
	   const class_decl::base_spec_sptr& r)
{return !operator==(l, r);}

/// Test if an ABI artifact is a class base specifier.
///
/// @param tod the ABI artifact to consider.
///
/// @return a pointer to the @ref class_decl::base_spec sub-object of
/// @p tod iff it's a class base specifier.
class_decl::base_spec*
is_class_base_spec(const type_or_decl_base* tod)
{
  return dynamic_cast<class_decl::base_spec*>
    (const_cast<type_or_decl_base*>(tod));
}

/// Test if an ABI artifact is a class base specifier.
///
/// @param tod the ABI artifact to consider.
///
/// @return a pointer to the @ref class_decl::base_spec sub-object of
/// @p tod iff it's a class base specifier.
class_decl::base_spec_sptr
is_class_base_spec(type_or_decl_base_sptr tod)
{return dynamic_pointer_cast<class_decl::base_spec>(tod);}

bool
member_function_template::operator==(const member_base& other) const
{
  try
    {
      const member_function_template& o =
	dynamic_cast<const member_function_template&>(other);

      if (!(is_constructor() == o.is_constructor()
	    && is_const() == o.is_const()
	    && member_base::operator==(o)))
	return false;

      if (function_tdecl_sptr ftdecl = as_function_tdecl())
	{
	  function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
	  if (other_ftdecl)
	    return ftdecl->function_tdecl::operator==(*other_ftdecl);
	}
    }
  catch(...)
    {}
  return false;
}

/// Equality operator for smart pointers to @ref
/// member_function_template.  This is compares the
/// pointed-to instances.
///
/// @param l the first instance to consider.
///
/// @param r the second instance to consider.
///
/// @return true iff @p l equals @p r.
bool
operator==(const member_function_template_sptr& l,
	   const member_function_template_sptr& r)
{
  if (l.get() == r.get())
    return true;
  if (!!l != !!r)
    return false;

  return *l == *r;
}

/// Inequality operator for smart pointers to @ref
/// member_function_template.  This is compares the pointed-to
/// instances.
///
/// @param l the first instance to consider.
///
/// @param r the second instance to consider.
///
/// @return true iff @p l equals @p r.
bool
operator!=(const member_function_template_sptr& l,
	   const member_function_template_sptr& r)
{return !operator==(l, r);}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance and on its
/// underlying function template.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
member_function_template::traverse(ir_node_visitor& v)
{
  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      if (function_tdecl_sptr f = as_function_tdecl())
	f->traverse(v);
      visiting(false);
    }
  return v.visit_end(this);
}

/// Equality operator of the the @ref member_class_template class.
///
/// @param other the other @ref member_class_template to compare against.
///
/// @return true iff the current instance equals @p other.
bool
member_class_template::operator==(const member_base& other) const
{
  try
    {
      const member_class_template& o =
	dynamic_cast<const member_class_template&>(other);

      if (!member_base::operator==(o))
	return false;

      return as_class_tdecl()->class_tdecl::operator==(o);
    }
  catch(...)
    {return false;}
}

/// Comparison operator for the @ref member_class_template
/// type.
///
/// @param other the other instance of @ref
/// member_class_template to compare against.
///
/// @return true iff the two instances are equal.
bool
member_class_template::operator==(const member_class_template& other) const
{
  const decl_base* o = dynamic_cast<const decl_base*>(&other);
  return *this == *o;
}

/// Comparison operator for the @ref member_class_template
/// type.
///
/// @param l the first argument of the operator.
///
/// @param r the second argument of the operator.
///
/// @return true iff the two instances are equal.
bool
operator==(const member_class_template_sptr& l,
	   const member_class_template_sptr& r)
{
  if (l.get() == r.get())
    return true;
  if (!!l != !!r)
    return false;

  return *l == *r;
}

/// Inequality operator for the @ref member_class_template
/// type.
///
/// @param l the first argument of the operator.
///
/// @param r the second argument of the operator.
///
/// @return true iff the two instances are equal.
bool
operator!=(const member_class_template_sptr& l,
	   const member_class_template_sptr& r)
{return !operator==(l, r);}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance and on the class
/// pattern of the template.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
member_class_template::traverse(ir_node_visitor& v)
{
  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      if (class_tdecl_sptr t = as_class_tdecl())
	t->traverse(v);
      visiting(false);
    }
  return v.visit_end(this);
}

/// Streaming operator for class_decl::access_specifier.
///
/// @param o the output stream to serialize the access specifier to.
///
/// @param a the access specifier to serialize.
///
/// @return the output stream.
std::ostream&
operator<<(std::ostream& o, access_specifier a)
{
  string r;

  switch (a)
  {
  case no_access:
    r = "none";
    break;
  case private_access:
    r = "private";
    break;
  case protected_access:
    r = "protected";
    break;
  case public_access:
    r= "public";
    break;
  };
  o << r;
  return o;
}

/// Sets the static-ness property of a class member.
///
/// @param d the class member to set the static-ness property for.
/// Note that this must be a class member otherwise the function
/// aborts the current process.
///
/// @param s this must be true if the member is to be static, false
/// otherwise.
void
set_member_is_static(decl_base& d, bool s)
{
  ABG_ASSERT(is_member_decl(d));

  context_rel* c = d.get_context_rel();
  ABG_ASSERT(c);

  c->set_is_static(s);

  scope_decl* scope = d.get_scope();

  if (class_or_union* cl = is_class_or_union_type(scope))
    {
      if (var_decl* v = is_var_decl(&d))
	{
	  if (s)
	    // remove from the non-static data members
	    for (class_decl::data_members::iterator i =
		   cl->priv_->non_static_data_members_.begin();
		 i != cl->priv_->non_static_data_members_.end();
		 ++i)
	      {
		if ((*i)->get_name() == v->get_name())
		  {
		    cl->priv_->non_static_data_members_.erase(i);
		    break;
		  }
	      }
	  else
	    {
	      bool is_already_in_non_static_data_members = false;
	      for (class_or_union::data_members::iterator i =
		     cl->priv_->non_static_data_members_.begin();
		   i != cl->priv_->non_static_data_members_.end();
		   ++i)
	      {
		if ((*i)->get_name() == v->get_name())
		  {
		    is_already_in_non_static_data_members = true;
		    break;
		  }
	      }
	      if (!is_already_in_non_static_data_members)
		{
		  var_decl_sptr var;
		  // add to non-static data members.
		  for (class_or_union::data_members::const_iterator i =
			 cl->priv_->data_members_.begin();
		       i != cl->priv_->data_members_.end();
		       ++i)
		    {
		      if ((*i)->get_name() == v->get_name())
			{
			  var = *i;
			  break;
			}
		    }
		  ABG_ASSERT(var);
		  cl->priv_->non_static_data_members_.push_back(var);
		}
	    }
	}
    }
}

/// Sets the static-ness property of a class member.
///
/// @param d the class member to set the static-ness property for.
/// Note that this must be a class member otherwise the function
/// aborts the current process.
///
/// @param s this must be true if the member is to be static, false
/// otherwise.
void
set_member_is_static(const decl_base_sptr& d, bool s)
{set_member_is_static(*d, s);}

// </class_decl>

// <union_decl>

/// Constructor for the @ref union_decl type.
///
/// @param env the @ref environment we are operating from.
///
/// @param name the name of the union type.
///
/// @param size_in_bits the size of the union, in bits.
///
/// @param locus the location of the type.
///
/// @param vis the visibility of instances of @ref union_decl.
///
/// @param mbr_types the member types of the union.
///
/// @param data_mbrs the data members of the union.
///
/// @param member_fns the member functions of the union.
union_decl::union_decl(const environment* env, const string& name,
		       size_t size_in_bits, const location& locus,
		       visibility vis, member_types& mbr_types,
		       data_members& data_mbrs, member_functions& member_fns)
  : type_or_decl_base(env,
		      UNION_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    decl_base(env, name, locus, name, vis),
    type_base(env, size_in_bits, 0),
    class_or_union(env, name, size_in_bits, 0,
		   locus, vis, mbr_types, data_mbrs, member_fns)
{
  runtime_type_instance(this);
}

/// Constructor for the @ref union_decl type.
///
/// @param env the @ref environment we are operating from.
///
/// @param name the name of the union type.
///
/// @param size_in_bits the size of the union, in bits.
///
/// @param locus the location of the type.
///
/// @param vis the visibility of instances of @ref union_decl.
///
/// @param mbr_types the member types of the union.
///
/// @param data_mbrs the data members of the union.
///
/// @param member_fns the member functions of the union.
///
/// @param is_anonymous whether the newly created instance is
/// anonymous.
union_decl::union_decl(const environment* env, const string& name,
		       size_t size_in_bits, const location& locus,
		       visibility vis, member_types& mbr_types,
		       data_members& data_mbrs, member_functions& member_fns,
		       bool is_anonymous)
  : type_or_decl_base(env,
		      UNION_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE),
    decl_base(env, name, locus,
	      // If the class is anonymous then by default it won't
	      // have a linkage name.  Also, the anonymous class does
	      // have an internal-only unique name that is generally
	      // not taken into account when comparing classes; such a
	      // unique internal-only name, when used as a linkage
	      // name might introduce spurious comparison false
	      // negatives.
	      /*linkage_name=*/is_anonymous ? string() : name,
	      vis),
    type_base(env, size_in_bits, 0),
    class_or_union(env, name, size_in_bits, 0,
		   locus, vis, mbr_types, data_mbrs, member_fns)
{
  runtime_type_instance(this);
  set_is_anonymous(is_anonymous);
}

/// Constructor for the @ref union_decl type.
///
/// @param env the @ref environment we are operating from.
///
/// @param name the name of the union type.
///
/// @param size_in_bits the size of the union, in bits.
///
/// @param locus the location of the type.
///
/// @param vis the visibility of instances of @ref union_decl.
union_decl::union_decl(const environment* env, const string& name,
		       size_t size_in_bits, const location& locus,
		       visibility vis)
  : type_or_decl_base(env,
		      UNION_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE
		      | ABSTRACT_SCOPE_TYPE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(env, name, locus, name, vis),
    type_base(env, size_in_bits, 0),
    class_or_union(env, name, size_in_bits,
		   0, locus, vis)
{
  runtime_type_instance(this);
}

/// Constructor for the @ref union_decl type.
///
/// @param env the @ref environment we are operating from.
///
/// @param name the name of the union type.
///
/// @param size_in_bits the size of the union, in bits.
///
/// @param locus the location of the type.
///
/// @param vis the visibility of instances of @ref union_decl.
///
/// @param is_anonymous whether the newly created instance is
/// anonymous.
union_decl::union_decl(const environment* env, const string& name,
		       size_t size_in_bits, const location& locus,
		       visibility vis, bool is_anonymous)
  : type_or_decl_base(env,
		      UNION_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE
		      | ABSTRACT_SCOPE_TYPE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(env, name, locus,
	      // If the class is anonymous then by default it won't
	      // have a linkage name.  Also, the anonymous class does
	      // have an internal-only unique name that is generally
	      // not taken into account when comparing classes; such a
	      // unique internal-only name, when used as a linkage
	      // name might introduce spurious comparison false
	      // negatives.
	      /*linkage_name=*/is_anonymous ? string() : name,
	      vis),
    type_base(env, size_in_bits, 0),
    class_or_union(env, name, size_in_bits,
		   0, locus, vis)
{
  runtime_type_instance(this);
  set_is_anonymous(is_anonymous);
}

/// Constructor for the @ref union_decl type.
///
/// @param env the @ref environment we are operating from.
///
/// @param name the name of the union type.
///
/// @param is_declaration_only a boolean saying whether the instance
/// represents a declaration only, or not.
union_decl::union_decl(const environment* env,
		       const string& name,
		       bool is_declaration_only)
  : type_or_decl_base(env,
		      UNION_TYPE
		      | ABSTRACT_TYPE_BASE
		      | ABSTRACT_DECL_BASE
		      | ABSTRACT_SCOPE_TYPE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(env, name, location(), name),
    type_base(env, 0, 0),
    class_or_union(env, name, is_declaration_only)
{
  runtime_type_instance(this);
}

/// Getter of the pretty representation of the current instance of
/// @ref union_decl.
///
/// @param internal set to true if the call is intended to get a
/// representation of the decl (or type) for the purpose of canonical
/// type comparison.  This is mainly used in the function
/// type_base::get_canonical_type_for().
///
/// In other words if the argument for this parameter is true then the
/// call is meant for internal use (for technical use inside the
/// library itself), false otherwise.  If you don't know what this is
/// for, then set it to false.
///
/// @param qualified_name if true, names emitted in the pretty
/// representation are fully qualified.
///
/// @return the pretty representaion for a union_decl.
string
union_decl::get_pretty_representation(bool internal,
				      bool qualified_name) const
{
  string repr;
  if (get_is_anonymous())
    {
      if (internal)
	repr = string("union ") +
	  get_type_name(this, qualified_name, /*internal=*/true);
      else
	repr = get_class_or_union_flat_representation(this, "",
						      /*one_line=*/true,
						      internal);
    }
  else
    {
      repr = "union ";
      if (qualified_name)
	repr += get_qualified_name(internal);
      else
	repr += get_name();
    }

  return repr;
}

/// Comparison operator for @ref union_decl.
///
/// @param other the instance of @ref union_decl to compare against.
///
/// @return true iff the current instance of @ref union_decl equals @p
/// other.
bool
union_decl::operator==(const decl_base& other) const
{
  const union_decl* op = dynamic_cast<const union_decl*>(&other);
  if (!op)
    return false;
  return try_canonical_compare(this, op);
}

/// Equality operator for union_decl.
///
/// Re-uses the equality operator that takes a decl_base.
///
/// @param other the other union_decl to compare against.
///
/// @return true iff the current instance equals the other one.
bool
union_decl::operator==(const type_base& other) const
{
  const decl_base *o = dynamic_cast<const decl_base*>(&other);
  if (!o)
    return false;
  return *this == *o;
}

/// Comparison operator for @ref union_decl.
///
/// @param other the instance of @ref union_decl to compare against.
///
/// @return true iff the current instance of @ref union_decl equals @p
/// other.
bool
union_decl::operator==(const union_decl& other) const
{
  const decl_base& o = other;
  return *this == o;
}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance and on its
/// members.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
union_decl::traverse(ir_node_visitor& v)
{
  if (v.type_node_has_been_visited(this))
    return true;

  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      bool stop = false;

      if (!stop)
	for (data_members::const_iterator i = get_data_members().begin();
	     i != get_data_members().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }

      if (!stop)
	for (member_functions::const_iterator i= get_member_functions().begin();
	     i != get_member_functions().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }

      if (!stop)
	for (member_types::const_iterator i = get_member_types().begin();
	     i != get_member_types().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }

      if (!stop)
	for (member_function_templates::const_iterator i =
	       get_member_function_templates().begin();
	     i != get_member_function_templates().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }

      if (!stop)
	for (member_class_templates::const_iterator i =
	       get_member_class_templates().begin();
	     i != get_member_class_templates().end();
	     ++i)
	  if (!(*i)->traverse(v))
	    {
	      stop = true;
	      break;
	    }
      visiting(false);
    }

  bool result = v.visit_end(this);
  v.mark_type_node_as_visited(this);
  return result;
}

/// Destructor of the @ref union_decl type.
union_decl::~union_decl()
{}

/// Compares two instances of @ref union_decl.
///
/// If the two intances are different, set a bitfield to give some
/// insight about the kind of differences there are.
///
/// @param l the first artifact of the comparison.
///
/// @param r the second artifact of the comparison.
///
/// @param k a pointer to a bitfield that gives information about the
/// kind of changes there are between @p l and @p r.  This one is set
/// iff @p k is non-null and the function returns false.
///
/// Please note that setting k to a non-null value does have a
/// negative performance impact because even if @p l and @p r are not
/// equal, the function keeps up the comparison in order to determine
/// the different kinds of ways in which they are different.
///
/// @return true if @p l equals @p r, false otherwise.
bool
equals(const union_decl& l, const union_decl& r, change_kind* k)
{
  bool result = equals(static_cast<const class_or_union&>(l),
		       static_cast<const class_or_union&>(r),
		       k);
  ABG_RETURN(result);
}

/// Copy a method of a @ref union_decl into a new @ref
/// union_decl.
///
/// @param t the @ref union_decl into which the method is to be copied.
///
/// @param method the method to copy into @p t.
///
/// @return the resulting newly copied method.
method_decl_sptr
copy_member_function(const union_decl_sptr& union_type,
		     const method_decl_sptr& f)
{return copy_member_function(union_type, f.get());}

/// Copy a method of a @ref union_decl into a new @ref
/// union_decl.
///
/// @param t the @ref union_decl into which the method is to be copied.
///
/// @param method the method to copy into @p t.
///
/// @return the resulting newly copied method.
method_decl_sptr
copy_member_function(const union_decl_sptr& union_type,
		     const method_decl* f)
{
  const class_or_union_sptr t = union_type;
  return copy_member_function(t, f);
}

/// Turn equality of shared_ptr of union_decl into a deep equality;
/// that is, make it compare the pointed to objects too.
///
/// @param l the left-hand-side operand of the operator
///
/// @param r the right-hand-side operand of the operator.
///
/// @return true iff @p l equals @p r.
bool
operator==(const union_decl_sptr& l, const union_decl_sptr& r)
{
  if (l.get() == r.get())
    return true;
  if (!!l != !!r)
    return false;

  return *l == *r;
}

/// Turn inequality of shared_ptr of union_decl into a deep equality;
/// that is, make it compare the pointed to objects too.
///
/// @param l the left-hand-side operand of the operator
///
/// @param r the right-hand-side operand of the operator.
///
/// @return true iff @p l is different from @p r.
bool
operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
{return !operator==(l, r);}
// </union_decl>

// <template_decl stuff>

/// Data type of the private data of the @template_decl type.
class template_decl::priv
{
  friend class template_decl;

  std::list<template_parameter_sptr> parms_;
public:

  priv()
  {}
}; // end class template_decl::priv

/// Add a new template parameter to the current instance of @ref
/// template_decl.
///
/// @param p the new template parameter to add.
void
template_decl::add_template_parameter(const template_parameter_sptr p)
{priv_->parms_.push_back(p);}

/// Get the list of template parameters of the current instance of
/// @ref template_decl.
///
/// @return the list of template parameters.
const std::list<template_parameter_sptr>&
template_decl::get_template_parameters() const
{return priv_->parms_;}

/// Constructor.
///
/// @param env the environment we are operating from.
///
/// @param name the name of the template decl.
///
/// @param locus the source location where the template declaration is
/// defined.
///
/// @param vis the visibility of the template declaration.
template_decl::template_decl(const environment* env,
			     const string& name,
			     const location& locus,
			     visibility vis)
  : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
    decl_base(env, name, locus, /*mangled_name=*/"", vis),
    priv_(new priv)
{
  runtime_type_instance(this);
}

/// Destructor.
template_decl::~template_decl()
{}

/// Equality operator.
///
/// @param o the other instance to compare against.
///
/// @return true iff @p equals the current instance.
bool
template_decl::operator==(const template_decl& o) const
{
  try
    {
      list<shared_ptr<template_parameter> >::const_iterator t0, t1;
      for (t0 = get_template_parameters().begin(),
	     t1 = o.get_template_parameters().begin();
	   (t0 != get_template_parameters().end()
	    && t1 != o.get_template_parameters().end());
	   ++t0, ++t1)
	{
	  if (**t0 != **t1)
	    return false;
	}

      if (t0 != get_template_parameters().end()
	  || t1 != o.get_template_parameters().end())
	return false;

      return true;
    }
  catch(...)
    {return false;}
}

// </template_decl stuff>

//<template_parameter>

/// The type of the private data of the @ref template_parameter type.
class template_parameter::priv
{
  friend class template_parameter;

  unsigned index_;
  template_decl_wptr template_decl_;
  mutable bool hashing_started_;
  mutable bool comparison_started_;

  priv();

public:

  priv(unsigned index, template_decl_sptr enclosing_template_decl)
    : index_(index),
      template_decl_(enclosing_template_decl),
      hashing_started_(),
      comparison_started_()
  {}
}; // end class template_parameter::priv

template_parameter::template_parameter(unsigned	 index,
				       template_decl_sptr enclosing_template)
  : priv_(new priv(index, enclosing_template))
  {}

unsigned
template_parameter::get_index() const
{return priv_->index_;}

const template_decl_sptr
template_parameter::get_enclosing_template_decl() const
{return priv_->template_decl_.lock();}

bool
template_parameter::get_hashing_has_started() const
{return priv_->hashing_started_;}

void
template_parameter::set_hashing_has_started(bool f) const
{priv_->hashing_started_ = f;}

bool
template_parameter::operator==(const template_parameter& o) const
{
  if (get_index() != o.get_index())
    return false;

  if (priv_->comparison_started_)
    return true;

  bool result = false;

  // Avoid inifite loops due to the fact that comparison the enclosing
  // template decl might lead to comparing this very same template
  // parameter with another one ...
  priv_->comparison_started_ = true;

  if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
    ;
  else if (get_enclosing_template_decl()
	   && (*get_enclosing_template_decl()
	       != *o.get_enclosing_template_decl()))
    ;
  else
    result = true;

  priv_->comparison_started_ = false;

  return result;
}

/// Inequality operator.
///
/// @param other the other instance to compare against.
///
/// @return true iff the other instance is different from the current
/// one.
bool
template_parameter::operator!=(const template_parameter& other) const
{return !operator==(other);}

/// Destructor.
template_parameter::~template_parameter()
{}

/// The type of the private data of the @ref type_tparameter type.
class type_tparameter::priv
{
  friend class type_tparameter;
}; // end class type_tparameter::priv

/// Constructor of the @ref type_tparameter type.
///
/// @param index the index the type template parameter.
///
/// @param enclosing_tdecl the enclosing template declaration.
///
/// @param name the name of the template parameter.
///
/// @param locus the location of the declaration of this type template
/// parameter.
type_tparameter::type_tparameter(unsigned		index,
				 template_decl_sptr	enclosing_tdecl,
				 const string&		name,
				 const location&	locus)
  : type_or_decl_base(enclosing_tdecl->get_environment(),
		      ABSTRACT_DECL_BASE
		      | ABSTRACT_TYPE_BASE
		      | BASIC_TYPE),
    decl_base(enclosing_tdecl->get_environment(), name, locus),
    type_base(enclosing_tdecl->get_environment(), 0, 0),
    type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
    template_parameter(index, enclosing_tdecl),
    priv_(new priv)
{
  runtime_type_instance(this);
}

bool
type_tparameter::operator==(const type_base& other) const
{
  if (!type_decl::operator==(other))
    return false;

  try
    {
      const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
      return template_parameter::operator==(o);
    }
  catch (...)
    {return false;}
}

bool
type_tparameter::operator==(const template_parameter& other) const
{
  try
    {
      const type_base& o = dynamic_cast<const type_base&>(other);
      return *this == o;
    }
  catch(...)
    {return false;}
}

bool
type_tparameter::operator==(const type_tparameter& other) const
{return *this == static_cast<const type_base&>(other);}

type_tparameter::~type_tparameter()
{}

/// The type of the private data of the @ref non_type_tparameter type.
class non_type_tparameter::priv
{
  friend class non_type_tparameter;

  type_base_wptr type_;

  priv();

public:

  priv(type_base_sptr type)
    : type_(type)
  {}
}; // end class non_type_tparameter::priv

/// The constructor for the @ref non_type_tparameter type.
///
/// @param index the index of the template parameter.
///
/// @param enclosing_tdecl the enclosing template declaration that
/// holds this parameter parameter.
///
/// @param name the name of the template parameter.
///
/// @param type the type of the template parameter.
///
/// @param locus the location of the declaration of this template
/// parameter.
non_type_tparameter::non_type_tparameter(unsigned		index,
					 template_decl_sptr	enclosing_tdecl,
					 const string&		name,
					 type_base_sptr	type,
					 const location&	locus)
  : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
    decl_base(type->get_environment(), name, locus, ""),
    template_parameter(index, enclosing_tdecl),
    priv_(new priv(type))
{
  runtime_type_instance(this);
}

/// Getter for the type of the template parameter.
///
/// @return the type of the template parameter.
const type_base_sptr
non_type_tparameter::get_type() const
{return priv_->type_.lock();}

/// Get the hash value of the current instance.
///
/// @return the hash value.
size_t
non_type_tparameter::get_hash() const
{
  non_type_tparameter::hash hash_tparm;
  return hash_tparm(this);
}

bool
non_type_tparameter::operator==(const decl_base& other) const
{
  if (!decl_base::operator==(other))
    return false;

  try
    {
      const non_type_tparameter& o =
	dynamic_cast<const non_type_tparameter&>(other);
      return (template_parameter::operator==(o)
	      && get_type() == o.get_type());
    }
  catch(...)
    {return false;}
}

bool
non_type_tparameter::operator==(const template_parameter& other) const
{
  try
    {
      const decl_base& o = dynamic_cast<const decl_base&>(other);
      return *this == o;
    }
  catch(...)
    {return false;}
}

non_type_tparameter::~non_type_tparameter()
{}

// <template_tparameter stuff>

/// Type of the private data of the @ref template_tparameter type.
class template_tparameter::priv
{
}; //end class template_tparameter::priv

/// Constructor for the @ref template_tparameter.
///
/// @param index the index of the template parameter.
///
/// @param enclosing_tdecl the enclosing template declaration.
///
/// @param name the name of the template parameter.
///
/// @param locus the location of the declaration of the template
/// parameter.
template_tparameter::template_tparameter(unsigned		index,
					 template_decl_sptr	enclosing_tdecl,
					 const string&		name,
					 const location&	locus)
  : type_or_decl_base(enclosing_tdecl->get_environment(),
		      ABSTRACT_DECL_BASE
		      | ABSTRACT_TYPE_BASE
		      | BASIC_TYPE),
    decl_base(enclosing_tdecl->get_environment(), name, locus),
    type_base(enclosing_tdecl->get_environment(), 0, 0),
    type_decl(enclosing_tdecl->get_environment(), name,
	      0, 0, locus, name, VISIBILITY_DEFAULT),
    type_tparameter(index, enclosing_tdecl, name, locus),
    template_decl(enclosing_tdecl->get_environment(), name, locus),
    priv_(new priv)
{
  runtime_type_instance(this);
}

bool
template_tparameter::operator==(const type_base& other) const
{
  try
    {
      const template_tparameter& o =
	dynamic_cast<const template_tparameter&>(other);
      return (type_tparameter::operator==(o)
	      && template_decl::operator==(o));
    }
  catch(...)
    {return false;}
}

bool
template_tparameter::operator==(const template_parameter& o) const
{
  try
    {
      const template_tparameter& other =
	dynamic_cast<const template_tparameter&>(o);
      return *this == static_cast<const type_base&>(other);
    }
  catch(...)
    {return false;}
}

bool
template_tparameter::operator==(const template_decl& o) const
{
  try
    {
      const template_tparameter& other =
	dynamic_cast<const template_tparameter&>(o);
      return type_base::operator==(other);
    }
  catch(...)
    {return false;}
}

template_tparameter::~template_tparameter()
{}

// </template_tparameter stuff>

// <type_composition stuff>

/// The type of the private data of the @ref type_composition type.
class type_composition::priv
{
  friend class type_composition;

  type_base_wptr type_;

  // Forbid this.
  priv();

public:

  priv(type_base_wptr type)
    : type_(type)
  {}
}; //end class type_composition::priv

/// Constructor for the @ref type_composition type.
///
/// @param index the index of the template type composition.
///
/// @param tdecl the enclosing template parameter that owns the
/// composition.
///
/// @param t the resulting type.
type_composition::type_composition(unsigned		index,
				   template_decl_sptr	tdecl,
				   type_base_sptr	t)
  : type_or_decl_base(tdecl->get_environment(),
		      ABSTRACT_DECL_BASE),
    decl_base(tdecl->get_environment(), "", location()),
    template_parameter(index, tdecl),
    priv_(new priv(t))
{
  runtime_type_instance(this);
}

/// Getter for the resulting composed type.
///
/// @return the composed type.
const type_base_sptr
type_composition::get_composed_type() const
{return priv_->type_.lock();}

/// Setter for the resulting composed type.
///
/// @param t the composed type.
void
type_composition::set_composed_type(type_base_sptr t)
{priv_->type_ = t;}

/// Get the hash value for the current instance.
///
/// @return the hash value.
size_t
type_composition::get_hash() const
{
  type_composition::hash hash_type_composition;
  return hash_type_composition(this);
}

type_composition::~type_composition()
{}

// </type_composition stuff>

//</template_parameter stuff>

// <function_template>

class function_tdecl::priv
{
  friend class function_tdecl;

  function_decl_sptr pattern_;
  binding binding_;

  priv();

public:

  priv(function_decl_sptr pattern, binding bind)
    : pattern_(pattern), binding_(bind)
  {}

  priv(binding bind)
    : binding_(bind)
  {}
}; // end class function_tdecl::priv

/// Constructor for a function template declaration.
///
/// @param env the environment we are operating from.
///
/// @param locus the location of the declaration.
///
/// @param vis the visibility of the declaration.  This is the
/// visibility the functions instantiated from this template are going
/// to have.
///
/// @param bind the binding of the declaration.  This is the binding
/// the functions instantiated from this template are going to have.
function_tdecl::function_tdecl(const environment*	env,
			       const location&		locus,
			       visibility		vis,
			       binding			bind)
  : type_or_decl_base(env,
		      ABSTRACT_DECL_BASE
		      | TEMPLATE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(env, "", locus, "", vis),
    template_decl(env, "", locus, vis),
    scope_decl(env, "", locus),
    priv_(new priv(bind))
{
  runtime_type_instance(this);
}

/// Constructor for a function template declaration.
///
/// @param pattern the pattern of the template.
///
/// @param locus the location of the declaration.
///
/// @param vis the visibility of the declaration.  This is the
/// visibility the functions instantiated from this template are going
/// to have.
///
/// @param bind the binding of the declaration.  This is the binding
/// the functions instantiated from this template are going to have.
function_tdecl::function_tdecl(function_decl_sptr	pattern,
			       const location&		locus,
			       visibility		vis,
			       binding			bind)
  : type_or_decl_base(pattern->get_environment(),
		      ABSTRACT_DECL_BASE
		      | TEMPLATE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(pattern->get_environment(), pattern->get_name(), locus,
	      pattern->get_name(), vis),
    template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
    scope_decl(pattern->get_environment(), pattern->get_name(), locus),
    priv_(new priv(pattern, bind))
{
  runtime_type_instance(this);
}

/// Set a new pattern to the function template.
///
/// @param p the new pattern.
void
function_tdecl::set_pattern(function_decl_sptr p)
{
  priv_->pattern_ = p;
  add_decl_to_scope(p, this);
  set_name(p->get_name());
}

/// Get the pattern of the function template.
///
/// @return the pattern.
function_decl_sptr
function_tdecl::get_pattern() const
{return priv_->pattern_;}

/// Get the binding of the function template.
///
/// @return the binding
decl_base::binding
function_tdecl::get_binding() const
{return priv_->binding_;}

/// Comparison operator for the @ref function_tdecl type.
///
/// @param other the other instance of @ref function_tdecl to compare against.
///
/// @return true iff the two instance are equal.
bool
function_tdecl::operator==(const decl_base& other) const
{
  const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
  if (o)
    return *this == *o;
  return false;
}

/// Comparison operator for the @ref function_tdecl type.
///
/// @param other the other instance of @ref function_tdecl to compare against.
///
/// @return true iff the two instance are equal.
bool
function_tdecl::operator==(const template_decl& other) const
{
  const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
  if (o)
    return *this == *o;
  return false;
}

/// Comparison operator for the @ref function_tdecl type.
///
/// @param o the other instance of @ref function_tdecl to compare against.
///
/// @return true iff the two instance are equal.
bool
function_tdecl::operator==(const function_tdecl& o) const
{
  if (!(get_binding() == o.get_binding()
	&& template_decl::operator==(o)
	&& scope_decl::operator==(o)
	&& !!get_pattern() == !!o.get_pattern()))
    return false;

  if (get_pattern())
    return (*get_pattern() == *o.get_pattern());

  return true;
}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance and on the
/// function pattern of the template.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
function_tdecl::traverse(ir_node_visitor&v)
{
  if (visiting())
    return true;

  if (!v.visit_begin(this))
    {
      visiting(true);
      if (get_pattern())
	get_pattern()->traverse(v);
      visiting(false);
    }
  return v.visit_end(this);
}

function_tdecl::~function_tdecl()
{}

// </function_template>

// <class template>

/// Type of the private data of the the @ref class_tdecl type.
class class_tdecl::priv
{
  friend class class_tdecl;
  class_decl_sptr pattern_;

public:

  priv()
  {}

  priv(class_decl_sptr pattern)
    : pattern_(pattern)
  {}
}; // end class class_tdecl::priv

/// Constructor for the @ref class_tdecl type.
///
/// @param env the environment we are operating from.
///
/// @param locus the location of the declaration of the class_tdecl
/// type.
///
/// @param vis the visibility of the instance of class instantiated
/// from this template.
class_tdecl::class_tdecl(const environment*	env,
			 const location&	locus,
			 visibility		vis)
  : type_or_decl_base(env,
		      ABSTRACT_DECL_BASE
		      | TEMPLATE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(env, "", locus, "", vis),
    template_decl(env, "", locus, vis),
    scope_decl(env, "", locus),
    priv_(new priv)
{
  runtime_type_instance(this);
}

/// Constructor for the @ref class_tdecl type.
///
/// @param pattern The details of the class template. This must NOT be a
/// null pointer.  If you really this to be null, please use the
/// constructor above instead.
///
/// @param locus the source location of the declaration of the type.
///
/// @param vis the visibility of the instances of class instantiated
/// from this template.
class_tdecl::class_tdecl(class_decl_sptr	pattern,
			 const location&	locus,
			 visibility		vis)
  : type_or_decl_base(pattern->get_environment(),
		      ABSTRACT_DECL_BASE
		      | TEMPLATE_DECL
		      | ABSTRACT_SCOPE_DECL),
    decl_base(pattern->get_environment(), pattern->get_name(),
	      locus, pattern->get_name(), vis),
    template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
    scope_decl(pattern->get_environment(), pattern->get_name(), locus),
    priv_(new priv(pattern))
{
  runtime_type_instance(this);
}

/// Setter of the pattern of the template.
///
/// @param p the new template.
void
class_tdecl::set_pattern(class_decl_sptr p)
{
  priv_->pattern_ = p;
  add_decl_to_scope(p, this);
  set_name(p->get_name());
}

/// Getter of the pattern of the template.
///
/// @return p the new template.
class_decl_sptr
class_tdecl::get_pattern() const
{return priv_->pattern_;}

bool
class_tdecl::operator==(const decl_base& other) const
{
  try
    {
      const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);

      if (!(template_decl::operator==(o)
	    && scope_decl::operator==(o)
	    && !!get_pattern() == !!o.get_pattern()))
	return false;

      if (!get_pattern() || !o.get_pattern())
	return true;

      return get_pattern()->decl_base::operator==(*o.get_pattern());
    }
  catch(...) {}
  return false;
}

bool
class_tdecl::operator==(const template_decl& other) const
{
  try
    {
      const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
      return *this == static_cast<const decl_base&>(o);
    }
  catch(...)
    {return false;}
}

bool
class_tdecl::operator==(const class_tdecl& o) const
{return *this == static_cast<const decl_base&>(o);}

/// This implements the ir_traversable_base::traverse pure virtual
/// function.
///
/// @param v the visitor used on the current instance and on the class
/// pattern of the template.
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
class_tdecl::traverse(ir_node_visitor&v)
{
  if (visiting())
    return true;

  if (v.visit_begin(this))
    {
      visiting(true);
      if (class_decl_sptr pattern = get_pattern())
	pattern->traverse(v);
      visiting(false);
    }
  return v.visit_end(this);
}

class_tdecl::~class_tdecl()
{}

/// This visitor checks if a given type as non-canonicalized sub
/// types.
class non_canonicalized_subtype_detector : public ir::ir_node_visitor
{
  type_base* type_;
  type_base* has_non_canonical_type_;

private:
  non_canonicalized_subtype_detector();

public:
  non_canonicalized_subtype_detector(type_base* type)
    : type_(type),
      has_non_canonical_type_()
  {}

  /// Return true if the visitor detected that there is a
  /// non-canonicalized sub-type.
  ///
  /// @return true if the visitor detected that there is a
  /// non-canonicalized sub-type.
  type_base*
  has_non_canonical_type() const
  {return has_non_canonical_type_;}

  /// The intent of this visitor handler is to avoid looking into
  /// sub-types of member functions of the type we are traversing.
  bool
  visit_begin(function_decl* f)
  {
    // Do not look at sub-types of non-virtual member functions.
    if (is_member_function(f)
	&& get_member_function_is_virtual(*f))
      return false;
    return true;
  }

  /// When visiting a sub-type, if it's *NOT* been canonicalized, set
  /// the 'has_non_canonical_type' flag.  And in any case, when
  /// visiting a sub-type, do not visit its children nodes.  So this
  /// function only goes to the level below the level of the top-most
  /// type.
  ///
  /// @return true if we are at the same level as the top-most type,
  /// otherwise return false.
  bool
  visit_begin(type_base* t)
  {
    if (t != type_)
      {
	if (!t->get_canonical_type())
	  // We are looking a sub-type of 'type_' which has no
	  // canonical type.  So tada! we found one!  Get out right
	  // now with the trophy.
	  has_non_canonical_type_ = t;

	return false;
      }
    return true;
  }

  /// When we are done visiting a sub-type, if it's been flagged as
  /// been non-canonicalized, then stop the traversing.
  ///
  /// Otherwise, keep going.
  ///
  /// @return false iff the sub-type that has been visited is
  /// non-canonicalized.
  bool
  visit_end(type_base* )
  {
    if (has_non_canonical_type_)
      return false;
    return true;
  }
}; //end class non_canonicalized_subtype_detector

/// Test if a type has sub-types that are non-canonicalized.
///
/// @param t the type which sub-types to consider.
///
/// @return true if a type has sub-types that are non-canonicalized.
type_base*
type_has_non_canonicalized_subtype(type_base_sptr t)
{
  if (!t)
    return 0;

  non_canonicalized_subtype_detector v(t.get());
  t->traverse(v);
  return v.has_non_canonical_type();
}

/// Tests if the change of a given type effectively comes from just
/// its sub-types.  That is, if the type has changed but its type name
/// hasn't changed, then the change of the type mostly likely is a
/// sub-type change.
///
/// @param t_v1 the first version of the type.
///
/// @param t_v2 the second version of the type.
///
/// @return true iff the type changed and the change is about its
/// sub-types.
bool
type_has_sub_type_changes(const type_base_sptr t_v1,
			  const type_base_sptr t_v2)
{
  type_base_sptr t1 = strip_typedef(t_v1);
  type_base_sptr t2 = strip_typedef(t_v2);

  string repr1 = get_pretty_representation(t1, /*internal=*/false),
    repr2 = get_pretty_representation(t2, /*internal=*/false);
  return (t1 != t2 && repr1 == repr2);
}

/// Make sure that the life time of a given (smart pointer to a) type
/// is the same as the life time of the libabigail library.
///
/// @param t the type to consider.
void
keep_type_alive(type_base_sptr t)
{
  environment* env = t->get_environment();
  ABG_ASSERT(env);
  env->priv_->extra_live_types_.push_back(t);
}

/// Hash an ABI artifact that is either a type or a decl.
///
/// This function intends to provides the fastest possible hashing for
/// types and decls, while being completely correct.
///
/// Note that if the artifact is a type and if it has a canonical
/// type, the hash value is going to be the pointer value of the
/// canonical type.  Otherwise, this function computes a hash value
/// for the type by recursively walking the type members.  This last
/// code path is possibly *very* slow and should only be used when
/// only handful of types are going to be hashed.
///
/// If the artifact is a decl, then a combination of the hash of its
/// type and the hash of the other properties of the decl is computed.
///
/// @param tod the type or decl to hash.
///
/// @return the resulting hash value.
size_t
hash_type_or_decl(const type_or_decl_base *tod)
{
  size_t result = 0;

  if (tod == 0)
    ;
  else if (const type_base* t = is_type(tod))
    result = hash_type(t);
  else if (const decl_base* d = is_decl(tod))
    {
      if (var_decl* v = is_var_decl(d))
	{
	  ABG_ASSERT(v->get_type());
	  size_t h = hash_type_or_decl(v->get_type());
	  string repr = v->get_pretty_representation(/*internal=*/true);
	  std::hash<string> hash_string;
	  h = hashing::combine_hashes(h, hash_string(repr));
	  result = h;
	}
      else if (function_decl* f = is_function_decl(d))
	{
	  ABG_ASSERT(f->get_type());
	  size_t h = hash_type_or_decl(f->get_type());
	  string repr = f->get_pretty_representation(/*internal=*/true);
	  std::hash<string> hash_string;
	  h = hashing::combine_hashes(h, hash_string(repr));
	  result = h;
	}
      else if (function_decl::parameter* p = is_function_parameter(d))
	{
	  type_base_sptr parm_type = p->get_type();
	  ABG_ASSERT(parm_type);
	  std::hash<bool> hash_bool;
	  std::hash<unsigned> hash_unsigned;
	  size_t h = hash_type_or_decl(parm_type);
	  h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
	  h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
	  result = h;
	}
      else if (class_decl::base_spec *bs = is_class_base_spec(d))
	{
	  member_base::hash hash_member;
	  std::hash<size_t> hash_size;
	  std::hash<bool> hash_bool;
	  type_base_sptr type = bs->get_base_class();
	  size_t h = hash_type_or_decl(type);
	  h = hashing::combine_hashes(h, hash_member(*bs));
	  h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
	  h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
	  result = h;
	}
      else
	// This is a *really* *SLOW* path.  If it shows up in a
	// performance profile, I bet it'd be a good idea to try to
	// avoid it altogether.
	result = d->get_hash();
    }
  else
    // We should never get here.
    abort();
  return result;
}

/// Hash an ABI artifact that is either a type.
///
/// This function intends to provides the fastest possible hashing for
/// types while being completely correct.
///
/// Note that if the type artifact has a canonical type, the hash
/// value is going to be the pointer value of the canonical type.
/// Otherwise, this function computes a hash value for the type by
/// recursively walking the type members.  This last code path is
/// possibly *very* slow and should only be used when only handful of
/// types are going to be hashed.
///
/// @param t the type or decl to hash.
///
/// @return the resulting hash value.
size_t
hash_type(const type_base *t)
{return hash_as_canonical_type_or_constant(t);}

/// Hash an ABI artifact that is either a type of a decl.
///
/// @param tod the ABI artifact to hash.
///
/// @return the hash value of the ABI artifact.
size_t
hash_type_or_decl(const type_or_decl_base_sptr& tod)
{return hash_type_or_decl(tod.get());}

/// Test if a given type is allowed to be non canonicalized
///
/// This is a subroutine of hash_as_canonical_type_or_constant.
///
/// For now, the only types allowed to be non canonicalized in the
/// system are decl-only class/union, the void type and variadic
/// parameter types.
///
/// @return true iff @p t is a one of the only types allowed to be
/// non-canonicalized in the system.
bool
is_non_canonicalized_type(const type_base *t)
{
  if (!t)
    return true;

  const environment* env = t->get_environment();
  return (is_declaration_only_class_or_union_type(t)
	  || env->is_void_type(t)
	  || env->is_variadic_parameter_type(t));
}

/// For a given type, return its exemplar type.
///
/// For a given type, its exemplar type is either its canonical type
/// or the canonical type of the definition type of a given
/// declaration-only type.  If the neither of those two types exist,
/// then the exemplar type is the given type itself.
///
/// @param type the input to consider.
///
/// @return the exemplar type.
type_base*
get_exemplar_type(const type_base* type)
{
  if (decl_base * decl = is_decl(type))
    {
      // Make sure we get the real definition of a decl-only type.
      decl = look_through_decl_only(decl);
      type = is_type(decl);
      ABG_ASSERT(type);
    }
  type_base *exemplar = type->get_naked_canonical_type();
  if (!exemplar)
    {
      // The type has no canonical type.  Let's be sure that it's one
      // of those rare types that are allowed to be non canonicalized
      // in the system.
      exemplar = const_cast<type_base*>(type);
      ABG_ASSERT(is_non_canonicalized_type(exemplar));
    }
  return exemplar;
}

/// Test if a given type is allowed to be non canonicalized
///
/// This is a subroutine of hash_as_canonical_type_or_constant.
///
/// For now, the only types allowed to be non canonicalized in the
/// system are decl-only class/union and the void type.
///
/// @return true iff @p t is a one of the only types allowed to be
/// non-canonicalized in the system.
bool
is_non_canonicalized_type(const type_base_sptr& t)
{return is_non_canonicalized_type(t.get());}

/// Hash a type by either returning the pointer value of its canonical
/// type or by returning a constant if the type doesn't have a
/// canonical type.
///
/// This is a subroutine of hash_type.
///
/// @param t the type to consider.
///
/// @return the hash value.
static size_t
hash_as_canonical_type_or_constant(const type_base *t)
{
  type_base *canonical_type = 0;

  if (t)
    canonical_type = t->get_naked_canonical_type();

  if (!canonical_type)
    {
      // If the type doesn't have a canonical type, maybe it's because
      // it's a declaration-only type?  If that's the case, let's try
      // to get the canonical type of the definition of this
      // declaration.
      decl_base *decl = is_decl(t);
      if (decl
	  && decl->get_is_declaration_only()
	  && decl->get_naked_definition_of_declaration())
	{
	  type_base *definition =
	    is_type(decl->get_naked_definition_of_declaration());
	  ABG_ASSERT(definition);
	  canonical_type = definition->get_naked_canonical_type();
	}
    }

  if (canonical_type)
    return reinterpret_cast<size_t>(canonical_type);

  // If we reached this point, it means we are seeing a
  // non-canonicalized type.  It must be a decl-only class or a void
  // type, otherwise it means that for some weird reason, the type
  // hasn't been canonicalized.  It should be!
  ABG_ASSERT(is_non_canonicalized_type(t));

  return 0xDEADBABE;
}

/// Test if the pretty representation of a given @ref function_decl is
/// lexicographically less then the pretty representation of another
/// @ref function_decl.
///
/// @param f the first @ref function_decl to consider for comparison.
///
/// @param s the second @ref function_decl to consider for comparison.
///
/// @return true iff the pretty representation of @p f is
/// lexicographically less than the pretty representation of @p s.
bool
function_decl_is_less_than(const function_decl &f, const function_decl &s)
{
  string fr = f.get_pretty_representation_of_declarator(),
    sr = s.get_pretty_representation_of_declarator();

  if (fr != sr)
    return fr < sr;

  fr = f.get_pretty_representation(/*internal=*/true),
    sr = s.get_pretty_representation(/*internal=*/true);

  if (fr != sr)
    return fr < sr;

  if (f.get_symbol())
    fr = f.get_symbol()->get_id_string();
  else if (!f.get_linkage_name().empty())
    fr = f.get_linkage_name();

  if (s.get_symbol())
    sr = s.get_symbol()->get_id_string();
  else if (!s.get_linkage_name().empty())
    sr = s.get_linkage_name();

  return fr < sr;
}

/// Test if two types have similar structures, even though they are
/// (or can be) different.
///
/// const and volatile qualifiers are completely ignored.
///
/// typedef are resolved to their definitions; their names are ignored.
///
/// Two indirect types (pointers or references) have similar structure
/// if their underlying types are of the same kind and have the same
/// name.  In the indirect types case, the size of the underlying type
/// does not matter.
///
/// Two direct types (i.e, non indirect) have a similar structure if
/// they have the same kind, name and size.  Two class types have
/// similar structure if they have the same name, size, and if the
/// types of their data members have similar types.
///
/// @param first the first type to consider.
///
/// @param second the second type to consider.
///
/// @param indirect_type whether to do an indirect comparison
///
/// @return true iff @p first and @p second have similar structures.
bool
types_have_similar_structure(const type_base_sptr& first,
			     const type_base_sptr& second,
			     bool indirect_type)
{
  // This wrapper function is used during comparisons. It is called by and its
  // wrappee calls the main equality functions, possibly resulting in a
  // multiplication of the cost of comparison.

  // This is a convenient place to add some memoisation to avoid at
  // least some of the duplicate calls. This is safe only if pointer
  // addresses are never reused.
  using Arguments = std::tuple<const type_base*, const type_base*, bool>;

  struct Hasher {
    size_t operator()(const Arguments& arguments) const {
      const auto& [first, second, indirect] = arguments;
      size_t seed = 0;
      std::hash<const type_base*> h;
      combine_hash(seed, h(first));
      combine_hash(seed, h(second));
      combine_hash(seed, indirect);
      return seed;
    }
    static void combine_hash(size_t& seed, size_t hash) {
      seed ^= hash + 0x9e3779b97f4a7c15 + (seed << 12) + (seed >> 4);
    }
  };

  static std::unordered_map<Arguments, abg_compat::optional<bool>, Hasher> memo;

  const Arguments t{first.get(), second.get(), indirect_type};
  const auto& [it, inserted] = memo.insert({t, {}});
  auto& result = it->second;
  if (inserted)
    result = types_have_similar_structure(
        std::get<0>(t), std::get<1>(t), std::get<2>(t));
  else
    ABG_ASSERT(result.has_value());
  return *result;
}

/// Test if two types have similar structures, even though they are
/// (or can be) different.
///
/// const and volatile qualifiers are completely ignored.
///
/// typedef are resolved to their definitions; their names are ignored.
///
/// Two indirect types (pointers, references or arrays) have similar
/// structure if their underlying types are of the same kind and have
/// the same name.  In the indirect types case, the size of the
/// underlying type does not matter.
///
/// Two direct types (i.e, non indirect) have a similar structure if
/// they have the same kind, name and size.  Two class types have
/// similar structure if they have the same name, size, and if the
/// types of their data members have similar types.
///
/// @param first the first type to consider.
///
/// @param second the second type to consider.
///
/// @param indirect_type if true, then consider @p first and @p
/// second as being underlying types of indirect types.  Meaning that
/// their size does not matter.
///
/// @return true iff @p first and @p second have similar structures.
bool
types_have_similar_structure(const type_base* first,
			     const type_base* second,
			     bool indirect_type)
{
  if (!!first != !!second)
    return false;

  if (!first)
    return false;

  // Treat typedefs purely as type aliases and ignore CV-qualifiers.
  first = peel_qualified_or_typedef_type(first);
  second = peel_qualified_or_typedef_type(second);

  // Eliminate all but N of the N^2 comparison cases. This also guarantees the
  // various ty2 below cannot be null.
  if (typeid(*first) != typeid(*second))
    return false;

  // Peel off matching pointers.
  if (const pointer_type_def* ty1 = is_pointer_type(first))
    {
      const pointer_type_def* ty2 = is_pointer_type(second);
      return types_have_similar_structure(ty1->get_pointed_to_type(),
					  ty2->get_pointed_to_type(),
					  /*indirect_type=*/true);
    }

  // Peel off matching references.
  if (const reference_type_def* ty1 = is_reference_type(first))
    {
      const reference_type_def* ty2 = is_reference_type(second);
      if (ty1->is_lvalue() != ty2->is_lvalue())
	return false;
      return types_have_similar_structure(ty1->get_pointed_to_type(),
					  ty2->get_pointed_to_type(),
					  /*indirect_type=*/true);
    }

  if (const type_decl* ty1 = is_type_decl(first))
    {
      const type_decl* ty2 = is_type_decl(second);
      if (!indirect_type)
	if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
	  return false;

      return ty1->get_name() == ty2->get_name();
    }

  if (const enum_type_decl* ty1 = is_enum_type(first))
    {
      const enum_type_decl* ty2 = is_enum_type(second);
      if (!indirect_type)
	if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
	  return false;

      return (get_name(ty1->get_underlying_type())
	      == get_name(ty2->get_underlying_type()));
    }

  if (const class_decl* ty1 = is_class_type(first))
    {
      const class_decl* ty2 = is_class_type(second);
      if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
	  && ty1->get_name() != ty2->get_name())
	return false;

      if (!indirect_type)
	{
	  if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
	      || (ty1->get_non_static_data_members().size()
		  != ty2->get_non_static_data_members().size()))
	    return false;

	  for (class_or_union::data_members::const_iterator
		 i = ty1->get_non_static_data_members().begin(),
		 j = ty2->get_non_static_data_members().begin();
	       (i != ty1->get_non_static_data_members().end()
		&& j != ty2->get_non_static_data_members().end());
	       ++i, ++j)
	    {
	      var_decl_sptr dm1 = *i;
	      var_decl_sptr dm2 = *j;
	      if (!types_have_similar_structure(dm1->get_type().get(),
						dm2->get_type().get(),
						indirect_type))
		return false;
	    }
	}

      return true;
    }

  if (const union_decl* ty1 = is_union_type(first))
    {
      const union_decl* ty2 = is_union_type(second);
      if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
	  && ty1->get_name() != ty2->get_name())
	return false;

      if (!indirect_type)
	return ty1->get_size_in_bits() == ty2->get_size_in_bits();

      return true;
    }

  if (const array_type_def* ty1 = is_array_type(first))
    {
      const array_type_def* ty2 = is_array_type(second);
      // TODO: Handle int[5][2] vs int[2][5] better.
      if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
	  || ty1->get_dimension_count() != ty2->get_dimension_count()
	  || !types_have_similar_structure(ty1->get_element_type(),
					   ty2->get_element_type(),
					   /*indirect_type=*/true))
	return false;

      return true;
    }

  if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
    {
      const array_type_def::subrange_type *ty2 = is_subrange_type(second);
      if (ty1->get_upper_bound() != ty2->get_upper_bound()
	  || ty1->get_lower_bound() != ty2->get_lower_bound()
	  || ty1->get_language() != ty2->get_language()
	  || !types_have_similar_structure(ty1->get_underlying_type(),
					   ty2->get_underlying_type(),
					   indirect_type))
	return false;

      return true;
    }

  if (const function_type* ty1 = is_function_type(first))
    {
      const function_type* ty2 = is_function_type(second);
      if (!types_have_similar_structure(ty1->get_return_type(),
					ty2->get_return_type(),
					indirect_type))
	return false;

      if (ty1->get_parameters().size() != ty2->get_parameters().size())
	return false;

      for (function_type::parameters::const_iterator
	     i = ty1->get_parameters().begin(),
	     j = ty2->get_parameters().begin();
	   (i != ty1->get_parameters().end()
	    && j != ty2->get_parameters().end());
	   ++i, ++j)
	if (!types_have_similar_structure((*i)->get_type(),
					  (*j)->get_type(),
					  indirect_type))
	  return false;

      return true;
    }

  // All kinds of type should have been handled at this point.
  ABG_ASSERT_NOT_REACHED;

  return false;
}

/// Look for a data member of a given class, struct or union type and
/// return it.
///
/// The data member is designated by its name.
///
/// @param type the class, struct or union type to consider.
///
/// @param dm_name the name of the data member to lookup.
///
/// @return the data member iff it was found in @type or NULL if no
/// data member with that name was found.
const var_decl*
lookup_data_member(const type_base* type,
		   const char* dm_name)

{
  class_or_union *cou = is_class_or_union_type(type);
  if (!cou)
    return 0;

  return cou->find_data_member(dm_name).get();
}

/// Get the function parameter designated by its index.
///
/// Note that the first function parameter has index 0.
///
/// @param fun the function to consider.
///
/// @param parm_index the index of the function parameter to get.
///
/// @return the function parameter designated by its index, of NULL if
/// no function parameter with that index was found.
const function_decl::parameter*
get_function_parameter(const decl_base* fun,
		       unsigned parm_index)
{
  function_decl* fn = is_function_decl(fun);
  if (!fn)
    return 0;

  const function_decl::parameters &parms = fn->get_type()->get_parameters();
  if (parms.size() <= parm_index)
    return 0;

  return parms[parm_index].get();
}

bool
ir_traversable_base::traverse(ir_node_visitor&)
{return true;}

// <ir_node_visitor stuff>

/// The private data structure of the ir_node_visitor type.
struct ir_node_visitor::priv
{
  pointer_set visited_ir_nodes;
  bool allow_visiting_already_visited_type_node;

  priv()
    : allow_visiting_already_visited_type_node(true)
  {}
}; // end struct ir_node_visitory::priv

/// Default Constructor of the ir_node_visitor type.
ir_node_visitor::ir_node_visitor()
  : priv_(new priv)
{}

ir_node_visitor::~ir_node_visitor() = default;

/// Set if the walker using this visitor is allowed to re-visit a type
/// node that was previously visited or not.
///
/// @param f if true, then the walker using this visitor is allowed to
/// re-visit a type node that was previously visited.
void
ir_node_visitor::allow_visiting_already_visited_type_node(bool f)
{priv_->allow_visiting_already_visited_type_node = f;}

/// Get if the walker using this visitor is allowed to re-visit a type
/// node that was previously visited or not.
///
/// @return true iff the walker using this visitor is allowed to
/// re-visit a type node that was previously visited.
bool
ir_node_visitor::allow_visiting_already_visited_type_node() const
{return priv_->allow_visiting_already_visited_type_node;}

/// Mark a given type node as having been visited.
///
/// Note that for this function to work, the type node must have been
/// canonicalized.  Otherwise the process is aborted.
///
/// @param p the type to mark as having been visited.
void
ir_node_visitor::mark_type_node_as_visited(type_base *p)
{
  if (allow_visiting_already_visited_type_node())
    return;

  if (p == 0 || type_node_has_been_visited(p))
    return;

  type_base* canonical_type = p->get_naked_canonical_type();
  ABG_ASSERT(canonical_type);

  size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
  priv_->visited_ir_nodes.insert(canonical_ptr_value);
}

/// Un-mark all visited type nodes.
///
/// That is, no type node is going to be considered as having been
/// visited anymore.
///
/// In other words, after invoking this funciton,
/// ir_node_visitor::type_node_has_been_visited() is going to return
/// false on all type nodes.
void
ir_node_visitor::forget_visited_type_nodes()
{priv_->visited_ir_nodes.clear();}

/// Test if a given type node has been marked as visited.
///
/// @param p the type node to consider.
///
/// @return true iff the type node @p p has been marked as visited by
/// the function ir_node_visitor::mark_type_node_as_visited.
bool
ir_node_visitor::type_node_has_been_visited(type_base* p) const
{
  if (allow_visiting_already_visited_type_node())
    return false;

  if (p == 0)
    return false;

  type_base *canonical_type = p->get_naked_canonical_type();
  ABG_ASSERT(canonical_type);

  size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
  pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
  if (it == priv_->visited_ir_nodes.end())
    return false;

  return true;
}

bool
ir_node_visitor::visit_begin(decl_base*)
{return true;}

bool
ir_node_visitor::visit_end(decl_base*)
{return true;}

bool
ir_node_visitor::visit_begin(scope_decl*)
{return true;}

bool
ir_node_visitor::visit_end(scope_decl*)
{return true;}

bool
ir_node_visitor::visit_begin(type_base*)
{return true;}

bool
ir_node_visitor::visit_end(type_base*)
{return true;}

bool
ir_node_visitor::visit_begin(scope_type_decl* t)
{return visit_begin(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_end(scope_type_decl* t)
{return visit_end(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_begin(type_decl* t)
{return visit_begin(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_end(type_decl* t)
{return visit_end(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_begin(namespace_decl* d)
{return visit_begin(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_end(namespace_decl* d)
{return visit_end(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_begin(qualified_type_def* t)
{return visit_begin(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_end(qualified_type_def* t)
{return visit_end(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_begin(pointer_type_def* t)
{return visit_begin(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_end(pointer_type_def* t)
{return visit_end(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_begin(reference_type_def* t)
{return visit_begin(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_end(reference_type_def* t)
{return visit_end(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_begin(array_type_def* t)
{return visit_begin(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_end(array_type_def* t)
{return visit_end(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
{return visit_begin(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_end(array_type_def::subrange_type* t)
{return visit_end(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_begin(enum_type_decl* t)
{return visit_begin(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_end(enum_type_decl* t)
{return visit_end(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_begin(typedef_decl* t)
{return visit_begin(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_end(typedef_decl* t)
{return visit_end(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_begin(function_type* t)
{return visit_begin(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_end(function_type* t)
{return visit_end(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_begin(var_decl* d)
{return visit_begin(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_end(var_decl* d)
{return visit_end(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_begin(function_decl* d)
{return visit_begin(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_end(function_decl* d)
{return visit_end(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_begin(function_decl::parameter* d)
{return visit_begin(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_end(function_decl::parameter* d)
{return visit_end(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_begin(function_tdecl* d)
{return visit_begin(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_end(function_tdecl* d)
{return visit_end(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_begin(class_tdecl* d)
{return visit_begin(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_end(class_tdecl* d)
{return visit_end(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_begin(class_or_union* t)
{return visit_begin(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_end(class_or_union* t)
{return visit_end(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_begin(class_decl* t)
{return visit_begin(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_end(class_decl* t)
{return visit_end(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_begin(union_decl* t)
{return visit_begin(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_end(union_decl* t)
{return visit_end(static_cast<type_base*>(t));}

bool
ir_node_visitor::visit_begin(class_decl::base_spec* d)
{return visit_begin(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_end(class_decl::base_spec* d)
{return visit_end(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_begin(member_function_template* d)
{return visit_begin(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_end(member_function_template* d)
{return visit_end(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_begin(member_class_template* d)
{return visit_begin(static_cast<decl_base*>(d));}

bool
ir_node_visitor::visit_end(member_class_template* d)
{return visit_end(static_cast<decl_base*>(d));}

// </ir_node_visitor stuff>

// <debugging facilities>

/// Generate a different string at each invocation.
///
/// @return the resulting string.
static string
get_next_string()
{
  static __thread size_t counter;
  ++counter;
  std::ostringstream o;
  o << counter;
  return o.str();
}

/// Convenience typedef for a hash map of pointer to function_decl and
/// string.
typedef unordered_map<const function_decl*, string,
		      function_decl::hash,
		      function_decl::ptr_equal> fns_to_str_map_type;

/// Return a string associated to a given function.  Two functions
/// that compare equal would yield the same string, as far as this
/// routine is concerned.  And two functions that are different would
/// yield different strings.
///
/// This is used to debug core diffing issues on functions.  The
/// sequence of strings can be given to the 'testdiff2' program that
/// is in the tests/ directory of the source tree, to reproduce core
/// diffing issues on string and thus ease the debugging.
///
/// @param fn the function to generate a string for.
///
/// @param m the function_decl* <-> string map to be used by this
/// function to generate strings associated to a function.
///
/// @return the resulting string.
static const string&
fn_to_str(const function_decl* fn,
	  fns_to_str_map_type& m)
{
  fns_to_str_map_type::const_iterator i = m.find(fn);
  if (i != m.end())
    return i->second;
  string s = get_next_string();
  return m[fn]= s;
}

/// Generate a sequence of string that matches a given sequence of
/// function.  In the resulting sequence, each function is "uniquely
/// representated" by a string.  For instance, if the same function "foo"
/// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
/// we don't care about the actual string) would appear at index 1 and 3.
///
/// @param begin the beginning of the sequence of functions to consider.
///
/// @param end the end of the sequence of functions.  This points to
/// one-passed-the-end of the actual sequence.
///
/// @param m the function_decl* <-> string map to be used by this
/// function to generate strings associated to a function.
///
/// @param o the output stream where to emit the generated list of
/// strings to.
static void
fns_to_str(vector<function_decl*>::const_iterator begin,
	   vector<function_decl*>::const_iterator end,
	   fns_to_str_map_type& m,
	   std::ostream& o)
{
  vector<function_decl*>::const_iterator i;
  for (i = begin; i != end; ++i)
    o << "'" << fn_to_str(*i, m) << "' ";
}

/// For each sequence of functions given in argument, generate a
/// sequence of string that matches a given sequence of function.  In
/// the resulting sequence, each function is "uniquely representated"
/// by a string.  For instance, if the same function "foo" appears at
/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
/// care about the actual string) would appear at index 1 and 3.
///
/// @param a_begin the beginning of the sequence of functions to consider.
///
/// @param a_end the end of the sequence of functions.  This points to
/// one-passed-the-end of the actual sequence.
///
/// @param b_begin the beginning of the second sequence of functions
/// to consider.
///
/// @param b_end the end of the second sequence of functions.
///
/// @param m the function_decl* <-> string map to be used by this
/// function to generate strings associated to a function.
///
/// @param o the output stream where to emit the generated list of
/// strings to.
static 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,
	   fns_to_str_map_type& m,
	   std::ostream& o)
{
  fns_to_str(a_begin, a_end, m, o);
  o << "->|<- ";
  fns_to_str(b_begin, b_end, m, o);
  o << "\n";
}

/// For each sequence of functions given in argument, generate a
/// sequence of string that matches a given sequence of function.  In
/// the resulting sequence, each function is "uniquely representated"
/// by a string.  For instance, if the same function "foo" appears at
/// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
/// care about the actual string) would appear at index 1 and 3.
///
/// @param a_begin the beginning of the sequence of functions to consider.
///
/// @param a_end the end of the sequence of functions.  This points to
/// one-passed-the-end of the actual sequence.
///
/// @param b_begin the beginning of the second sequence of functions
/// to consider.
///
/// @param b_end the end of the second sequence of functions.
///
/// @param o the output stream where to emit the generated list of
/// strings to.
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)
{
  fns_to_str_map_type m;
  fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
}

// </debugging facilities>

// </class template>

}// end namespace ir
}//end namespace abigail

namespace
{

/// Update the qualified parent name, qualified name and scoped name
/// of a tree decl node.
///
/// @return true if the tree walking should continue, false otherwise.
///
/// @param d the tree node to take in account.
bool
qualified_name_setter::do_update(abigail::ir::decl_base* d)
{
  std::string parent_qualified_name;
  abigail::ir::scope_decl* parent = d->get_scope();
  if (parent)
    d->priv_->qualified_parent_name_ = parent->get_qualified_name();
  else
    d->priv_->qualified_parent_name_ = abigail::interned_string();

  abigail::environment* env = d->get_environment();
  ABG_ASSERT(env);
  if (!d->priv_->qualified_parent_name_.empty())
    {
      if (d->get_name().empty())
	d->priv_->qualified_name_ = abigail::interned_string();
      else
	d->priv_->qualified_name_ =
	  env->intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
    }

  if (d->priv_->scoped_name_.empty())
    {
      if (parent
	  && !parent->get_is_anonymous()
	  && !parent->get_name().empty())
	d->priv_->scoped_name_ =
	  env->intern(parent->get_name() + "::" + d->get_name());
      else
	d->priv_->scoped_name_ =
	  env->intern(d->get_name());
    }

  if (!is_scope_decl(d))
    return false;

  return true;
}

/// This is called when we start visiting a decl node, during the
/// udpate of the qualified name of a given sub-tree.
///
/// @param d the decl node we are visiting.
///
/// @return true iff the traversal should keep going.
bool
qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
{return do_update(d);}

/// This is called when we start visiting a type node, during the
/// udpate of the qualified name of a given sub-tree.
///
/// @param d the decl node we are visiting.
///
/// @return true iff the traversal should keep going.
bool
qualified_name_setter::visit_begin(abigail::ir::type_base* t)
{
  if (abigail::ir::decl_base* d = get_type_declaration(t))
    return do_update(d);
  return false;
}
}// end anonymous namespace.
