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

/// @file
///
/// This file contains the definitions of the entry points to
/// de-serialize an instance of @ref abigail::translation_unit from an
/// ABI Instrumentation file in libabigail native XML format.  This
/// native XML format is named "abixml".

#include "config.h"
#include <assert.h>
#include <libxml/xmlreader.h>
#include <libxml/xmlstring.h>
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <memory>
#include <sstream>
#include <unordered_map>

#include "abg-suppression-priv.h"

#include "abg-internal.h"
#include "abg-tools-utils.h"

// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS

#include "abg-libxml-utils.h"
#include "abg-reader.h"
#include "abg-corpus.h"
#include "abg-symtab-reader.h"

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

namespace abigail
{

using xml::xml_char_sptr;

/// The namespace for the native XML file format reader.
namespace xml_reader
{
using std::string;
using std::deque;
using std::shared_ptr;
using std::unordered_map;
using std::dynamic_pointer_cast;
using std::vector;
using std::istream;

static bool	read_is_declaration_only(xmlNodePtr, bool&);
static bool	read_is_artificial(xmlNodePtr, bool&);
static bool	read_tracking_non_reachable_types(xmlNodePtr, bool&);
static bool	read_is_non_reachable_type(xmlNodePtr, bool&);
static bool	read_naming_typedef_id_string(xmlNodePtr, string&);
#ifdef WITH_DEBUG_SELF_COMPARISON
static bool	read_type_id_string(xmlNodePtr, string&);
static bool	maybe_map_type_with_type_id(const type_base_sptr&,
					    xmlNodePtr);
static bool	maybe_map_type_with_type_id(const type_base_sptr&,
					    const string&);
#define MAYBE_MAP_TYPE_WITH_TYPE_ID(type, xml_node) \
  maybe_map_type_with_type_id(type, xml_node)
#else
#define MAYBE_MAP_TYPE_WITH_TYPE_ID(type, xml_node)
#endif
static void	maybe_set_naming_typedef(read_context&	ctxt, xmlNodePtr, const decl_base_sptr &);
class read_context;

/// This abstracts the context in which the current ABI
/// instrumentation dump is being de-serialized.  It carries useful
/// information needed during the de-serialization, but that does not
/// make sense to be stored in the final resulting in-memory
/// representation of ABI Corpus.
class read_context
{
public:

  typedef unordered_map<string,
			vector<type_base_sptr> >::const_iterator
  const_types_map_it;

  typedef unordered_map<string,
			vector<type_base_sptr> >::iterator
  types_map_it;

  typedef unordered_map<string,
			shared_ptr<function_tdecl> >::const_iterator
  const_fn_tmpl_map_it;

  typedef unordered_map<string,
			shared_ptr<class_tdecl> >::const_iterator
  const_class_tmpl_map_it;

  typedef unordered_map<string, xmlNodePtr> string_xml_node_map;

  typedef unordered_map<xmlNodePtr, decl_base_sptr> xml_node_decl_base_sptr_map;

  friend vector<type_base_sptr>* get_types_from_type_id(read_context&,
							const string&);

  friend unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
	 get_artifact_used_by_relation_map(read_context& ctxt);

private:
  string						m_path;
  environment*						m_env;
  unordered_map<string, vector<type_base_sptr> >	m_types_map;
  unordered_map<string, shared_ptr<function_tdecl> >	m_fn_tmpl_map;
  unordered_map<string, shared_ptr<class_tdecl> >	m_class_tmpl_map;
  vector<type_base_sptr>				m_types_to_canonicalize;
  string_xml_node_map					m_id_xml_node_map;
  xml_node_decl_base_sptr_map				m_xml_node_decl_map;
  xml::reader_sptr					m_reader;
  xmlNodePtr						m_corp_node;
  deque<shared_ptr<decl_base> >			m_decls_stack;
  corpus_sptr						m_corpus;
  corpus_group_sptr					m_corpus_group;
  corpus::exported_decls_builder*			m_exported_decls_builder;
  suppr::suppressions_type				m_supprs;
  bool							m_tracking_non_reachable_types;
  bool							m_drop_undefined_syms;
#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
  unordered_map<type_or_decl_base*,
		vector<type_or_decl_base*>>		m_artifact_used_by_map;
#endif

  read_context();

public:
  read_context(xml::reader_sptr reader,
	       environment*	env)
    : m_env(env),
      m_reader(reader),
      m_corp_node(),
      m_exported_decls_builder(),
      m_tracking_non_reachable_types(),
      m_drop_undefined_syms()
  {}

  /// Getter for the flag that tells us if we are tracking types that
  /// are not reachable from global functions and variables.
  ///
  /// @return true iff we are tracking types that are not reachable
  /// from global functions and variables.
  bool
  tracking_non_reachable_types() const
  {return m_tracking_non_reachable_types;}

  /// Setter for the flag that tells us if we are tracking types that
  /// are not reachable from global functions and variables.
  ///
  /// @param f the new value of the flag.
  /// from global functions and variables.
  void
  tracking_non_reachable_types(bool f)
  {m_tracking_non_reachable_types = f;}

  /// Getter for the flag that tells us if we are dropping functions
  /// and variables that have undefined symbols.
  ///
  /// @return true iff we are dropping functions and variables that have
  /// undefined symbols.
  bool
  drop_undefined_syms() const
  {return m_drop_undefined_syms;}

  /// Setter for the flag that tells us if we are dropping functions
  /// and variables that have undefined symbols.
  ///
  /// @param f the new value of the flag.
  void
  drop_undefined_syms(bool f)
  {m_drop_undefined_syms = f;}

  /// Getter of the path to the ABI file.
  ///
  /// @return the path to the native xml abi file.
  const string&
  get_path() const
  {return m_path;}

  /// Setter of the path to the ABI file.
  ///
  /// @param the new path to the native ABI file.
  void
  set_path(const string& s)
  {m_path = s;}

  /// Getter for the environment of this reader.
  ///
  /// @return the environment of this reader.
  const environment*
  get_environment() const
  {return m_env;}

  /// Getter for the environment of this reader.
  ///
  /// @return the environment of this reader.
  environment*
  get_environment()
  {return m_env;}

  /// Setter for the environment of this reader.
  ///
  /// @param env the environment of this reader.
  void
  set_environment(environment* env)
  {m_env = env;}

  xml::reader_sptr
  get_reader() const
  {return m_reader;}

  /// Getter of the current XML node in the corpus element sub-tree
  /// that needs to be processed.
  ///
  /// @return the current XML node in the corpus element sub-tree that
  /// needs to be processed.
  xmlNodePtr
  get_corpus_node() const
  {return m_corp_node;}

  /// Setter of the current XML node in the corpus element sub-tree
  /// that needs to be processed.
  ///
  /// @param node set the current XML node in the corpus element
  /// sub-tree that needs to be processed.
  void
  set_corpus_node(xmlNodePtr node)
  {m_corp_node = node;}

  const string_xml_node_map&
  get_id_xml_node_map() const
  {return m_id_xml_node_map;}

  string_xml_node_map&
  get_id_xml_node_map()
  {return m_id_xml_node_map;}

  void
  clear_id_xml_node_map()
  {get_id_xml_node_map().clear();}

  const xml_node_decl_base_sptr_map&
  get_xml_node_decl_map() const
  {return m_xml_node_decl_map;}

  xml_node_decl_base_sptr_map&
  get_xml_node_decl_map()
  {return m_xml_node_decl_map;}

  void
  map_xml_node_to_decl(xmlNodePtr node,
		       decl_base_sptr decl)
  {
    if (node)
      get_xml_node_decl_map()[node]= decl;
  }

  decl_base_sptr
  get_decl_for_xml_node(xmlNodePtr node) const
  {
    xml_node_decl_base_sptr_map::const_iterator i =
      get_xml_node_decl_map().find(node);

    if (i != get_xml_node_decl_map().end())
      return i->second;

    return decl_base_sptr();
  }

  void
  clear_xml_node_decl_map()
  {get_xml_node_decl_map().clear();}

  void
  map_id_and_node (const string& id,
		   xmlNodePtr node)
  {
    if (!node)
      return;

    string_xml_node_map::iterator i = get_id_xml_node_map().find(id);
    if (i != get_id_xml_node_map().end())
      {
	bool is_declaration = false;
	read_is_declaration_only(node, is_declaration);
	if (is_declaration)
	  i->second = node;
      }
    else
      get_id_xml_node_map()[id] = node;
  }

  xmlNodePtr
  get_xml_node_from_id(const string& id) const
  {
    string_xml_node_map::const_iterator i = get_id_xml_node_map().find(id);
    if (i != get_id_xml_node_map().end())
     return i->second;
    return 0;
  }

  scope_decl_sptr
  get_scope_for_node(xmlNodePtr node,
		     access_specifier& access);

  // This is defined later, after build_type() is declared, because it
  // uses it.
  type_base_sptr
  build_or_get_type_decl(const string& id,
			 bool add_decl_to_scope);

  /// Return the first type already seen, that is identified by a
  /// given ID.
  ///
  /// Note that for a type to be "identified" by id, the function
  /// key_type_decl must have been previously called with that type
  /// and with id.
  ///
  /// @param id the id to consider.
  ///
  /// @return the type identified by the unique id id, or a null
  /// pointer if no type has ever been associated with id before.
  type_base_sptr
  get_type_decl(const string& id) const
  {
    const_types_map_it i = m_types_map.find(id);
    if (i == m_types_map.end())
      return type_base_sptr();
    type_base_sptr result = i->second[0];
    return result;
  }

  /// Return the vector of types already seen, that are identified by
  /// a given ID.
  ///
  /// Note that for a type to be "identified" by id, the function
  /// key_type_decl must have been previously called with that type
  /// and with id.
  ///
  /// @param id the id to consider.
  ///
  /// @return thevector of types already seen, that are identified by
  /// a given ID, or 0 if no type has ever been associated with @p id
  /// before.
  const vector<type_base_sptr>*
  get_all_type_decls(const string& id) const
  {
    const_types_map_it i = m_types_map.find(id);
    if (i == m_types_map.end())
      return 0;
    else
      return &i->second;
  }

  /// Return the function template that is identified by a unique ID.
  ///
  /// Note that for a function template to be identified by id, the
  /// function key_fn_tmpl_decl must have been previously called with
  /// that function template and with id.
  ///
  /// @param id the ID to consider.
  ///
  /// @return the function template identified by id, or a null
  /// pointer if no function template has ever been associated with
  /// id before.
  shared_ptr<function_tdecl>
  get_fn_tmpl_decl(const string& id) const
  {
    const_fn_tmpl_map_it i = m_fn_tmpl_map.find(id);
    if (i == m_fn_tmpl_map.end())
      return shared_ptr<function_tdecl>();
    return i->second;
  }

  /// Return the class template that is identified by a unique ID.
  ///
  /// Note that for a class template to be identified by id, the
  /// function key_class_tmpl_decl must have been previously called
  /// with that class template and with id.
  ///
  /// @param id the ID to consider.
  ///
  /// @return the class template identified by id, or a null pointer
  /// if no class template has ever been associated with id before.
  shared_ptr<class_tdecl>
  get_class_tmpl_decl(const string& id) const
  {
    const_class_tmpl_map_it i = m_class_tmpl_map.find(id);
    if (i == m_class_tmpl_map.end())
      return shared_ptr<class_tdecl>();
    return i->second;
  }

  /// Return the current lexical scope.
  scope_decl*
  get_cur_scope() const
  {
    shared_ptr<decl_base> cur_decl = get_cur_decl();

    if (dynamic_cast<scope_decl*>(cur_decl.get()))
      // The current decl is a scope_decl, so it's our lexical scope.
      return dynamic_pointer_cast<scope_decl>(cur_decl).get();
    else if (cur_decl)
      // The current decl is not a scope_decl, so our lexical scope is
      // the scope of this decl.
      return cur_decl->get_scope();
    else
      // We have no scope set.
      return 0;
  }

  decl_base_sptr
  get_cur_decl() const
  {
    if (m_decls_stack.empty())
      return shared_ptr<decl_base>(static_cast<decl_base*>(0));
    return m_decls_stack.back();
  }

  translation_unit*
  get_translation_unit()
  {
    const global_scope* global = 0;
    for (deque<shared_ptr<decl_base> >::reverse_iterator i =
	   m_decls_stack.rbegin();
	 i != m_decls_stack.rend();
	 ++i)
      if (decl_base_sptr d = *i)
	if ((global = get_global_scope(d)))
	  break;

    if (global)
      return global->get_translation_unit();

    return 0;
  }

  /// Test if a given type is from the current translation unit.
  ///
  /// @param type the type to consider.
  ///
  /// @return true iff the type is from the current translation unit.
  bool
  type_is_from_translation_unit(type_base_sptr type)
  {
    decl_base_sptr d = get_type_declaration(type);
    if (d)
      return (ir::get_translation_unit(d) == get_translation_unit());
    else if (function_type_sptr fn_type = is_function_type(type))
      return bool(lookup_function_type(fn_type, *get_translation_unit()));
    else
      return false;
  }

  void
  push_decl(decl_base_sptr d)
  {
    m_decls_stack.push_back(d);
  }

  decl_base_sptr
  pop_decl()
  {
    if (m_decls_stack.empty())
      return decl_base_sptr();

    shared_ptr<decl_base> t = get_cur_decl();
    m_decls_stack.pop_back();
    return t;
  }

  /// Pop all decls until a give scope is popped.
  ///
  /// @param scope the scope to pop.
  ///
  /// @return true if the scope was popped, false otherwise.  Note
  /// that if the scope wasn't found, it might mean that many other
  /// decls were popped.
  bool
  pop_scope(scope_decl_sptr scope)
  {
    decl_base_sptr d;
    do
      {
	d = pop_decl();
	scope_decl_sptr s = dynamic_pointer_cast<scope_decl>(d);
	if (s == scope)
	  break;
      }
    while (d);

    if (!d)
      return false;

    return dynamic_pointer_cast<scope_decl>(d) == scope;
  }

  /// like @ref pop_scope, but if the scope couldn't be popped, the
  /// function aborts the execution of the process.
  ///
  /// @param scope the scope to pop.
  void
  pop_scope_or_abort(scope_decl_sptr scope)
  {ABG_ASSERT(pop_scope(scope));}

  void
  clear_decls_stack()
  {m_decls_stack.clear();}

  void
  clear_type_map()
  {m_types_map.clear();}

  /// Clean the vector of types to canonicalize after the translation
  /// unit has been read.
  void
  clear_types_to_canonicalize()
  {m_types_to_canonicalize.clear();}


  /// Test if two types are equal, without comparing them structurally.
  ///
  /// This either tests that type pointers are equal, or it tests
  /// their names.  This is because it might be two early to compare
  /// types structurally because we are not necessarily done building
  /// them yet.
  ///
  /// @param t1 the first type to compare.
  ///
  /// @param t2 the second type to compare.
  ///
  /// @return true iff the types are equal.
  bool
  types_equal(type_base_sptr t1, type_base_sptr t2)
  {
    if (t1.get() == t2.get())
      return true;

    // We are going to test qualified names only if both types have
    // already been added to their scope.
    bool qualified = (get_type_scope(t1) && get_type_scope(t2));

    return (get_type_name(t1, qualified)
	    == get_type_name(t2, qualified));
  }

  /// Associate an ID with a type.
  ///
  /// @param type the type to associate witht he ID.
  ///
  /// @param id the ID to associate to the type.
  ///
  /// @return true upon successful completion.
  bool
  key_type_decl(const type_base_sptr& type, const string& id)
  {
    if (!type)
      return false;

    m_types_map[id].push_back(type);

    return true;
  }

  /// Associate an ID to a function template.
  ///
  /// @param fn_tmpl_decl the function template to consider.
  ///
  /// @param id the ID to associate to the function template.
  ///
  /// @return true upon successful completion, false otherwise.  Note
  /// that the function returns false if an ID was previously
  /// associated to the function template.
  bool
  key_fn_tmpl_decl(shared_ptr<function_tdecl> fn_tmpl_decl,
		   const string& id)
  {
    ABG_ASSERT(fn_tmpl_decl);

    const_fn_tmpl_map_it i = m_fn_tmpl_map.find(id);
    if (i != m_fn_tmpl_map.end())
      return false;

    m_fn_tmpl_map[id] = fn_tmpl_decl;
    return true;
  }

  /// Associate an ID to a class template.
  ///
  /// @param class_tmpl_decl the class template to consider.
  ///
  /// @param id the ID to associate to the class template.
  ///
  /// @return true upon successful completion, false otherwise.  Note
  /// that the function returns false if an ID was previously
  /// associated to the class template.
  bool
  key_class_tmpl_decl(shared_ptr<class_tdecl> class_tmpl_decl,
		      const string& id)
  {
    ABG_ASSERT(class_tmpl_decl);

    const_class_tmpl_map_it i = m_class_tmpl_map.find(id);
    if (i != m_class_tmpl_map.end())
      return false;

    m_class_tmpl_map[id] = class_tmpl_decl;
    return true;
  }

#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
  /// Record that an artifact is used by another one.
  ///
  /// If a type is "used" by another one (as in the type is a sub-type
  /// of another one), this function records that relation.
  ///
  /// @param used the type that is used.
  ///
  /// @param user the type that uses @p used.
  void
  record_artifact_as_used_by(type_or_decl_base* used,
			     type_or_decl_base* user)
  {
    if (m_artifact_used_by_map.find(used) == m_artifact_used_by_map.end())
      {
	vector<type_or_decl_base*> v;
	m_artifact_used_by_map[used] = v;
      }
    m_artifact_used_by_map[used].push_back(user);
  }

  /// Record that an artifact is used by another one.
  ///
  /// If a type is "used" by another one (as in the type is a sub-type
  /// of another one), this function records that relation.
  ///
  /// @param used the type that is used.
  ///
  /// @param user the type that uses @p used.
  void
  record_artifact_as_used_by(const type_or_decl_base_sptr& used,
			     const type_or_decl_base_sptr& user)
  {record_artifact_as_used_by(used.get(), user.get());}

  /// Record the sub-types of a fn-decl as being used by the fn-decl.
  ///
  /// @param fn the function decl to consider.
  void
  record_artifacts_as_used_in_fn_decl(const function_decl *fn)
  {
    if (!fn)
      return;

    type_base_sptr t = fn->get_return_type();
    record_artifact_as_used_by(t.get(), const_cast<function_decl*>(fn));

    for (auto pit : fn->get_parameters())
      {
	type_base_sptr t = pit->get_type();
	record_artifact_as_used_by(t.get(), const_cast<function_decl*>(fn));
      }
  }

  /// Record the sub-types of a function decl as being used by it.
  ///
  /// @param fn the function decl to consider.
  void
  record_artifacts_as_used_in_fn_decl(const function_decl_sptr& fn)
  {record_artifacts_as_used_in_fn_decl(fn.get());}

  /// Record the sub-types of a function type as being used by it.
  ///
  /// @param fn_type the function decl to consider.
  void
  record_artifacts_as_used_in_fn_type(const function_type *fn_type)
  {
    if (!fn_type)
      return;

    type_base_sptr t = fn_type->get_return_type();
    record_artifact_as_used_by(t.get(), const_cast<function_type*>(fn_type));

    for (auto pit : fn_type->get_parameters())
      {
	type_base_sptr t = pit->get_type();
	record_artifact_as_used_by(t.get(),
				   const_cast<function_type*>(fn_type));
      }
  }

  /// Record the sub-types of a function type as being used by it.
  ///
  /// @param fn_type the function decl to consider.
  void
  record_artifacts_as_used_in_fn_type(const function_type_sptr& fn_type)
  {record_artifacts_as_used_in_fn_type(fn_type.get());}
#endif

  /// This function must be called on each declaration that is created during
  /// the parsing.  It adds the declaration to the current scope, and updates
  /// the state of the parsing context accordingly.
  ///
  /// @param decl the newly created declaration.
  void
  push_decl_to_current_scope(decl_base_sptr decl,
			     bool add_to_current_scope)
  {
    ABG_ASSERT(decl);

    if (add_to_current_scope)
      add_decl_to_scope(decl, get_cur_scope());
    if (!decl->get_translation_unit())
      decl->set_translation_unit(get_translation_unit());
    ABG_ASSERT(decl->get_translation_unit());
    push_decl(decl);
  }

  /// This function must be called on each type decl that is created
  /// during the parsing.  It adds the type decl to the current scope
  /// and associates a unique ID to it.
  ///
  /// @param t type_decl
  ///
  /// @param id the unique ID to be associated to t
  ///
  /// @return true upon successful completion.
  ///
  bool
  push_and_key_type_decl(shared_ptr<type_base> t, const string& id,
			 bool add_to_current_scope)
  {
    shared_ptr<decl_base> decl = dynamic_pointer_cast<decl_base>(t);
    ABG_ASSERT(decl);

    push_decl_to_current_scope(decl, add_to_current_scope);
    if (!t->get_translation_unit())
      t->set_translation_unit(get_translation_unit());
    ABG_ASSERT(t->get_translation_unit());
    key_type_decl(t, id);
    return true;
  }

  const corpus_sptr
  get_corpus() const
  {return m_corpus;}

  corpus_sptr
  get_corpus()
  {return m_corpus;}

  void
  set_corpus(corpus_sptr c)
  {m_corpus = c;}

  /// Getter of the current corpus group.
  ///
  /// @return the current corpus group.n
  const corpus_group_sptr&
  get_corpus_group() const
  {return m_corpus_group;}

  /// Getter of the current corpus group.
  ///
  /// @return the current corpus group.
  corpus_group_sptr&
  get_corpus_group()
  {return m_corpus_group;}

  /// Setter of the corpus_group
  ///
  /// @param group the new corpus group.
  void
  set_corpus_group(const corpus_group_sptr& group)
  {m_corpus_group = group;}

  /// Getter for the object that determines if a given declaration
  /// ought to be put in the set of exported decls of the current
  /// corpus.
  ///
  /// @return the exported decls builder.
  corpus::exported_decls_builder*
  get_exported_decls_builder()
  {return m_exported_decls_builder;}

  /// Setter for the object that determines if a given declaration
  /// ought to be put in the set of exported decls of the current
  /// corpus.
  ///
  /// @param d the new exported decls builder.
  ///
  /// @return the exported decls builder.
  void
  set_exported_decls_builder(corpus::exported_decls_builder* d)
  {m_exported_decls_builder = d;}

  /// Getter of the vector of the suppression specifications
  /// associated to the current read context.
  ///
  /// @return the vector of suppression specifications.
  suppr::suppressions_type&
  get_suppressions()
  {return m_supprs;}

  /// Getter of the vector of the suppression specifications
  /// associated to the current read context.
  ///
  /// @return the vector of suppression specifications.
  const suppr::suppressions_type&
  get_suppressions() const
  {return const_cast<read_context*>(this)->get_suppressions();}

  /// Test if there are suppression specifications (associated to the
  /// current corpus) that match a given SONAME or file name.
  ///
  /// @param soname the SONAME to consider.
  ///
  /// @param the file name to consider.
  ///
  /// @return true iff there are suppression specifications (associated to the
  /// current corpus) that match the SONAME denoted by @p soname or
  /// the file name denoted by @p filename.
  bool
  corpus_is_suppressed_by_soname_or_filename(const string& soname,
					     const string& filename)
  {
    using suppr::suppressions_type;
    using suppr::file_suppression_sptr;
    using suppr::is_file_suppression;

    for (suppressions_type::const_iterator s = get_suppressions().begin();
	 s != get_suppressions().end();
	 ++s)
      if (file_suppression_sptr suppr = is_file_suppression(*s))
	if (suppr::suppression_matches_soname_or_filename(soname, filename,
							  *suppr))
	  return true;

    return false;
  }

  /// Add a given function to the set of exported functions of the
  /// current corpus, if the function satisfies the different
  /// constraints requirements.
  ///
  /// @param fn the function to consider.
  void
  maybe_add_fn_to_exported_decls(function_decl* fn)
  {
    if (fn)
      if (corpus::exported_decls_builder* b = get_exported_decls_builder())
	b->maybe_add_fn_to_exported_fns(fn);
  }

  /// Add a given variable to the set of exported functions of the
  /// current corpus, if the function satisfies the different
  /// constraints requirements.
  ///
  /// @param var the variable to consider.
  void
  maybe_add_var_to_exported_decls(var_decl* var)
  {
    if (var && var->get_scope())
      if (corpus::exported_decls_builder* b = get_exported_decls_builder())
	b->maybe_add_var_to_exported_vars(var);
  }

  /// Add a given variable to the set of exported functions of the
  /// current corpus, if the function satisfies the different
  /// constraints requirements.
  ///
  /// @param var the variable to consider.
  void
  maybe_add_var_to_exported_decls(const var_decl_sptr &var)
  {return maybe_add_var_to_exported_decls(var.get());}

  /// Clear all the data that must absolutely be cleared at the end of
  /// the parsing of a translation unit.
  void
  clear_per_translation_unit_data()
  {
  }

  /// Clear all the data that must absolutely be cleared at the end of
  /// the parsing of an ABI corpus.
  void
  clear_per_corpus_data()
  {
    clear_type_map();
    clear_types_to_canonicalize();
    clear_xml_node_decl_map();
    clear_id_xml_node_map();
    clear_decls_stack();
  }

#ifdef WITH_DEBUG_SELF_COMPARISON
  /// Perform a debugging routine for the "self-comparison" mode.
  ///
  /// This is done when this command is on:
  ///
  ///   "abidw --debug-abidiff".
  ///
  /// Consider a type 't' built from an XML element from the abixml
  /// reader and that has just been canonicalized.
  ///
  /// This function checks if the canonical type of 't' is the same as
  /// the canonical type of the type which was saved into the abixml
  /// with the same "type-id" as the one of 't'.
  ///
  /// Note that at abixml saving time, a debugging file was saved on
  /// disk to record the mapping of canonical type pointers and their
  /// type-ids.  Right before reading the abixml again, that file was
  /// read again and the mapping was loaded in the map returned by
  /// environment::get_type_id_canonical_type_map().
  void
  maybe_check_abixml_canonical_type_stability(type_base_sptr& t)
  {
    if (!m_env->self_comparison_debug_is_on()
	|| m_env->get_type_id_canonical_type_map().empty())
      return ;

    if (class_decl_sptr c = is_class_type(t))
      if (odr_is_relevant(*c) && c->get_is_declaration_only())
	// Declaration-only classes don't have canonical types in
	// environments where ODR is relevant (like in C++).
	return;

    // Let's get the type-id of this type as recorded in the
    // originating abixml file.
    string type_id =
      m_env->get_type_id_from_pointer(reinterpret_cast<uintptr_t>(t.get()));

    if (!type_id.empty())
      {
	// Now let's get the canonical type that initially led to the
	// serialization of a type with this type-id, when the abixml
	// was being serialized.
	auto j = m_env->get_type_id_canonical_type_map().find(type_id);
	if (j == m_env->get_type_id_canonical_type_map().end())
	  {
	    if (t->get_naked_canonical_type())
	      std::cerr << "error: no type with type-id: '"
			<< type_id
			<< "' could be read back from the typeid file\n";
	  }
	else if (j->second
		 != reinterpret_cast<uintptr_t>(t->get_canonical_type().get()))
	  // So thecanonical type of 't' (at abixml de-serialization
	  // time) is different from the canonical type that led to
	  // the serialization of 't' at abixml serialization time.
	  // Report this because it needs further debugging.
	  std::cerr << "error: canonical type for type '"
		    << t->get_pretty_representation(/*internal=*/false,
						    /*qualified=*/false)
		    << "' of type-id '" << type_id
		    << "' changed from '" << std::hex
		    << j->second << "' to '" << std::hex
		    << reinterpret_cast<uintptr_t>(t->get_canonical_type().get())
		    << std::dec
		    << "'\n";
	    }
  }
#endif

  /// Test if a type should be canonicalized early.  If so,
  /// canonicalize it right away.  Otherwise, schedule it for late
  /// canonicalizing; that is, schedule it so that it's going to be
  /// canonicalized when the translation unit is fully read.
  ///
  /// @param t the type to consider for canonicalizing.
  void
  maybe_canonicalize_type(type_base_sptr t,
			  bool force_delay = false)
  {
    if (!t)
      return;

    if (t->get_canonical_type())
      return;

    // If this class has some non-canonicalized sub type, then wait
    // for the when we've read all the translation unit to
    // canonicalize all of its non-canonicalized sub types and then we
    // can canonicalize this one.
    //
    // Also, if this is a declaration-only class, wait for the end of
    // the translation unit reading so that we have its definition and
    // then we'll use that for canonicalizing it.
    if (!force_delay
	&& !type_has_non_canonicalized_subtype(t)
	&& !is_class_type(t)
	&& !is_union_type(t)
	// Below are types that *must* be canonicalized only after
	// they are added to their context; but then this function
	// might be called to early, before they are actually added to
	// their context.
	//
	// TODO: make sure this function is called after types are
	// added to their context, so that we can try to
	// early-canonicalize some of these types, reducing the size
	// of the set of types to put on the side, waiting for being
	// canonicalized.
	&& !is_method_type(t)
	&& !is_reference_type(t)
	&& !is_pointer_type(t)
	&& !is_array_type(t)
	&& !is_qualified_type(t)
	&& !is_typedef(t)
	&& !is_enum_type(t)
	&& !is_function_type(t))
      {
	canonicalize(t);
#ifdef WITH_DEBUG_SELF_COMPARISON
	maybe_check_abixml_canonical_type_stability(t);
#endif
      }
    else
      {
	// We do not want to try to canonicalize a class type that
	// hasn't been properly added to its context.
	if (class_decl_sptr c = is_class_type(t))
	  ABG_ASSERT(c->get_scope());

	schedule_type_for_late_canonicalizing(t);
      }
  }

  /// Schedule a type for being canonicalized after the current
  /// translation unit is read.
  ///
  /// @param t the type to consider for canonicalization.
  void
  schedule_type_for_late_canonicalizing(type_base_sptr t)
  {m_types_to_canonicalize.push_back(t);}

  /// Perform the canonicalizing of types that ought to be done after
  /// the current translation unit is read.  This function is called
  /// when the current corpus is fully built.
  void
  perform_late_type_canonicalizing()
  {
    for (vector<type_base_sptr>::iterator i = m_types_to_canonicalize.begin();
	 i != m_types_to_canonicalize.end();
	 ++i)
      {
	canonicalize(*i);
#ifdef WITH_DEBUG_SELF_COMPARISON
	maybe_check_abixml_canonical_type_stability(*i);
#endif
      }
  }

  /// Test whether if a given function suppression matches a function
  /// designated by a regular expression that describes its name.
  ///
  /// @param s the suppression specification to evaluate to see if it
  /// matches a given function name.
  ///
  /// @param fn_name the name of the function of interest.  Note that
  /// this name must be *non* qualified.
  ///
  /// @return true iff the suppression specification @p s matches the
  /// function whose name is @p fn_name.
  bool
  suppression_matches_function_name(const suppr::function_suppression_sptr& s,
				    const string& fn_name) const
  {
    if (!s)
      return false;
    return suppression_matches_function_name(*s, fn_name);
  }

  /// Tests if a suppression specification can match ABI artifacts
  /// coming from the ABI corpus being analyzed.
  ///
  /// This tests if the suppression matches the soname of and binary
  /// name of the corpus being analyzed.
  ///
  /// @param s the suppression specification to consider.
  bool
  suppression_can_match(const suppr::suppression_base& s) const
  {
    corpus_sptr corp = get_corpus();

    if (!s.priv_->matches_soname(corp->get_soname()))
      if (s.has_soname_related_property())
	// The suppression has some SONAME related properties, but
	// none of them match the SONAME of the current binary.  So
	// the suppression cannot match the current binary.
	return false;

    if (!s.priv_->matches_binary_name(corp->get_path()))
      if (s.has_file_name_related_property())
	// The suppression has some file_name related properties, but
	// none of them match the file name of the current binary.  So
	// the suppression cannot match the current binary.
	return false;

    return true;
  }

  /// Test whether if a given function suppression matches a function
  /// designated by a regular expression that describes its name.
  ///
  /// @param s the suppression specification to evaluate to see if it
  /// matches a given function name.
  ///
  /// @param fn_name the name of the function of interest.  Note that
  /// this name must be *non* qualified.
  ///
  /// @return true iff the suppression specification @p s matches the
  /// function whose name is @p fn_name.
  bool
  suppression_matches_function_name(const suppr::function_suppression& s,
				    const string& fn_name) const
  {
    if (!s.get_drops_artifact_from_ir()
	|| !suppression_can_match(s))
      return false;

    return suppr::suppression_matches_function_name(s, fn_name);
  }

  /// Test whether if a given function suppression matches a function
  /// designated by a regular expression that describes its linkage
  /// name (symbol name).
  ///
  /// @param s the suppression specification to evaluate to see if it
  /// matches a given function linkage name
  ///
  /// @param fn_linkage_name the linkage name of the function of interest.
  ///
  /// @return true iff the suppression specification @p s matches the
  /// function whose linkage name is @p fn_linkage_name.
  bool
  suppression_matches_function_sym_name(const suppr::function_suppression_sptr& s,
					const string& fn_linkage_name) const
  {
    if (!s)
      return false;
    return suppression_matches_function_sym_name(*s, fn_linkage_name);
  }

  /// Test whether if a given function suppression matches a function
  /// designated by a regular expression that describes its linkage
  /// name (symbol name).
  ///
  /// @param s the suppression specification to evaluate to see if it
  /// matches a given function linkage name
  ///
  /// @param fn_linkage_name the linkage name of the function of interest.
  ///
  /// @return true iff the suppression specification @p s matches the
  /// function whose linkage name is @p fn_linkage_name.
  bool
  suppression_matches_function_sym_name(const suppr::function_suppression& s,
					const string& fn_linkage_name) const
  {
    if (!s.get_drops_artifact_from_ir()
	|| !suppression_can_match(s))
      return false;

    return suppr::suppression_matches_function_sym_name(s, fn_linkage_name);
  }

  /// Test whether if a given variable suppression specification
  /// matches a variable denoted by its name.
  ///
  /// @param s the variable suppression specification to consider.
  ///
  /// @param var_name the name of the variable to consider.
  ///
  /// @return true iff the suppression specification @p s matches the
  /// variable whose name is @p var_name.
  bool
  suppression_matches_variable_name(const suppr::variable_suppression& s,
				    const string& var_name) const
  {
    if (!s.get_drops_artifact_from_ir()
	|| !suppression_can_match(s))
      return false;

    return suppr::suppression_matches_variable_name(s, var_name);
  }

  /// Test whether if a given variable suppression specification
  /// matches a variable denoted by its linkage name.
  ///
  /// @param s the variable suppression specification to consider.
  ///
  /// @param var_linkage_name the linkage name of the variable to consider.
  ///
  /// @return true iff variable suppression specification @p s matches
  /// the variable denoted by linkage name @p var_linkage_name.
  bool
  suppression_matches_variable_sym_name(const suppr::variable_suppression& s,
					const string& var_linkage_name) const
  {
    if (!s.get_drops_artifact_from_ir()
	|| !suppression_can_match(s))
      return false;

    return suppr::suppression_matches_variable_sym_name(s, var_linkage_name);
  }

  /// Test if a given type suppression specification matches a type
  /// designated by its name and location.
  ///
  /// @param s the suppression specification to consider.
  ///
  /// @param type_name the fully qualified type name to consider.
  ///
  /// @param type_location the type location to consider.
  ///
  /// @return true iff the type suppression specification matches a
  /// type of a given name and location.
  bool
  suppression_matches_type_name_or_location(const suppr::type_suppression& s,
					    const string& type_name,
					    const location& type_location) const
  {
    if (!suppression_can_match(s))
      return false;

    return suppr::suppression_matches_type_name_or_location(s, type_name,
							    type_location);
  }
};// end class read_context

static int	advance_cursor(read_context&);
static bool read_translation_unit(read_context&, translation_unit&, xmlNodePtr);
static translation_unit_sptr get_or_read_and_add_translation_unit(read_context&, xmlNodePtr);
static translation_unit_sptr read_translation_unit_from_input(read_context&);
static bool	read_symbol_db_from_input(read_context&,
					  string_elf_symbols_map_sptr&,
					  string_elf_symbols_map_sptr&);
static bool	read_location(const read_context&, xmlNodePtr, location&);
static bool	read_artificial_location(const read_context&,
					 xmlNodePtr, location&);
static bool     maybe_set_artificial_location(const read_context&,
					      xmlNodePtr,
					      type_or_decl_base_sptr);
static bool	read_visibility(xmlNodePtr, decl_base::visibility&);
static bool	read_binding(xmlNodePtr, decl_base::binding&);
static bool	read_access(xmlNodePtr, access_specifier&);
static bool	read_size_and_alignment(xmlNodePtr, size_t&, size_t&);
static bool	read_static(xmlNodePtr, bool&);
static bool	read_offset_in_bits(xmlNodePtr, size_t&);
static bool	read_cdtor_const(xmlNodePtr, bool&, bool&, bool&);
static bool	read_is_virtual(xmlNodePtr, bool&);
static bool	read_is_struct(xmlNodePtr, bool&);
static bool	read_is_anonymous(xmlNodePtr, bool&);
static bool	read_elf_symbol_type(xmlNodePtr, elf_symbol::type&);
static bool	read_elf_symbol_binding(xmlNodePtr, elf_symbol::binding&);
static bool	read_elf_symbol_visibility(xmlNodePtr,
					   elf_symbol::visibility&);

static namespace_decl_sptr
build_namespace_decl(read_context&, const xmlNodePtr, bool);

// <build a c++ class from an instance of xmlNodePtr>
//
// Note that whenever a new function to build a type is added here,
// you should make sure to call it from the build_type function, which
// should be the last function of the list of declarated function
// below.

static elf_symbol_sptr
build_elf_symbol(read_context&, const xmlNodePtr, bool);

static elf_symbol_sptr
build_elf_symbol_from_reference(read_context&, const xmlNodePtr);

static string_elf_symbols_map_sptr
build_elf_symbol_db(read_context&, const xmlNodePtr, bool);

static function_decl::parameter_sptr
build_function_parameter (read_context&, const xmlNodePtr);

static function_decl_sptr
build_function_decl(read_context&, const xmlNodePtr,
		    class_or_union_sptr, bool);

static function_decl_sptr
build_function_decl_if_not_suppressed(read_context&, const xmlNodePtr,
				      class_or_union_sptr, bool);

static bool
function_is_suppressed(const read_context& ctxt,
		       xmlNodePtr node);

static var_decl_sptr
build_var_decl_if_not_suppressed(read_context&, const xmlNodePtr, bool);

static var_decl_sptr
build_var_decl(read_context&, const xmlNodePtr, bool);

static bool
variable_is_suppressed(const read_context& ctxt,
		       xmlNodePtr node);

static shared_ptr<type_decl>
build_type_decl(read_context&, const xmlNodePtr, bool);

static qualified_type_def_sptr
build_qualified_type_decl(read_context&, const xmlNodePtr, bool);

static shared_ptr<pointer_type_def>
build_pointer_type_def(read_context&, const xmlNodePtr, bool);

static shared_ptr<reference_type_def>
build_reference_type_def(read_context&, const xmlNodePtr, bool);

static shared_ptr<function_type>
build_function_type(read_context&, const xmlNodePtr, bool);

static array_type_def::subrange_sptr
build_subrange_type(read_context&, const xmlNodePtr);

static array_type_def_sptr
build_array_type_def(read_context&, const xmlNodePtr, bool);

static enum_type_decl_sptr
build_enum_type_decl(read_context&, const xmlNodePtr, bool);

static shared_ptr<typedef_decl>
build_typedef_decl(read_context&, const xmlNodePtr, bool);

static class_decl_sptr
build_class_decl(read_context&, const xmlNodePtr, bool);

static union_decl_sptr
build_union_decl(read_context&, const xmlNodePtr, bool);

static shared_ptr<function_tdecl>
build_function_tdecl(read_context&, const xmlNodePtr, bool);

static shared_ptr<class_tdecl>
build_class_tdecl(read_context&, const xmlNodePtr, bool);

static type_tparameter_sptr
build_type_tparameter(read_context&, const xmlNodePtr,
		      unsigned, template_decl_sptr);

static type_composition_sptr
build_type_composition(read_context&, const xmlNodePtr,
		       unsigned, template_decl_sptr);

static non_type_tparameter_sptr
build_non_type_tparameter(read_context&, const xmlNodePtr,
			  unsigned, template_decl_sptr);

static template_tparameter_sptr
build_template_tparameter(read_context&, const xmlNodePtr,
			  unsigned, template_decl_sptr);

static template_parameter_sptr
build_template_parameter(read_context&, const xmlNodePtr,
			 unsigned, template_decl_sptr);

// Please make this build_type function be the last one of the list.
// Note that it should call each type-building function above.  So
// please make sure to update it accordingly, whenever a new
// type-building function is added here.
static shared_ptr<type_base>
build_type(read_context&, const xmlNodePtr, bool);
// </build a c++ class  from an instance of xmlNodePtr>

static type_or_decl_base_sptr	handle_element_node(read_context&, xmlNodePtr, bool);
static decl_base_sptr	handle_type_decl(read_context&, xmlNodePtr, bool);
static decl_base_sptr	handle_namespace_decl(read_context&, xmlNodePtr, bool);
static decl_base_sptr	handle_qualified_type_decl(read_context&,
						   xmlNodePtr, bool);
static decl_base_sptr	handle_pointer_type_def(read_context&,
						xmlNodePtr, bool);
static decl_base_sptr	handle_reference_type_def(read_context&,
						  xmlNodePtr, bool);
static type_base_sptr	handle_function_type(read_context&,
					     xmlNodePtr, bool);
static decl_base_sptr	handle_array_type_def(read_context&,
					      xmlNodePtr, bool);
static decl_base_sptr	handle_enum_type_decl(read_context&, xmlNodePtr, bool);
static decl_base_sptr	handle_typedef_decl(read_context&, xmlNodePtr, bool);
static decl_base_sptr	handle_var_decl(read_context&, xmlNodePtr, bool);
static decl_base_sptr	handle_function_decl(read_context&, xmlNodePtr, bool);
static decl_base_sptr	handle_class_decl(read_context&, xmlNodePtr, bool);
static decl_base_sptr	handle_union_decl(read_context&, xmlNodePtr, bool);
static decl_base_sptr	handle_function_tdecl(read_context&, xmlNodePtr, bool);
static decl_base_sptr	handle_class_tdecl(read_context&, xmlNodePtr, bool);

#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
#define RECORD_ARTIFACT_AS_USED_BY(ctxt, used, user) \
  ctxt.record_artifact_as_used_by(used,user)
#define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(ctxt, fn) \
  ctxt.record_artifacts_as_used_in_fn_decl(fn)
#define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(ctxt, fn_type)\
  ctxt.record_artifacts_as_used_in_fn_type(fn_type)
#else
#define RECORD_ARTIFACT_AS_USED_BY(ctxt, used, user)
#define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(ctxt, fn)
#define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(ctxt, fn_type)
#endif

/// Get the IR node representing the scope for a given XML node.
///
/// This function might trigger the building of a full sub-tree of IR.
///
/// @param node the XML for which to return the scope decl.  If its
/// parent XML node has no corresponding IR node, that IR node is constructed.
///
/// @param access the access specifier of the node in its scope, if
/// applicable.  If the node doesn't have any access specifier
/// provided in its scope, then the parameter is set to no_access.
///
/// @return the IR node representing the scope of the IR node for the
/// XML node given in argument.
scope_decl_sptr
read_context::get_scope_for_node(xmlNodePtr node,
				 access_specifier& access)
{
  scope_decl_sptr nil, scope;
  if (!node)
    return nil;

  xmlNodePtr parent = node->parent;
  access = no_access;
  if (parent
      && (xmlStrEqual(parent->name, BAD_CAST("data-member"))
	  || xmlStrEqual(parent->name, BAD_CAST("member-type"))
	  || xmlStrEqual(parent->name, BAD_CAST("member-function"))
	  || xmlStrEqual(parent->name, BAD_CAST("member-template"))))
    {
      read_access(parent, access);
      parent = parent->parent;
    }

  xml_node_decl_base_sptr_map::const_iterator i =
    get_xml_node_decl_map().find(parent);
  if (i == get_xml_node_decl_map().end())
    {
      if (xmlStrEqual(parent->name, BAD_CAST("abi-instr")))
	{
	  translation_unit_sptr tu =
	    get_or_read_and_add_translation_unit(*this, parent);
	  return tu->get_global_scope();
	}

      access_specifier a = no_access;
      scope_decl_sptr parent_scope = get_scope_for_node(parent, a);
      push_decl(parent_scope);
      scope = dynamic_pointer_cast<scope_decl>
	(handle_element_node(*this, parent, /*add_decl_to_scope=*/true));
      ABG_ASSERT(scope);
      pop_scope_or_abort(parent_scope);
    }
  else
    scope = dynamic_pointer_cast<scope_decl>(i->second);

  return scope;
}

/// Get the type declaration IR node that matches a given XML type node ID.
///
/// If no IR node has been built for this ID, this function builds the
/// type declaration IR node and returns it.  Subsequent invocation of
/// this function with this ID will just return that ID previously returned.
///
/// @param id the XML node ID to consider.
///
/// @return the type declaration for the ID given in parameter.
type_base_sptr
read_context::build_or_get_type_decl(const string& id,
				     bool add_decl_to_scope)
{
  type_base_sptr t = get_type_decl(id);

  if (!t)
    {
      xmlNodePtr n = get_xml_node_from_id(id);
      ABG_ASSERT(n);

      scope_decl_sptr scope;
      access_specifier access = no_access;
      if (add_decl_to_scope)
	{
	  scope = get_scope_for_node(n, access);
	  /// In some cases, if for instance the scope of 'n' is a
	  /// namespace, get_scope_for_node() can trigger the building
	  /// of what is underneath of the namespace, if that has not
	  /// already been done.  So after that, the IR node for 'n'
	  /// might have been built; let's try to see if we are in
	  /// that case.  Otherwise, we'll just build the IR node for
	  /// 'n' ourselves.
	  if ((t = get_type_decl(id)))
	    return t;
	  ABG_ASSERT(scope);
	  push_decl(scope);
	}

      t = build_type(*this, n, add_decl_to_scope);
      ABG_ASSERT(t);
      if (is_member_type(t) && access != no_access)
	{
	  ABG_ASSERT(add_decl_to_scope);
	  decl_base_sptr d = get_type_declaration(t);
	  ABG_ASSERT(d);
	  set_member_access_specifier(d, access);
	}
      map_xml_node_to_decl(n, get_type_declaration(t));

      if (add_decl_to_scope)
	pop_scope_or_abort(scope);

      maybe_canonicalize_type(t, !add_decl_to_scope);
    }
  return t;
}

/// Moves the xmlTextReader cursor to the next xml node in the input
/// document.  Return 1 of the parsing was successful, 0 if no input
/// xml token is left, or -1 in case of error.
///
/// @param ctxt the read context
///
static int
advance_cursor(read_context& ctxt)
{
  xml::reader_sptr reader = ctxt.get_reader();
  return xmlTextReaderRead(reader.get());
}

/// Walk an entire XML sub-tree to build a map where the key is the
/// the value of the 'id' attribute (for type definitions) and the key
/// is the xml node containing the 'id' attribute.
///
/// @param ctxt the context of the reader.
///
/// @param node the XML sub-tree node to walk.  It must be an element
/// node.
static void
walk_xml_node_to_map_type_ids(read_context& ctxt,
			      xmlNodePtr node)
{
  xmlNodePtr n = node;

  if (!n || n->type != XML_ELEMENT_NODE)
    return;

  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(n, "id"))
    {
      string id = CHAR_STR(s);
      ctxt.map_id_and_node(id, n);
    }

  for (n = xmlFirstElementChild(n); n; n = xmlNextElementSibling(n))
    walk_xml_node_to_map_type_ids(ctxt, n);
}

static bool
read_translation_unit(read_context& ctxt, translation_unit& tu, xmlNodePtr node)
{
  tu.set_corpus(ctxt.get_corpus().get());

  xml::xml_char_sptr addrsize_str =
    XML_NODE_GET_ATTRIBUTE(node, "address-size");
  if (addrsize_str)
    {
      char address_size = atoi(reinterpret_cast<char*>(addrsize_str.get()));
      tu.set_address_size(address_size);
    }

  xml::xml_char_sptr path_str = XML_NODE_GET_ATTRIBUTE(node, "path");
  if (path_str)
    tu.set_path(reinterpret_cast<char*>(path_str.get()));

  xml::xml_char_sptr comp_dir_path_str =
    XML_NODE_GET_ATTRIBUTE(node, "comp-dir-path");
  if (comp_dir_path_str)
    tu.set_compilation_dir_path(reinterpret_cast<char*>
				(comp_dir_path_str.get()));

  xml::xml_char_sptr language_str = XML_NODE_GET_ATTRIBUTE(node, "language");
  if (language_str)
    tu.set_language(string_to_translation_unit_language
		     (reinterpret_cast<char*>(language_str.get())));


  // We are at global scope, as we've just seen the top-most
  // "abi-instr" element.
  ctxt.push_decl(tu.get_global_scope());
  ctxt.map_xml_node_to_decl(node, tu.get_global_scope());

  if (ctxt.get_id_xml_node_map().empty()
      || !ctxt.get_corpus())
    walk_xml_node_to_map_type_ids(ctxt, node);

  for (xmlNodePtr n = xmlFirstElementChild(node);
       n;
       n = xmlNextElementSibling(n))
    handle_element_node(ctxt, n, /*add_decl_to_scope=*/true);

  ctxt.pop_scope_or_abort(tu.get_global_scope());

  xml::reader_sptr reader = ctxt.get_reader();
  if (!reader)
    return false;

  ctxt.clear_per_translation_unit_data();

  return true;
}

/// Read a given xml node representing a tranlsation unit.
///
/// If the current corpus already contains a translation unit of the
/// path of the xml node we need to look at, then return that
/// translation unit.  Otherwise, read the translation unit, build a
/// @ref translation_unit out of it, add it to the current corpus and
/// return it.
///
/// @param ctxt the read context.
///
/// @param node the XML node to consider.
///
/// @return the resulting translation unit.
static translation_unit_sptr
get_or_read_and_add_translation_unit(read_context& ctxt, xmlNodePtr node)
{
  corpus_sptr corp = ctxt.get_corpus();

  translation_unit_sptr tu;
  string tu_path;
  xml::xml_char_sptr path_str = XML_NODE_GET_ATTRIBUTE(node, "path");

  if (path_str)
    {
      tu_path = reinterpret_cast<char*>(path_str.get());
      ABG_ASSERT(!tu_path.empty());

      if (corp)
	tu = corp->find_translation_unit(tu_path);

      if (tu)
	return tu;
    }

  tu.reset(new translation_unit(ctxt.get_environment(), tu_path));
  if (corp)
    corp->add(tu);

  if (read_translation_unit(ctxt, *tu, node))
    return tu;

  return translation_unit_sptr();
}

/// Parse the input XML document containing a translation_unit,
/// represented by an 'abi-instr' element node, associated to the current
/// context.
///
/// @param ctxt the current input context
///
/// @return the translation unit resulting from the parsing upon
/// successful completion, or nil.
static translation_unit_sptr
read_translation_unit_from_input(read_context&	ctxt)
{
  translation_unit_sptr tu, nil;

  xmlNodePtr node = ctxt.get_corpus_node();
  if (!node)
    {
      xml::reader_sptr reader = ctxt.get_reader();
      if (!reader)
	return nil;

      // The document must start with the abi-instr node.
      int status = 1;
      while (status == 1
	     && XML_READER_GET_NODE_TYPE(reader) != XML_READER_TYPE_ELEMENT)
	status = advance_cursor (ctxt);

      if (status != 1 || !xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
				       BAD_CAST("abi-instr")))
	return nil;

      node = xmlTextReaderExpand(reader.get());
      if (!node)
	return nil;
    }
  else
    {
      if (!xmlStrEqual(node->name, BAD_CAST("abi-instr")))
	return nil;
    }

  tu = get_or_read_and_add_translation_unit(ctxt, node);

  // We are not in the mode where the current corpus node came from a
  // local invocation of xmlTextReaderExpand.  So let's set
  // ctxt.get_corpus_node to the next child element node of the corpus
  // that needs to be processed.
  ctxt.set_corpus_node(xmlNextElementSibling(node));

  return tu;
}

/// Parse the input XML document that may contain function symbol and
/// variable symbol databases.
///
/// A function symbols database is an XML element named
/// "elf-function-symbols" and a variable symbols database is an XML
/// element named "elf-variable-symbols."  They contains "elf-symbol"
/// XML elements.
///
/// @param ctxt the read_context to use for the parsing.
///
/// @param fn_symdb any resulting function symbol database object, if
/// elf-function-symbols was present.
///
/// @param var_symdb any resulting variable symbol database object, if
/// elf-variable-symbols was present.
///
/// @return true upon successful parsing, false otherwise.
static bool
read_symbol_db_from_input(read_context&		 ctxt,
			  string_elf_symbols_map_sptr& fn_symdb,
			  string_elf_symbols_map_sptr& var_symdb)
{
  xml::reader_sptr reader = ctxt.get_reader();
  if (!reader)
    return false;

  if (!ctxt.get_corpus_node())
    for (;;)
      {
	int status = 1;
	while (status == 1
	       && XML_READER_GET_NODE_TYPE(reader) != XML_READER_TYPE_ELEMENT)
	  status = advance_cursor (ctxt);

	if (status != 1)
	  return false;

	bool has_fn_syms = false, has_var_syms = false;
	if (xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
			 BAD_CAST("elf-function-symbols")))
	  has_fn_syms = true;
	else if (xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
			      BAD_CAST("elf-variable-symbols")))
	  has_var_syms = true;
	else
	  break;

	xmlNodePtr node = xmlTextReaderExpand(reader.get());
	if (!node)
	  return false;

	if (has_fn_syms)
	  fn_symdb = build_elf_symbol_db(ctxt, node, true);
	else if (has_var_syms)
	  var_symdb = build_elf_symbol_db(ctxt, node, false);

	xmlTextReaderNext(reader.get());
      }
  else
    for (xmlNodePtr n = ctxt.get_corpus_node(); n; n = xmlNextElementSibling(n))
      {
	bool has_fn_syms = false, has_var_syms = false;
	if (xmlStrEqual(n->name, BAD_CAST("elf-function-symbols")))
	  has_fn_syms = true;
	else if (xmlStrEqual(n->name, BAD_CAST("elf-variable-symbols")))
	  has_var_syms = true;
	else
	  {
	    ctxt.set_corpus_node(n);
	    break;
	  }

	if (has_fn_syms)
	  fn_symdb = build_elf_symbol_db(ctxt, n, true);
	else if (has_var_syms)
	  var_symdb = build_elf_symbol_db(ctxt, n, false);
	else
	  break;
      }

  return true;
}

/// From an "elf-needed" XML_ELEMENT node, build a vector of strings
/// representing the vector of the dependencies needed by a given
/// corpus.
///
/// @param node the XML_ELEMENT node of name "elf-needed".
///
/// @param needed the output vector of string to populate with the
/// vector of dependency names found on the xml node @p node.
///
/// @return true upon successful completion, false otherwise.
static bool
build_needed(xmlNode* node, vector<string>& needed)
{
  if (!node || !xmlStrEqual(node->name,BAD_CAST("elf-needed")))
    return false;

  for (xmlNodePtr n = xmlFirstElementChild(node);
       n;
       n = xmlNextElementSibling(n))
    {
      if (!xmlStrEqual(n->name, BAD_CAST("dependency")))
	continue;

      string name;
      if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(n, "name"))
	xml::xml_char_sptr_to_string(s, name);

      if (!name.empty())
	needed.push_back(name);
    }

  return true;
}

/// Move to the next xml element node and expext it to be named
/// "elf-needed".  Then read the sub-tree to made of that node and
/// extracts a vector of needed dependencies name from it.
///
/// @param ctxt the read context used to the xml reading.
///
/// @param needed the resulting vector of dependency names.
///
/// @return true upon successful completion, false otherwise.
static bool
read_elf_needed_from_input(read_context&	ctxt,
			   vector<string>&	needed)
{
  xml::reader_sptr reader = ctxt.get_reader();
  if (!reader)
    return false;

  xmlNodePtr node = ctxt.get_corpus_node();

  if (!node)
    {
      int status = 1;
      while (status == 1
	     && XML_READER_GET_NODE_TYPE(reader) != XML_READER_TYPE_ELEMENT)
	status = advance_cursor (ctxt);

      if (status != 1)
	return false;

      if (!xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
			BAD_CAST("elf-needed")))
	return false;

      node = xmlTextReaderExpand(reader.get());
      if (!node)
	return false;
    }
  else
    {
      if (!xmlStrEqual(node->name, BAD_CAST("elf-needed")))
	return false;
    }

  bool result = build_needed(node, needed);

  ctxt.set_corpus_node(xmlNextElementSibling(node));

  return result;
}

/// Add suppressions specifications to the set of suppressions to be
/// used during the construction of the ABI internal representation
/// (the ABI corpus) from ELF and DWARF.
///
/// During the construction of the ABI corpus, ABI artifacts that
/// match the a given suppression specification are dropped on the
/// floor; that is, they are discarded and won't be part of the final
/// ABI corpus.  This is a way to reduce the amount of data held by
/// the final ABI corpus.
///
/// Note that the suppression specifications provided to this function
/// are only considered during the construction of the ABI corpus.
/// For instance, they are not taken into account during e.g
/// comparisons of two ABI corpora that might happen later.  If you
/// want to apply suppression specifications to the comparison (or
/// reporting) of ABI corpora please refer to the documentation of the
/// @ref diff_context type to learn how to set suppressions that are
/// to be used in that context.
///
/// @param ctxt the context that is going to be used by functions that
/// read types and declarations information to construct and ABI
/// corpus.
///
/// @param supprs the suppression specifications to be applied during
/// the construction of the ABI corpus.
void
add_read_context_suppressions(read_context& ctxt,
			      const suppr::suppressions_type& supprs)
{
  for (suppr::suppressions_type::const_iterator i = supprs.begin();
       i != supprs.end();
       ++i)
    if ((*i)->get_drops_artifact_from_ir())
      ctxt.get_suppressions().push_back(*i);
}

/// Configure the @ref read_context so that types not reachable from
/// public interface are taken into account when the abixml file is
/// read.
///
/// @param ctxt the @read_context to consider.
///
/// @param flag if yes, then types not reachable from public interface
/// are taken into account when the abixml file is read.
void
consider_types_not_reachable_from_public_interfaces(read_context& ctxt,
						    bool flag)
{ctxt.tracking_non_reachable_types(flag);}

#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
/// Get the vector of types that have a given type-id.
///
/// This function is available only if the project has been configured
/// with --enable-show-type-use-in-abilint.
///
/// @param ctxt the abixml text reader context to use.
///
/// @param type_id the type-id to consider.
vector<type_base_sptr>*
get_types_from_type_id(read_context& ctxt, const string& type_id)
{
  auto it = ctxt.m_types_map.find(type_id);
  if (it == ctxt.m_types_map.end())
    return nullptr;
  return &it->second;
}

/// Get the map that associates an artififact to its users.
///
/// This function is available only if the project has been configured
/// with --enable-show-type-use-in-abilint.
///
/// @param ctxt the abixml text reader context to use.
unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
get_artifact_used_by_relation_map(read_context& ctxt)
{return &ctxt.m_artifact_used_by_map;}
#endif

/// Read the "version" attribute from the current XML element which is
/// supposed to be a corpus or a corpus group and set the format
/// version to the corpus object accordingly.
///
/// Note that this is a subroutine of read_corpus_from_input and
/// read_corpus_group_from_input.
///
/// @param reader the XML reader to consider.  That reader must be
/// set to an XML element representing a corpus or a corpus group.
///
/// @param corp output parameter.  The corpus object which format
/// version string is going to be set according to the value of the
/// "version" attribute found on the current XML element.
static void
handle_version_attribute(xml::reader_sptr& reader, corpus& corp)
{
  string version_string;
  if (xml_char_sptr s = XML_READER_GET_ATTRIBUTE(reader, "version"))
    xml::xml_char_sptr_to_string(s, version_string);

  vector<string> v;
  if (version_string.empty())
    {
      v.push_back("1");
      v.push_back("0");
    }
  else
    tools_utils::split_string(version_string, ".", v);
  corp.set_format_major_version_number(v[0]);
  corp.set_format_minor_version_number(v[1]);
}

/// Parse the input XML document containing an ABI corpus, represented
/// by an 'abi-corpus' element node, associated to the current
/// context.
///
/// @param ctxt the current input context.
///
/// @return the corpus resulting from the parsing
corpus_sptr
read_corpus_from_input(read_context& ctxt)
{
  corpus_sptr nil;

  xml::reader_sptr reader = ctxt.get_reader();
  if (!reader)
    return nil;

  // This is to remember to call xmlTextReaderNext if we ever call
  // xmlTextReaderExpand.
  bool call_reader_next = false;

  xmlNodePtr node = ctxt.get_corpus_node();
  if (!node)
    {
      // The document must start with the abi-corpus node.
      int status = 1;
      while (status == 1
	     && XML_READER_GET_NODE_TYPE(reader) != XML_READER_TYPE_ELEMENT)
	status = advance_cursor (ctxt);

      if (status != 1 || !xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
				       BAD_CAST("abi-corpus")))
	return nil;

      ctxt.set_corpus(std::make_shared<corpus>(ctxt.get_environment(), ""));
#ifdef WITH_DEBUG_SELF_COMPARISON
      if (ctxt.get_environment()->self_comparison_debug_is_on())
	ctxt.get_environment()->
	  set_self_comparison_debug_input(ctxt.get_corpus());
#endif

      if (!ctxt.get_corpus_group())
	ctxt.clear_per_corpus_data();

      corpus& corp = *ctxt.get_corpus();
      corp.set_origin(corpus::NATIVE_XML_ORIGIN);
      ctxt.set_exported_decls_builder(corp.get_exported_decls_builder().get());

      handle_version_attribute(reader, corp);

      xml::xml_char_sptr path_str = XML_READER_GET_ATTRIBUTE(reader, "path");
      string path;

      if (path_str)
	{
	  path = reinterpret_cast<char*>(path_str.get());
	  corp.set_path(path);
	}

      xml::xml_char_sptr architecture_str =
	XML_READER_GET_ATTRIBUTE(reader, "architecture");
      if (architecture_str)
	corp.set_architecture_name
	  (reinterpret_cast<char*>(architecture_str.get()));

      xml::xml_char_sptr soname_str =
	XML_READER_GET_ATTRIBUTE(reader, "soname");
      string soname;

      if (soname_str)
	{
	  soname = reinterpret_cast<char*>(soname_str.get());
	  corp.set_soname(soname);
	}

      // Apply suppression specifications here to honour:
      //
      //   [suppress_file]
      //     (soname_regexp
      //      |soname_not_regexp
      //      |file_name_regexp
      //      |file_name_not_regexp) = <soname-or-file-name>
      if ((!soname.empty() || !path.empty())
	  && ctxt.corpus_is_suppressed_by_soname_or_filename(soname, path))
	return nil;

      node = xmlTextReaderExpand(reader.get());
      if (!node)
	return nil;

      call_reader_next = true;
    }
  else
    {
      ctxt.set_corpus(std::make_shared<corpus>(ctxt.get_environment(), ""));
#ifdef WITH_DEBUG_SELF_COMPARISON
      if (ctxt.get_environment()->self_comparison_debug_is_on())
	ctxt.get_environment()->
	  set_self_comparison_debug_input(ctxt.get_corpus());
#endif

      if (!ctxt.get_corpus_group())
	ctxt.clear_per_corpus_data();

      corpus& corp = *ctxt.get_corpus();
      corp.set_origin(corpus::NATIVE_XML_ORIGIN);

      ctxt.set_exported_decls_builder(corp.get_exported_decls_builder().get());

      xml::xml_char_sptr path_str = XML_NODE_GET_ATTRIBUTE(node, "path");
      if (path_str)
	corp.set_path(reinterpret_cast<char*>(path_str.get()));

      xml::xml_char_sptr architecture_str =
	XML_NODE_GET_ATTRIBUTE(node, "architecture");
      if (architecture_str)
	corp.set_architecture_name
	  (reinterpret_cast<char*>(architecture_str.get()));

      xml::xml_char_sptr soname_str =
	XML_NODE_GET_ATTRIBUTE(node, "soname");
      if (soname_str)
	corp.set_soname(reinterpret_cast<char*>(soname_str.get()));
    }

  // If the corpus element node has children nodes, make
  // ctxt.get_corpus_node() returns the first child element node of
  // the corpus element that *needs* to be processed.
  if (node->children)
    {
      xmlNodePtr n = xmlFirstElementChild(node);
      ctxt.set_corpus_node(n);
    }

  corpus& corp = *ctxt.get_corpus();

  walk_xml_node_to_map_type_ids(ctxt, node);

  // Read the needed element
  vector<string> needed;
  read_elf_needed_from_input(ctxt, needed);
  if (!needed.empty())
    corp.set_needed(needed);

  string_elf_symbols_map_sptr fn_sym_db, var_sym_db;

  // Read the symbol databases.
  read_symbol_db_from_input(ctxt, fn_sym_db, var_sym_db);
  // Note that it's possible that both fn_sym_db and var_sym_db are nil,
  // due to potential suppression specifications.  That's fine.
  corp.set_symtab(symtab_reader::symtab::load(fn_sym_db, var_sym_db));

  ctxt.get_environment()->canonicalization_is_done(false);

  // Read the translation units.
  while (read_translation_unit_from_input(ctxt))
    ;

  if (ctxt.tracking_non_reachable_types())
    {
      bool is_tracking_non_reachable_types = false;
      read_tracking_non_reachable_types(node, is_tracking_non_reachable_types);

      ABG_ASSERT
	(corp.recording_types_reachable_from_public_interface_supported()
	 == is_tracking_non_reachable_types);
    }


  ctxt.perform_late_type_canonicalizing();

  ctxt.get_environment()->canonicalization_is_done(true);

  if (call_reader_next)
    {
      // This is the necessary counter-part of the xmlTextReaderExpand()
      // call at the beginning of the function.
      xmlTextReaderNext(reader.get());
      // The call above invalidates the xml node returned by
      // xmlTextReaderExpand, which is can still be accessed via
      // ctxt.set_corpus_node.
      ctxt.set_corpus_node(0);
    }
  else
    {
      node = ctxt.get_corpus_node();
      node = xmlNextElementSibling(node);
      if (!node)
	{
	  node = ctxt.get_corpus_node();
	  if (node)
	    node = xmlNextElementSibling(node->parent);
	}
      ctxt.set_corpus_node(node);
    }

  return ctxt.get_corpus();
}

/// Parse the input XML document containing an ABI corpus group,
/// represented by an 'abi-corpus-group' element node, associated to
/// the current context.
///
/// @param ctxt the current input context.
///
/// @return the corpus group resulting from the parsing
corpus_group_sptr
read_corpus_group_from_input(read_context& ctxt)
{
  corpus_group_sptr nil;

  xml::reader_sptr reader = ctxt.get_reader();
  if (!reader)
    return nil;

  // The document must start with the abi-corpus-group node.
  int status = 1;
  while (status == 1
	 && XML_READER_GET_NODE_TYPE(reader) != XML_READER_TYPE_ELEMENT)
    status = advance_cursor (ctxt);

  if (status != 1 || !xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
				   BAD_CAST("abi-corpus-group")))
    return nil;

  if (!ctxt.get_corpus_group())
    {
      corpus_group_sptr g(new corpus_group(ctxt.get_environment(),
					   ctxt.get_path()));
      ctxt.set_corpus_group(g);
    }

  corpus_group_sptr group = ctxt.get_corpus_group();

  handle_version_attribute(reader, *group);

  xml::xml_char_sptr path_str = XML_READER_GET_ATTRIBUTE(reader, "path");
  if (path_str)
    group->set_path(reinterpret_cast<char*>(path_str.get()));

  xmlNodePtr node = xmlTextReaderExpand(reader.get());
  if (!node)
    return nil;

  node = xmlFirstElementChild(node);
  ctxt.set_corpus_node(node);

  corpus_sptr corp;
  while ((corp = read_corpus_from_input(ctxt)))
    ctxt.get_corpus_group()->add_corpus(corp);

  xmlTextReaderNext(reader.get());

  return ctxt.get_corpus_group();
}

/// De-serialize an ABI corpus group from an input XML document which
/// root node is 'abi-corpus-group'.
///
/// @param in the input stream to read the XML document from.
///
/// @param env the environment to use.  Note that the life time of
/// this environment must be greater than the lifetime of the
/// resulting corpus as the corpus uses resources that are allocated
/// in the environment.
///
/// @return the resulting corpus group de-serialized from the parsing.
/// This is non-null iff the parsing resulted in a valid corpus group.
corpus_group_sptr
read_corpus_group_from_native_xml(std::istream* in,
				  environment*  env)
{
  read_context_sptr read_ctxt = create_native_xml_read_context(in, env);
  return read_corpus_group_from_input(*read_ctxt);
}

/// De-serialize an ABI corpus group from an XML document file which
/// root node is 'abi-corpus-group'.
///
/// @param path the path to the input file to read the XML document
/// from.
///
/// @param env the environment to use.  Note that the life time of
/// this environment must be greater than the lifetime of the
/// resulting corpus as the corpus uses resources that are allocated
/// in the environment.
///
/// @return the resulting corpus group de-serialized from the parsing.
/// This is non-null if the parsing successfully resulted in a corpus
/// group.
corpus_group_sptr
read_corpus_group_from_native_xml_file(const string& path,
				       environment*  env)
{
    read_context_sptr read_ctxt = create_native_xml_read_context(path, env);
    corpus_group_sptr group = read_corpus_group_from_input(*read_ctxt);
    return group;
}

/// Parse an ABI instrumentation file (in XML format) at a given path.
///
/// @param input_file a path to the file containing the xml document
/// to parse.
///
/// @param env the environment to use.
///
/// @return the translation unit resulting from the parsing upon
/// successful completion, or nil.
translation_unit_sptr
read_translation_unit_from_file(const string&	input_file,
				environment*	env)
{
  read_context ctxt(xml::new_reader_from_file(input_file), env);
  translation_unit_sptr tu = read_translation_unit_from_input(ctxt);
  ctxt.get_environment()->canonicalization_is_done(false);
  ctxt.perform_late_type_canonicalizing();
  ctxt.get_environment()->canonicalization_is_done(true);
  return tu;
}

/// Parse an ABI instrumentation file (in XML format) from an
/// in-memory buffer.
///
/// @param buffer the in-memory buffer containing the xml document to
/// parse.
///
/// @param env the environment to use.
///
/// @return the translation unit resulting from the parsing upon
/// successful completion, or nil.
translation_unit_sptr
read_translation_unit_from_buffer(const string&	buffer,
				  environment*		env)
{
  read_context ctxt(xml::new_reader_from_buffer(buffer), env);
  translation_unit_sptr tu = read_translation_unit_from_input(ctxt);
  ctxt.get_environment()->canonicalization_is_done(false);
  ctxt.perform_late_type_canonicalizing();
  ctxt.get_environment()->canonicalization_is_done(true);
  return tu;
}

/// Parse a translation unit from an abixml input from a given
/// context.
///
/// @param ctxt the @ref read_context to consider.
///
/// @return the constructed @ref translation_unit from the content of
/// the input abixml.
translation_unit_sptr
read_translation_unit(read_context& ctxt)
{
  translation_unit_sptr tu = read_translation_unit_from_input(ctxt);
  ctxt.get_environment()->canonicalization_is_done(false);
  ctxt.perform_late_type_canonicalizing();
  ctxt.get_environment()->canonicalization_is_done(true);
  return tu;
}

/// This function is called by @ref read_translation_unit_from_input.
/// It handles the current xml element node of the reading context.
/// The result of the "handling" is to build the representation of the
/// xml node and tied it to the current translation unit.
///
/// @param ctxt the current parsing context.
///
/// @return true upon successful completion, false otherwise.
static type_or_decl_base_sptr
handle_element_node(read_context& ctxt, xmlNodePtr node,
		    bool add_to_current_scope)
{
  type_or_decl_base_sptr decl;
  if (!node)
    return decl;

  ((decl = handle_namespace_decl(ctxt, node, add_to_current_scope))
   ||(decl = handle_type_decl(ctxt, node, add_to_current_scope))
   ||(decl = handle_qualified_type_decl(ctxt, node,
					add_to_current_scope))
   ||(decl = handle_pointer_type_def(ctxt, node,
				     add_to_current_scope))
   || (decl = handle_reference_type_def(ctxt, node, add_to_current_scope))
   || (decl = handle_function_type(ctxt, node, add_to_current_scope))
   || (decl = handle_array_type_def(ctxt, node, add_to_current_scope))
   || (decl = handle_enum_type_decl(ctxt, node,
				    add_to_current_scope))
   || (decl = handle_typedef_decl(ctxt, node,
				  add_to_current_scope))
   || (decl = handle_var_decl(ctxt, node,
			      add_to_current_scope))
   || (decl = handle_function_decl(ctxt, node,
				   add_to_current_scope))
   || (decl = handle_class_decl(ctxt, node,
				add_to_current_scope))
   || (decl = handle_union_decl(ctxt, node,
				add_to_current_scope))
   || (decl = handle_function_tdecl(ctxt, node,
				    add_to_current_scope))
   || (decl = handle_class_tdecl(ctxt, node,
				 add_to_current_scope)));

  // If the user wants us to track non-reachable types, then read the
  // 'is-non-reachable-type' attribute on type elements and record
  // reachable types accordingly.
  if (ctxt.tracking_non_reachable_types())
    {
      if (type_base_sptr t = is_type(decl))
	{
	  corpus_sptr abi = ctxt.get_corpus();
	  ABG_ASSERT(abi);
	  bool is_non_reachable_type = false;
	  read_is_non_reachable_type(node, is_non_reachable_type);
	  if (!is_non_reachable_type)
	    abi->record_type_as_reachable_from_public_interfaces(*t);
	}
    }

    return decl;
}

/// Parses location attributes on an xmlNodePtr.
///
///@param ctxt the current parsing context
///
///@param loc the resulting location.
///
/// @return true upon sucessful parsing, false otherwise.
static bool
read_location(const read_context&	ctxt,
	      xmlNodePtr		node,
	      location&		loc)
{
  string file_path;
  size_t line = 0, column = 0;

  if (xml_char_sptr f = xml::build_sptr(xmlGetProp(node, BAD_CAST("filepath"))))
    file_path = CHAR_STR(f);

  if (file_path.empty())
    return read_artificial_location(ctxt, node, loc);

  if (xml_char_sptr l = xml::build_sptr(xmlGetProp(node, BAD_CAST("line"))))
    line = atoi(CHAR_STR(l));
  else
    return read_artificial_location(ctxt, node, loc);

  if (xml_char_sptr c = xml::build_sptr(xmlGetProp(node, BAD_CAST("column"))))
    column = atoi(CHAR_STR(c));

  read_context& c = const_cast<read_context&>(ctxt);
  loc = c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
								    line,
								    column);
  return true;
}

/// Parses the artificial location attributes on an xmlNodePtr.
///
/// The artificial location is the line number of the xmlNode as well
/// as the URI of the node.
///
///@param ctxt the current parsing context
///
///@param loc the resulting location.
///
/// @return true upon sucessful parsing, false otherwise.
static bool
read_artificial_location(const read_context& ctxt,
			 xmlNodePtr node,
			 location& loc)
{
  if (!node)
    return false;

   string file_path;
   size_t line = 0, column = 0;

   line = node->line;

   if (node->doc)
       file_path = reinterpret_cast<const char*>(node->doc->URL);

   read_context& c = const_cast<read_context&>(ctxt);
   loc =
     c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
								 line, column);
   loc.set_is_artificial(true);
   return true;
}

/// Set the artificial location of a xmlNode to an artifact.
///
/// The artificial location is the line number of the xmlNode as well
/// as the URI of the node.
///
/// The function sets the artificial location only if the artifact
/// doesn"t already have one.
///
///@param ctxt the current parsing context
///
///@param node the XML node to consider.
///
///@param artifact the ABI artifact.
///
/// @return true iff the location was set on the artifact.
static bool
maybe_set_artificial_location(const read_context& ctxt,
			      xmlNodePtr node,
			      type_or_decl_base_sptr artefact)
{
  if (artefact && !artefact->has_artificial_location())
    {
      location l;
      if (read_artificial_location(ctxt, node, l))
	{
	  artefact->set_artificial_location(l);
	  return true;
	}
    }
  return false;
}

/// Parse the visibility attribute.
///
/// @param node the xml node to read from.
///
/// @param vis the resulting visibility.
///
/// @return true upon successful completion, false otherwise.
static bool
read_visibility(xmlNodePtr node, decl_base::visibility& vis)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "visibility"))
    {
      string v = CHAR_STR(s);

      if (v == "default")
	vis = decl_base::VISIBILITY_DEFAULT;
      else if (v == "hidden")
	vis = decl_base::VISIBILITY_HIDDEN;
      else if (v == "internal")
	vis = decl_base::VISIBILITY_INTERNAL;
      else if (v == "protected")
	vis = decl_base::VISIBILITY_PROTECTED;
      else
	vis = decl_base::VISIBILITY_DEFAULT;
      return true;
    }
  return false;
}

/// Parse the "binding" attribute on the current element.
///
/// @param node the xml node to build parse the bind from.
///
/// @param bind the resulting binding attribute.
///
/// @return true upon successful completion, false otherwise.
static bool
read_binding(xmlNodePtr node, decl_base::binding& bind)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "binding"))
    {
      string b = CHAR_STR(s);

      if (b == "global")
	bind = decl_base::BINDING_GLOBAL;
      else if (b == "local")
	bind = decl_base::BINDING_LOCAL;
      else if (b == "weak")
	bind = decl_base::BINDING_WEAK;
      else
	bind = decl_base::BINDING_GLOBAL;
      return true;
    }

  return false;
}

/// Read the 'access' attribute on the current xml node.
///
/// @param node the xml node to consider.
///
/// @param access the access attribute.  Set iff the function returns true.
///
/// @return true upon sucessful completion, false otherwise.
static bool
read_access(xmlNodePtr node, access_specifier& access)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "access"))
    {
      string a = CHAR_STR(s);

      if (a == "private")
	access = private_access;
      else if (a == "protected")
	access = protected_access;
      else if (a == "public")
	access = public_access;
      else
	/// If there is an access specifier of an unsupported value,
	/// we should not assume anything and abort.
	abort();

      return true;
    }
  return false;
}

/// Parse 'size-in-bits' and 'alignment-in-bits' attributes of a given
/// xmlNodePtr reprensting an xml element.
///
/// @param node the xml element node to consider.
///
/// @param size_in_bits the resulting value for the 'size-in-bits'
/// attribute.  This set only if this function returns true and the if
/// the attribute was present on the xml element node.
///
/// @param align_in_bits the resulting value for the
/// 'alignment-in-bits' attribute.  This set only if this function
/// returns true and the if the attribute was present on the xml
/// element node.
///
/// @return true if either one of the two attributes above were set,
/// false otherwise.
static bool
read_size_and_alignment(xmlNodePtr node,
			size_t& size_in_bits,
			size_t& align_in_bits)
{

  bool got_something = false;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "size-in-bits"))
    {
      size_in_bits = atoll(CHAR_STR(s));
      got_something = true;
    }

  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "alignment-in-bits"))
    {
      align_in_bits = atoll(CHAR_STR(s));
      got_something = true;
    }
  return got_something;
}

/// Parse the 'static' attribute of a given xml element node.
///
/// @param node the xml element node to consider.
///
/// @param is_static the resulting the parsing.  Is set if the
/// function returns true.
///
/// @return true if the xml element node has the 'static' attribute
/// set, false otherwise.
static bool
read_static(xmlNodePtr node, bool& is_static)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "static"))
    {
      string b = CHAR_STR(s);
      is_static = b == "yes";
      return true;
    }
  return false;
}

/// Parse the 'layout-offset-in-bits' attribute of a given xml element node.
///
/// @param offset_in_bits set to true if the element node contains the
/// attribute.
///
/// @return true iff the xml element node contains the attribute.
static bool
read_offset_in_bits(xmlNodePtr	node,
		    size_t&	offset_in_bits)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "layout-offset-in-bits"))
    {
      offset_in_bits = strtoull(CHAR_STR(s), 0, 0);
      return true;
    }
  return false;
}

/// Parse the 'constructor', 'destructor' and 'const' attribute of a
/// given xml node.
///
/// @param is_constructor the resulting value of the parsing of the
/// 'constructor' attribute.  Is set if the xml node contains the
/// attribute and if the function returns true.
///
/// @param is_destructor the resulting value of the parsing of the
/// 'destructor' attribute.  Is set if the xml node contains the
/// attribute and if the function returns true.
///
/// @param is_const the resulting value of the parsing of the 'const'
/// attribute.  Is set if the xml node contains the attribute and if
/// the function returns true.
///
/// @return true if at least of the attributes above is set, false
/// otherwise.
///
/// Note that callers of this function should initialize
/// is_constructor, is_destructor and is_const prior to passing them
/// to this function.
static bool
read_cdtor_const(xmlNodePtr	node,
		 bool&		is_constructor,
		 bool&		is_destructor,
		 bool&		is_const)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "constructor"))
    {
      string b = CHAR_STR(s);
      if (b == "yes")
	is_constructor = true;
      else
	is_constructor = false;

      return true;
    }

  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "destructor"))
    {
      string b = CHAR_STR(s);
      if (b == "yes")
	is_destructor = true;
      else
	is_destructor = false;

      return true;
    }

  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "const"))
    {
      string b = CHAR_STR(s);
      if (b == "yes")
	is_const = true;
      else
	is_const = false;

      return true;
    }

  return false;
}

/// Read the "is-declaration-only" attribute of the current xml node.
///
/// @param node the xml node to consider.
///
/// @param is_decl_only is set to true iff the "is-declaration-only" attribute
/// is present and set to "yes".
///
/// @return true iff the is_decl_only attribute was set.
static bool
read_is_declaration_only(xmlNodePtr node, bool& is_decl_only)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-declaration-only"))
    {
      string str = CHAR_STR(s);
      if (str == "yes")
	is_decl_only = true;
      else
	is_decl_only = false;
      return true;
    }
  return false;
}

/// Read the "is-artificial" attribute of the current XML node.
///
/// @param node the XML node to consider.
///
/// @param is_artificial this output parameter is set to true iff the
/// "is-artificial" parameter is present and set to 'yes'.
///
/// @return true iff the "is-artificial" parameter was present on the
/// XML node.
static bool
read_is_artificial(xmlNodePtr node, bool& is_artificial)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-artificial"))
    {
      string is_artificial_str = CHAR_STR(s) ? CHAR_STR(s) : "";
      is_artificial = is_artificial_str == "yes";
      return true;
    }
  return false;
}

/// Read the 'tracking-non-reachable-types' attribute on the current
/// XML element.
///
/// @param node the current XML element.
///
/// @param tracking_non_reachable_types output parameter.  This is set
/// to true iff the 'tracking-non-reachable-types' attribute is
/// present on the current XML node and set to 'yes'.  In that case,
/// the function returns true.
///
/// @return true iff the 'tracking-non-reachable-types' attribute is
/// present on the current XML node and set to 'yes'.
static bool
read_tracking_non_reachable_types(xmlNodePtr node,
				  bool& tracking_non_reachable_types)
{
  if (xml_char_sptr s =
      XML_NODE_GET_ATTRIBUTE(node, "tracking-non-reachable-types"))
    {
      string tracking_non_reachable_types_str = CHAR_STR(s) ? CHAR_STR(s) : "";
      tracking_non_reachable_types =
	(tracking_non_reachable_types_str == "yes")
	? true
	: false;
      return true;
    }
  return false;
}

/// Read the 'is-non-reachable' attribute on the current XML element.
///
/// @param node the current XML element.
///
/// @param is_non_reachable_type output parameter. This is set to true
/// iff the 'is-non-reachable' attribute is present on the current XML
/// element with a value se to 'yes'.
///
/// @return true iff the 'is-non-reachable' attribute is present on
/// the current XML element with a value se to 'yes'.
static bool
read_is_non_reachable_type(xmlNodePtr node, bool& is_non_reachable_type)
{
  if (xml_char_sptr s =
      XML_NODE_GET_ATTRIBUTE(node, "is-non-reachable"))
    {
      string is_non_reachable_type_str = CHAR_STR(s) ? CHAR_STR(s) : "";
      is_non_reachable_type =
	(is_non_reachable_type_str == "yes")
	? true
	: false;
      return true;
    }
  return false;
}

/// Read the "naming-typedef-id" property from an XML node.
///
/// @param node the XML node to consider.
///
/// @param naming_typedef_id output parameter.  It's set to the
/// content of the "naming-typedef-id" property, if it's present.
///
/// @return true iff the "naming-typedef-id" property exists and was
/// read from @p node.
static bool
read_naming_typedef_id_string(xmlNodePtr node, string& naming_typedef_id)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "naming-typedef-id"))
    {
      naming_typedef_id = xml::unescape_xml_string(CHAR_STR(s));
      return true;
    }
  return false;
}

/// Read the "is-virtual" attribute of the current xml node.
///
/// @param node the xml node to read the attribute from
///
/// @param is_virtual is set to true iff the "is-virtual" attribute is
/// present and set to "yes".
///
/// @return true iff the is-virtual attribute is present.
static bool
read_is_virtual(xmlNodePtr node, bool& is_virtual)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-virtual"))
    {
      string str = CHAR_STR(s);
      if (str == "yes")
	is_virtual = true;
      else
	is_virtual = false;
      return true;
    }
  return false;
}

/// Read the 'is-struct' attribute.
///
/// @param node the xml node to read the attribute from.
///
/// @param is_struct is set to true iff the "is-struct" attribute is
/// present and set to "yes".
///
/// @return true iff the "is-struct" attribute is present.
static bool
read_is_struct(xmlNodePtr node, bool& is_struct)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-struct"))
    {
      string str = CHAR_STR(s);
      if (str == "yes")
	  is_struct = true;
      else
	is_struct = false;
      return true;
    }
  return false;
}

/// Read the 'is-anonymous' attribute.
///
/// @param node the xml node to read the attribute from.
///
/// @param is_anonymous is set to true iff the "is-anonymous" is present
/// and set to "yes".
///
/// @return true iff the "is-anonymous" attribute is present.
static bool
read_is_anonymous(xmlNodePtr node, bool& is_anonymous)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-anonymous"))
    {
      string str = CHAR_STR(s);
      is_anonymous = (str == "yes");
      return true;
    }
  return false;
}

/// Read the 'type' attribute of the 'elf-symbol' element.
///
/// @param node the XML node to read the attribute from.
///
/// @param t the resulting elf_symbol::type.
///
/// @return true iff the function completed successfully.
static bool
read_elf_symbol_type(xmlNodePtr node, elf_symbol::type& t)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type"))
    {
      string str;
      xml::xml_char_sptr_to_string(s, str);
      if (!string_to_elf_symbol_type(str, t))
	return false;
      return true;
    }
  return false;
}

/// Read the 'binding' attribute of the of the 'elf-symbol' element.
///
/// @param node the XML node to read the attribute from.
///
/// @param b the XML the resulting elf_symbol::binding.
///
/// @return true iff the function completed successfully.
static bool
read_elf_symbol_binding(xmlNodePtr node, elf_symbol::binding& b)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "binding"))
    {
      string str;
      xml::xml_char_sptr_to_string(s, str);
      if (!string_to_elf_symbol_binding(str, b))
	return false;
      return true;
    }
  return false;
}

/// Read the 'visibility' attribute of the of the 'elf-symbol'
/// element.
///
/// @param node the XML node to read the attribute from.
///
/// @param b the XML the resulting elf_symbol::visibility.
///
/// @return true iff the function completed successfully.
static bool
read_elf_symbol_visibility(xmlNodePtr node, elf_symbol::visibility& v)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "visibility"))
    {
      string str;
      xml::xml_char_sptr_to_string(s, str);
      if (!string_to_elf_symbol_visibility(str, v))
	return false;
      return true;
    }
  return false;
}

#ifdef WITH_DEBUG_SELF_COMPARISON
/// Read the value of the 'id' attribute from a given XML node.
///
/// @param node the XML node to consider.
///
/// @param type_id the string to set the 'id' to.
///
/// @return true iff @p type_id was successfully set.
static bool
read_type_id_string(xmlNodePtr node, string& type_id)
{
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    {
      type_id = CHAR_STR(s);
      return true;
    }
  return false;
}

/// Associate a type-id string with the type that was constructed from
/// it.
///
/// Note that if we are not in "self comparison debugging" mode or if
/// the type we are looking at is not canonicalized, then this
/// function does nothing.
///
/// @param t the type built from the a type XML node that has a
/// particular type-id.
///
/// @param type_id the type-id of type @p t.
///
/// @return true if the association was performed.
static bool
maybe_map_type_with_type_id(const type_base_sptr& t,
			    const string& type_id)
{
  if (!t)
    return false;

  environment *env = t->get_environment();
  if (!env->self_comparison_debug_is_on()
      || is_non_canonicalized_type(t.get()))
    return false;

  env->get_pointer_type_id_map()[reinterpret_cast<uintptr_t>(t.get())] =
    type_id;

  return true;
}

/// Associate a type-id string with the type that was constructed from
/// it.
///
/// Note that if we are not in "self comparison debugging" mode or if
/// the type we are looking at is not canonicalized, then this
/// function does nothing.
///
/// @param t the type built from the a type XML node that has a
/// particular type-id.
///
/// @param type_id the type-id of type @p t.
///
/// @return true if the association was performed.
static bool
maybe_map_type_with_type_id(const type_base_sptr& t,
			    xmlNodePtr node)
{
  if (!t)
    return false;

  environment *env = t->get_environment();
  if (!env->self_comparison_debug_is_on()
      || is_non_canonicalized_type(t.get()))
    return false;

  string type_id;
  if (!read_type_id_string(node, type_id) || type_id.empty())
    return false;

  return maybe_map_type_with_type_id(t, type_id);
}

#endif

/// Set the naming typedef to a given decl depending on the content of
/// the "naming-typedef-id" property of its descriptive XML element.
///
/// @param ctxt the current read context.
///
/// @param node the XML node to read from.
///
/// @param decl the decl to set the naming typedef to.
static void
maybe_set_naming_typedef(read_context&		ctxt,
			 xmlNodePtr		node,
			 const decl_base_sptr&	decl)
{
  string naming_typedef_id;
  read_naming_typedef_id_string(node, naming_typedef_id);
  if (!naming_typedef_id.empty())
    {
      typedef_decl_sptr naming_typedef =
	is_typedef(ctxt.build_or_get_type_decl(naming_typedef_id, true));
      ABG_ASSERT(naming_typedef);
      decl->set_naming_typedef(naming_typedef);
    }
}

/// Build a @ref namespace_decl from an XML element node which name is
/// "namespace-decl".  Note that this function recursively reads the
/// content of the namespace and builds the proper IR nodes
/// accordingly.
///
/// @param ctxt the read context to use.
///
/// @param node the XML node to consider.  It must constain the
/// content of the namespace, that is, children XML nodes representing
/// what is inside the namespace, unless the namespace is empty.
///
/// @param add_to_current_scope if set to yes, the resulting
/// namespace_decl is added to the IR being currently built.
///
/// @return a pointer to the the resulting @ref namespace_decl.
static namespace_decl_sptr
build_namespace_decl(read_context&	ctxt,
		     const xmlNodePtr	node,
		     bool		add_to_current_scope)
{
  namespace_decl_sptr nil;
  if (!node || !xmlStrEqual(node->name, BAD_CAST("namespace-decl")))
    return nil;

  if (decl_base_sptr d = ctxt.get_decl_for_xml_node(node))
    {
      namespace_decl_sptr result = dynamic_pointer_cast<namespace_decl>(d);
      ABG_ASSERT(result);
      return result;
    }

  string name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    name = xml::unescape_xml_string(CHAR_STR(s));

  location loc;
  read_location(ctxt, node, loc);

  const environment* env = ctxt.get_environment();
  namespace_decl_sptr decl(new namespace_decl(env, name, loc));
  maybe_set_artificial_location(ctxt, node, decl);
  ctxt.push_decl_to_current_scope(decl, add_to_current_scope);
  ctxt.map_xml_node_to_decl(node, decl);

  for (xmlNodePtr n = xmlFirstElementChild(node);
       n;
       n = xmlNextElementSibling(n))
    handle_element_node(ctxt, n, /*add_to_current_scope=*/true);

  ctxt.pop_scope_or_abort(decl);

  return decl;
}

/// Build an instance of @ref elf_symbol from an XML element node
/// which name is 'elf-symbol'.
///
/// @param ctxt the context used for reading the XML input.
///
/// @param node the XML node to read.
///
/// @param drop_if_suppressed if the elf symbol was suppressed by a
/// suppression specification then do not build it.
///
/// @return the @ref elf_symbol built, or nil if it couldn't be built.
static elf_symbol_sptr
build_elf_symbol(read_context& ctxt, const xmlNodePtr node,
		 bool drop_if_suppressed)
{
  elf_symbol_sptr nil;

  if (!node
      || node->type != XML_ELEMENT_NODE
      || !xmlStrEqual(node->name, BAD_CAST("elf-symbol")))
    return nil;

  string name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    xml::xml_char_sptr_to_string(s, name);

  size_t size = 0;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "size"))
    size = strtol(CHAR_STR(s), NULL, 0);

  bool is_defined = true;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-defined"))
    {
      string value;
      xml::xml_char_sptr_to_string(s, value);
      if (value == "true" || value == "yes")
	is_defined = true;
      else
	is_defined = false;
    }

  bool is_common = false;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-common"))
    {
      string value;
      xml::xml_char_sptr_to_string(s, value);
      if (value == "true" || value == "yes")
	is_common = true;
      else
	is_common = false;
    }

  string version_string;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "version"))
    xml::xml_char_sptr_to_string(s, version_string);

  bool is_default_version = false;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-default-version"))
    {
      string value;
      xml::xml_char_sptr_to_string(s, value);
      if (value == "true" || value == "yes")
	is_default_version = true;
    }

  elf_symbol::type type = elf_symbol::NOTYPE_TYPE;
  read_elf_symbol_type(node, type);

  elf_symbol::binding binding = elf_symbol::GLOBAL_BINDING;
  read_elf_symbol_binding(node, binding);

  elf_symbol::visibility visibility = elf_symbol::DEFAULT_VISIBILITY;
  read_elf_symbol_visibility(node, visibility);

  elf_symbol::version version(version_string, is_default_version);

  const bool is_suppressed = suppr::is_elf_symbol_suppressed(ctxt, name, type);
  if (drop_if_suppressed && is_suppressed)
    return elf_symbol_sptr();

  const environment* env = ctxt.get_environment();
  elf_symbol_sptr e = elf_symbol::create(env, /*index=*/0,
					 size, name, type, binding,
					 is_defined, is_common,
					 version, visibility);

  e->set_is_suppressed(is_suppressed);

  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "crc"))
    e->set_crc(strtoull(CHAR_STR(s), NULL, 0));

  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "namespace"))
    {
      std::string ns;
      xml::xml_char_sptr_to_string(s, ns);
      e->set_namespace(ns);
    }

  return e;
}

/// Build and instance of elf_symbol from an XML attribute named
/// 'elf-symbol-id' which value is the ID of a symbol that should
/// present in the symbol db of the corpus associated to the current
/// context.
///
/// @param ctxt the current context to consider.
///
/// @param node the xml element node to consider.
///
/// @param function_symbol is true if we should look for a function
/// symbol, is false if we should look for a variable symbol.
///
/// @return a shared pointer the resutling elf_symbol.
static elf_symbol_sptr
build_elf_symbol_from_reference(read_context& ctxt, const xmlNodePtr node)
{
  elf_symbol_sptr nil;

  if (!node)
    return nil;

  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "elf-symbol-id"))
    {
      string sym_id;
      xml::xml_char_sptr_to_string(s, sym_id);
      if (sym_id.empty())
	return nil;

      string name, ver;
      elf_symbol::get_name_and_version_from_id(sym_id, name, ver);
      if (name.empty())
	return nil;

      const elf_symbols& symbols =
	  ctxt.get_corpus()->get_symtab()->lookup_symbol(name);

      for (const auto& symbol : symbols)
	if (symbol->get_id_string() == sym_id)
	  return symbol;
    }

  return nil;
}

/// Build an instance of string_elf_symbols_map_type from an XML
/// element representing either a function symbols data base, or a
/// variable symbols database.
///
/// @param ctxt the context to take in account.
///
/// @param node the XML node to consider.
///
/// @param function_syms true if we should look for a function symbols
/// data base, false if we should look for a variable symbols data
/// base.
static string_elf_symbols_map_sptr
build_elf_symbol_db(read_context& ctxt,
		    const xmlNodePtr node,
		    bool function_syms)
{
  string_elf_symbols_map_sptr map, nil;
  string_elf_symbol_sptr_map_type id_sym_map;

  if (!node)
    return nil;

  if (function_syms
      && !xmlStrEqual(node->name, BAD_CAST("elf-function-symbols")))
    return nil;

  if (!function_syms
      && !xmlStrEqual(node->name, BAD_CAST("elf-variable-symbols")))
    return nil;

  ctxt.set_corpus_node(node);

  typedef std::unordered_map<xmlNodePtr, elf_symbol_sptr>
    xml_node_ptr_elf_symbol_sptr_map_type;
  xml_node_ptr_elf_symbol_sptr_map_type xml_node_ptr_elf_symbol_map;

  elf_symbol_sptr sym;
  for (xmlNodePtr n = xmlFirstElementChild(node);
       n;
       n = xmlNextElementSibling(n))
    if ((sym = build_elf_symbol(ctxt, n, /*drop_if_suppress=*/false)))
      {
	id_sym_map[sym->get_id_string()] = sym;
	xml_node_ptr_elf_symbol_map[n] = sym;
      }

  if (id_sym_map.empty())
    return nil;

  map.reset(new string_elf_symbols_map_type);
  string_elf_symbols_map_type::iterator it;
  for (string_elf_symbol_sptr_map_type::const_iterator i = id_sym_map.begin();
       i != id_sym_map.end();
       ++i)
    (*map)[i->second->get_name()].push_back(i->second);

  // Now build the alias relations
  for (xml_node_ptr_elf_symbol_sptr_map_type::const_iterator x =
	 xml_node_ptr_elf_symbol_map.begin();
       x != xml_node_ptr_elf_symbol_map.end();
       ++x)
    {
      if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(x->first, "alias"))
	{
	  string alias_id = CHAR_STR(s);

	  // Symbol aliases can be multiple separated by comma(,), split them
	  std::vector<std::string> elems;
	  std::stringstream aliases(alias_id);
	  std::string item;
	  while (std::getline(aliases, item, ','))
	    elems.push_back(item);
	  for (std::vector<string>::iterator alias = elems.begin();
	       alias != elems.end(); ++alias)
	    {
	      string_elf_symbol_sptr_map_type::const_iterator i =
	      id_sym_map.find(*alias);
	      ABG_ASSERT(i != id_sym_map.end());
	      ABG_ASSERT(i->second->is_main_symbol());

	      x->second->get_main_symbol()->add_alias(i->second);
	    }
	}
    }

  return map;
}

/// Build a function parameter from a 'parameter' xml element node.
///
/// @param ctxt the contexte of the xml parsing.
///
/// @param node the xml 'parameter' element node to de-serialize from.
static shared_ptr<function_decl::parameter>
build_function_parameter(read_context& ctxt, const xmlNodePtr node)
{
  shared_ptr<function_decl::parameter> nil;

  if (!node || !xmlStrEqual(node->name, BAD_CAST("parameter")))
    return nil;

  ABG_ASSERT(ctxt.get_environment());

  bool is_variadic = false;
  string is_variadic_str;
  if (xml_char_sptr s =
      xml::build_sptr(xmlGetProp(node, BAD_CAST("is-variadic"))))
    {
      is_variadic_str = CHAR_STR(s) ? CHAR_STR(s) : "";
      is_variadic = is_variadic_str == "yes";
    }

  bool is_artificial = false;
  read_is_artificial(node, is_artificial);

  string type_id;
  if (xml_char_sptr a = xml::build_sptr(xmlGetProp(node, BAD_CAST("type-id"))))
    type_id = CHAR_STR(a);

  type_base_sptr type;
  if (is_variadic)
    type = ctxt.get_environment()->get_variadic_parameter_type();
  else
    {
      ABG_ASSERT(!type_id.empty());
      type = ctxt.build_or_get_type_decl(type_id, true);
    }
  ABG_ASSERT(type);
  ABG_ASSERT(type->get_environment() == ctxt.get_environment());

  string name;
  if (xml_char_sptr a = xml::build_sptr(xmlGetProp(node, BAD_CAST("name"))))
    name = CHAR_STR(a);

  location loc;
  read_location(ctxt, node, loc);

  function_decl::parameter_sptr p
    (new function_decl::parameter(type, name, loc,
				  is_variadic, is_artificial));

  return p;
}

/// Build a function_decl from a 'function-decl' xml node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to build the function_decl from.
///
/// @param as_method_decl if this is set to a class_decl pointer, it
/// means that the 'function-decl' xml node should be parsed as a
/// method_decl.  The class_decl pointer is the class decl to which
/// the resulting method_decl is a member function of.  The resulting
/// shared_ptr<function_decl> that is returned is then really a
/// shared_ptr<method_decl>.
///
/// @param add_to_current_scope if set to yes, the resulting of
/// this function is added to its current scope.
///
/// @return a pointer to a newly created function_decl upon successful
/// completion, a null pointer otherwise.
static function_decl_sptr
build_function_decl(read_context&	ctxt,
		    const xmlNodePtr	node,
		    class_or_union_sptr as_method_decl,
		    bool		add_to_current_scope)
{
  function_decl_sptr nil;

  if (!xmlStrEqual(node->name, BAD_CAST("function-decl")))
    return nil;

  string name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    name = xml::unescape_xml_string(CHAR_STR(s));

  string mangled_name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "mangled-name"))
    mangled_name = xml::unescape_xml_string(CHAR_STR(s));

  string inline_prop;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "declared-inline"))
    inline_prop = CHAR_STR(s);
  bool declared_inline = inline_prop == "yes";

  decl_base::visibility vis = decl_base::VISIBILITY_NONE;
  read_visibility(node, vis);

  decl_base::binding bind = decl_base::BINDING_NONE;
  read_binding(node, bind);

  size_t size = ctxt.get_translation_unit()->get_address_size(), align = 0;
  read_size_and_alignment(node, size, align);

  location loc;
  read_location(ctxt, node, loc);

  environment* env = ctxt.get_environment();
  ABG_ASSERT(env);
  std::vector<function_decl::parameter_sptr> parms;
  type_base_sptr return_type = env->get_void_type();

  for (xmlNodePtr n = xmlFirstElementChild(node);
       n ;
       n = xmlNextElementSibling(n))
    {
      if (xmlStrEqual(n->name, BAD_CAST("parameter")))
	{
	  if (function_decl::parameter_sptr p =
	      build_function_parameter(ctxt, n))
	    parms.push_back(p);
	}
      else if (xmlStrEqual(n->name, BAD_CAST("return")))
	{
	  string type_id;
	  if (xml_char_sptr s =
	      xml::build_sptr(xmlGetProp(n, BAD_CAST("type-id"))))
	    type_id = CHAR_STR(s);
	  if (!type_id.empty())
	    return_type = ctxt.build_or_get_type_decl(type_id, true);
	}
    }

  function_type_sptr fn_type(as_method_decl
			     ? new method_type(return_type, as_method_decl,
					       parms, /*is_const=*/false,
					       size, align)
			     : new function_type(return_type,
						 parms, size, align));

  ABG_ASSERT(fn_type);

  fn_type->set_is_artificial(true);

  function_decl_sptr fn_decl(as_method_decl
			     ? new method_decl (name, fn_type,
						declared_inline, loc,
						mangled_name, vis, bind)
			     : new function_decl(name, fn_type,
						 declared_inline, loc,
						 mangled_name, vis,
						 bind));

  maybe_set_artificial_location(ctxt, node, fn_decl);
  ctxt.push_decl_to_current_scope(fn_decl, add_to_current_scope);
  RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(ctxt, fn_decl);

  elf_symbol_sptr sym = build_elf_symbol_from_reference(ctxt, node);
  if (sym)
    fn_decl->set_symbol(sym);

  if (fn_decl->get_symbol() && fn_decl->get_symbol()->is_public())
    fn_decl->set_is_in_public_symbol_table(true);

  ctxt.get_translation_unit()->bind_function_type_life_time(fn_type);

  ctxt.maybe_canonicalize_type(fn_type, !add_to_current_scope);

  ctxt.maybe_add_fn_to_exported_decls(fn_decl.get());

  return fn_decl;
}

/// Build a function_decl from a 'function-decl' xml node if it's not
/// been suppressed by a suppression specification that is in the
/// context.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to build the function_decl from.
///
/// @param as_method_decl if this is set to a class_or_union pointer,
/// it means that the 'function-decl' xml node should be parsed as a
/// method_decl.  The class_or_union pointer is the class or union the
/// resulting method_decl is a member function of.  The resulting @ref
/// function_decl_sptr that is returned is then really a @ref
/// method_decl_sptr.
///
/// @param add_to_current_scope if set to yes, the resulting of
/// this function is added to its current scope.
///
/// @return a pointer to a newly created function_decl upon successful
/// completion.  If the function was suppressed by a suppression
/// specification then returns nil.
static function_decl_sptr
build_function_decl_if_not_suppressed(read_context&	ctxt,
				      const xmlNodePtr	node,
				      class_or_union_sptr as_method_decl,
				      bool		add_to_current_scope)
{
    function_decl_sptr fn;

  if (function_is_suppressed(ctxt, node))
    // The function was suppressed by at least one suppression
    // specification associated to the current read context.  So
    // don't build any IR for it.
    ;
  else
    fn = build_function_decl(ctxt, node, as_method_decl,
			     add_to_current_scope);
  return fn;
}

/// Test if a given function denoted by its name and linkage name is
/// suppressed by any of the suppression specifications associated to
/// a given context of native xml reading.
///
/// @param ctxt the native xml reading context of interest.
///
/// @param note the XML node that represents the fucntion.
/// match.
///
/// @return true iff at least one function specification matches the
/// function denoted by the node @p node.
static bool
function_is_suppressed(const read_context& ctxt, xmlNodePtr node)
{
  string fname;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    fname = xml::unescape_xml_string(CHAR_STR(s));

  string flinkage_name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "mangled-name"))
    flinkage_name = xml::unescape_xml_string(CHAR_STR(s));

  scope_decl* scope = ctxt.get_cur_scope();

  string qualified_name = build_qualified_name(scope, fname);

  return suppr::function_is_suppressed(ctxt, qualified_name, flinkage_name);
}

/// Test if a type denoted by its name, context and location is
/// suppressed by the suppression specifications that are associated
/// to a given read context.
///
/// @param ctxt the read context to consider.
///
/// @param note the XML node that represents the type.
///
/// @return true iff the type designated by @p node is suppressed by
///  at least of suppression specifications associated to the current
///  read context.
static bool
type_is_suppressed(const read_context& ctxt, xmlNodePtr node)
{
  string type_name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    type_name = xml::unescape_xml_string(CHAR_STR(s));

  location type_location;
  read_location(ctxt, node, type_location);

  scope_decl* scope = ctxt.get_cur_scope();

  string qualified_name = build_qualified_name(scope, type_name);

  bool type_is_private = false;
  return suppr::type_is_suppressed(ctxt, qualified_name, type_location,
				   type_is_private,
				   /*require_drop_property=*/true);
}

/// Build a @ref var_decl out of a an XML node that describes it iff
/// the variable denoted by the XML node is not suppressed by a
/// suppression specification associated to the current read context.
///
/// @param ctxt the read context to use.
///
/// @param node the XML node for the variable to consider.
///
/// @parm add_to_current_scope whether to add the built @ref var_decl
/// to the current scope or not.
///
/// @return true iff the @ref var_decl was built.
static var_decl_sptr
build_var_decl_if_not_suppressed(read_context&		ctxt,
				 const xmlNodePtr	node,
				 bool			add_to_current_scope)
{
  var_decl_sptr var;
  if (!variable_is_suppressed(ctxt, node))
    var = build_var_decl(ctxt, node, add_to_current_scope);
  return var;
}

/// Test if a variable denoted by its XML node is suppressed by a
/// suppression specification that is present in a given read context.
///
/// @param ctxt the read context to consider.
///
/// @param node the XML node of the variable to consider.
///
/// @return true iff the variable denoted by @p node is suppressed.
static bool
variable_is_suppressed(const read_context& ctxt, xmlNodePtr node)
{
  string name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    name = xml::unescape_xml_string(CHAR_STR(s));

  string linkage_name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "mangled-name"))
    linkage_name = xml::unescape_xml_string(CHAR_STR(s));

  scope_decl* scope = ctxt.get_cur_scope();

  string qualified_name = build_qualified_name(scope, name);

  return suppr::variable_is_suppressed(ctxt, qualified_name, linkage_name);
}

/// Test if a variable in a particular scope is suppressed by a
/// suppression specification that is present in a given read context.
///
/// @parm ctxt the read context to consider.
///
/// @param scope the scope of the variable to consider.
///
/// @param v the variable to consider.
///
/// @return true iff the variable @p v is suppressed.
static bool
variable_is_suppressed(const read_context& ctxt,
		       const scope_decl* scope,
		       const var_decl& v)
{
  string qualified_name = build_qualified_name(scope, v.get_name());
  return suppr::variable_is_suppressed(ctxt, qualified_name,
				       v.get_linkage_name());
}

/// Build pointer to var_decl from a 'var-decl' xml Node
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to build the var_decl from.
///
/// @return a pointer to a newly built var_decl upon successful
/// completion, a null pointer otherwise.
static shared_ptr<var_decl>
build_var_decl(read_context&	ctxt,
	       const xmlNodePtr node,
	       bool		add_to_current_scope)
{
  shared_ptr<var_decl> nil;

  if (!xmlStrEqual(node->name, BAD_CAST("var-decl")))
    return nil;

  string name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    name = xml::unescape_xml_string(CHAR_STR(s));

  string type_id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
    type_id = CHAR_STR(s);
  type_base_sptr underlying_type = ctxt.build_or_get_type_decl(type_id,
							       true);
  ABG_ASSERT(underlying_type);

  string mangled_name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "mangled-name"))
    mangled_name = xml::unescape_xml_string(CHAR_STR(s));

  decl_base::visibility vis = decl_base::VISIBILITY_NONE;
  read_visibility(node, vis);

  decl_base::binding bind = decl_base::BINDING_NONE;
  read_binding(node, bind);

  location locus;
  read_location(ctxt, node, locus);

  var_decl_sptr decl(new var_decl(name, underlying_type,
				  locus, mangled_name,
				  vis, bind));
  maybe_set_artificial_location(ctxt, node, decl);

  elf_symbol_sptr sym = build_elf_symbol_from_reference(ctxt, node);
  if (sym)
    decl->set_symbol(sym);

  ctxt.push_decl_to_current_scope(decl, add_to_current_scope);
  if (add_to_current_scope)
    {
      // This variable is really being kept in the IR, so let's record
      // that it's using its type.
      RECORD_ARTIFACT_AS_USED_BY(ctxt, underlying_type, decl);
    }

  if (decl->get_symbol() && decl->get_symbol()->is_public())
    decl->set_is_in_public_symbol_table(true);

  return decl;
}

/// Build a type_decl from a "type-decl" XML Node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the XML node to build the type_decl from.
///
/// @param add_to_current_scope if set to yes, the resulting of
/// this function is added to its current scope.
///
/// @return a pointer to type_decl upon successful completion, a null
/// pointer otherwise.
static shared_ptr<type_decl>
build_type_decl(read_context&		ctxt,
		const xmlNodePtr	node,
		bool			add_to_current_scope)
{
  shared_ptr<type_decl> nil;

  if (!xmlStrEqual(node->name, BAD_CAST("type-decl")))
    return nil;

  if (decl_base_sptr d = ctxt.get_decl_for_xml_node(node))
    {
      type_decl_sptr result = dynamic_pointer_cast<type_decl>(d);
      ABG_ASSERT(result);
      return result;
    }

  string name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    name = xml::unescape_xml_string(CHAR_STR(s));

  string id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    id = CHAR_STR(s);
  ABG_ASSERT(!id.empty());

  size_t size_in_bits= 0;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "size-in-bits"))
    size_in_bits = atoi(CHAR_STR(s));

  size_t alignment_in_bits = 0;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "alignment-in-bits"))
    alignment_in_bits = atoi(CHAR_STR(s));

  bool is_decl_only = false;
  read_is_declaration_only(node, is_decl_only);

  location loc;
  read_location(ctxt, node, loc);

  bool is_anonymous = false;
  read_is_anonymous(node, is_anonymous);

  if (type_base_sptr d = ctxt.get_type_decl(id))
    {
      // I've seen instances of DSOs where a type_decl would appear
      // several times.  Hugh.
      type_decl_sptr ty = dynamic_pointer_cast<type_decl>(d);
      ABG_ASSERT(ty);
      ABG_ASSERT(name == ty->get_name());
      ABG_ASSERT(ty->get_size_in_bits() == size_in_bits);
      ABG_ASSERT(ty->get_alignment_in_bits() == alignment_in_bits);
      return ty;
    }

  const environment* env = ctxt.get_environment();
  type_decl_sptr decl(new type_decl(env, name, size_in_bits,
				    alignment_in_bits, loc));
  maybe_set_artificial_location(ctxt, node, decl);
  decl->set_is_anonymous(is_anonymous);
  decl->set_is_declaration_only(is_decl_only);
  if (ctxt.push_and_key_type_decl(decl, id, add_to_current_scope))
    {
      ctxt.map_xml_node_to_decl(node, decl);
      return decl;
    }

  return nil;
}

/// Build a qualified_type_def from a 'qualified-type-def' xml node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to build the qualified_type_def from.
///
/// @param add_to_current_scope if set to yes, the resulting of this
/// function is added to its current scope.
///
/// @return a pointer to a newly built qualified_type_def upon
/// successful completion, a null pointer otherwise.
static qualified_type_def_sptr
build_qualified_type_decl(read_context&	ctxt,
			  const xmlNodePtr	node,
			  bool			add_to_current_scope)
{
  qualified_type_def_sptr nil;
  if (!xmlStrEqual(node->name, BAD_CAST("qualified-type-def")))
    return nil;

  if (decl_base_sptr d = ctxt.get_decl_for_xml_node(node))
    {
      qualified_type_def_sptr result =
	dynamic_pointer_cast<qualified_type_def>(d);
      ABG_ASSERT(result);
      return result;
    }

  string id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE (node, "id"))
    id = CHAR_STR(s);

  ABG_ASSERT(!id.empty());

  location loc;
  read_location(ctxt, node, loc);

  qualified_type_def::CV cv = qualified_type_def::CV_NONE;
    string const_str;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "const"))
    const_str = CHAR_STR(s);
  bool const_cv = const_str == "yes";

  string volatile_str;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "volatile"))
    volatile_str = CHAR_STR(s);
  bool volatile_cv = volatile_str == "yes";

  string restrict_str;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "restrict"))
    restrict_str = CHAR_STR(s);
  bool restrict_cv = restrict_str == "yes";

  if (const_cv)
    cv = cv | qualified_type_def::CV_CONST;
  if (volatile_cv)
    cv = cv | qualified_type_def::CV_VOLATILE;
  if (restrict_cv)
    cv = cv | qualified_type_def::CV_RESTRICT;

  string type_id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
    type_id = CHAR_STR(s);
  ABG_ASSERT(!type_id.empty());

  shared_ptr<type_base> underlying_type =
    ctxt.build_or_get_type_decl(type_id, true);
  ABG_ASSERT(underlying_type);

  qualified_type_def_sptr decl;
  if (type_base_sptr t = ctxt.get_type_decl(id))
    {
      decl = is_qualified_type(t);
      ABG_ASSERT(decl);
    }
  else
    {
      decl.reset(new qualified_type_def(underlying_type, cv, loc));
      maybe_set_artificial_location(ctxt, node, decl);
      ctxt.push_and_key_type_decl(decl, id, add_to_current_scope);
      RECORD_ARTIFACT_AS_USED_BY(ctxt, underlying_type, decl);
    }

  ctxt.map_xml_node_to_decl(node, decl);

  return decl;
}

/// Build a pointer_type_def from a 'pointer-type-def' xml node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to build the pointer_type_def from.
///
/// @param add_to_current_scope if set to yes, the resulting of
/// this function is added to its current scope.
///
/// @return a pointer to a newly built pointer_type_def upon
/// successful completion, a null pointer otherwise.
static pointer_type_def_sptr
build_pointer_type_def(read_context&	ctxt,
		       const xmlNodePtr node,
		       bool		add_to_current_scope)
{

  shared_ptr<pointer_type_def> nil;

  if (!xmlStrEqual(node->name, BAD_CAST("pointer-type-def")))
    return nil;

  if (decl_base_sptr d = ctxt.get_decl_for_xml_node(node))
    {
      pointer_type_def_sptr result =
	dynamic_pointer_cast<pointer_type_def>(d);
      ABG_ASSERT(result);
      return result;
    }

  string id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    id = CHAR_STR(s);
  ABG_ASSERT(!id.empty());

  if (type_base_sptr t = ctxt.get_type_decl(id))
    {
      pointer_type_def_sptr result = is_pointer_type(t);
      ABG_ASSERT(result);
      return result;
    }

  string type_id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
    type_id = CHAR_STR(s);

  size_t size_in_bits = ctxt.get_translation_unit()->get_address_size();
  size_t alignment_in_bits = 0;
  read_size_and_alignment(node, size_in_bits, alignment_in_bits);
  location loc;
  read_location(ctxt, node, loc);

  // Create the pointer type /before/ the pointed-to type.  After the
  // creation, the type is 'keyed' using ctxt.push_and_key_type_decl.
  // This means that the type can be retrieved from its type ID.  This
  // is so that if the pointed-to type indirectly uses this pointer
  // type (via recursion) then that is made possible.
  pointer_type_def_sptr t(new pointer_type_def(ctxt.get_environment(),
					       size_in_bits,
					       alignment_in_bits,
					       loc));
  maybe_set_artificial_location(ctxt, node, t);

  if (ctxt.push_and_key_type_decl(t, id, add_to_current_scope))
    ctxt.map_xml_node_to_decl(node, t);

  type_base_sptr pointed_to_type =
    ctxt.build_or_get_type_decl(type_id, true);
  ABG_ASSERT(pointed_to_type);

  t->set_pointed_to_type(pointed_to_type);
  RECORD_ARTIFACT_AS_USED_BY(ctxt, pointed_to_type, t);
  return t;
}

/// Build a reference_type_def from a pointer to 'reference-type-def'
/// xml node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to build the reference_type_def from.
///
/// @param add_to_current_scope if set to yes, the resulting of
/// this function is added to its current scope.
///
/// @return a pointer to a newly built reference_type_def upon
/// successful completio, a null pointer otherwise.
static shared_ptr<reference_type_def>
build_reference_type_def(read_context&		ctxt,
			 const xmlNodePtr	node,
			 bool			add_to_current_scope)
{
  shared_ptr<reference_type_def> nil;

  if (!xmlStrEqual(node->name, BAD_CAST("reference-type-def")))
    return nil;

  if (decl_base_sptr d = ctxt.get_decl_for_xml_node(node))
    {
      reference_type_def_sptr result =
	dynamic_pointer_cast<reference_type_def>(d);
      ABG_ASSERT(result);
      return result;
    }

  string id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    id = CHAR_STR(s);
  ABG_ASSERT(!id.empty());

  if (type_base_sptr d = ctxt.get_type_decl(id))
    {
      reference_type_def_sptr ty = is_reference_type(d);
      ABG_ASSERT(ty);
      return ty;
    }

  location loc;
  read_location(ctxt, node, loc);
  string kind;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "kind"))
    kind = CHAR_STR(s); // this should be either "lvalue" or "rvalue".
  bool is_lvalue = kind == "lvalue";

  size_t size_in_bits = ctxt.get_translation_unit()->get_address_size();
  size_t alignment_in_bits = 0;
  read_size_and_alignment(node, size_in_bits, alignment_in_bits);

  string type_id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
    type_id = CHAR_STR(s);
  ABG_ASSERT(!type_id.empty());

  // Create the reference type /before/ the pointed-to type.  After
  // the creation, the type is 'keyed' using
  // ctxt.push_and_key_type_decl.  This means that the type can be
  // retrieved from its type ID.  This is so that if the pointed-to
  // type indirectly uses this reference type (via recursion) then
  // that is made possible.
  reference_type_def_sptr t(new reference_type_def(ctxt.get_environment(),
						   is_lvalue, size_in_bits,
						   alignment_in_bits, loc));
  maybe_set_artificial_location(ctxt, node, t);
  if (ctxt.push_and_key_type_decl(t, id, add_to_current_scope))
    ctxt.map_xml_node_to_decl(node, t);

  type_base_sptr pointed_to_type =
    ctxt.build_or_get_type_decl(type_id,/*add_to_current_scope=*/ true);
  ABG_ASSERT(pointed_to_type);
  t->set_pointed_to_type(pointed_to_type);
  RECORD_ARTIFACT_AS_USED_BY(ctxt, pointed_to_type, t);

  return t;
}

/// Build a function_type from a pointer to 'function-type'
/// xml node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to build the function_type from.
///
/// @param add_to_current_scope if set to yes, the result of
/// this function is added to its current scope.
///
/// @return a pointer to a newly built function_type upon
/// successful completion, a null pointer otherwise.
static function_type_sptr
build_function_type(read_context&	ctxt,
		    const xmlNodePtr	node,
		    bool /*add_to_current_scope*/)
{
  function_type_sptr nil;

  if (!xmlStrEqual(node->name, BAD_CAST("function-type")))
    return nil;

  string id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    id = CHAR_STR(s);
  ABG_ASSERT(!id.empty());

  string method_class_id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "method-class-id"))
    method_class_id = CHAR_STR(s);

  bool is_method_t = !method_class_id.empty();

  size_t size = ctxt.get_translation_unit()->get_address_size(), align = 0;
  read_size_and_alignment(node, size, align);

  environment* env = ctxt.get_environment();
  ABG_ASSERT(env);
  std::vector<shared_ptr<function_decl::parameter> > parms;
  type_base_sptr return_type = env->get_void_type();

  class_or_union_sptr method_class_type;
  if (is_method_t)
    {
      method_class_type =
	is_class_or_union_type(ctxt.build_or_get_type_decl(method_class_id,
							   /*add_decl_to_scope=*/true));
      ABG_ASSERT(method_class_type);
    }


 function_type_sptr fn_type(is_method_t
			    ? new method_type(method_class_type,
					      ctxt.get_environment(),
					      size, align)
			    : new function_type(return_type,
						parms, size, align));

  ctxt.get_translation_unit()->bind_function_type_life_time(fn_type);
  ctxt.key_type_decl(fn_type, id);
  RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(ctxt, fn_type);

  for (xmlNodePtr n = xmlFirstElementChild(node);
       n;
       n = xmlNextElementSibling(n))
    {
      if (xmlStrEqual(n->name, BAD_CAST("parameter")))
	{
	  if (function_decl::parameter_sptr p =
	      build_function_parameter(ctxt, n))
	    parms.push_back(p);
	}
      else if (xmlStrEqual(n->name, BAD_CAST("return")))
	{
	  string type_id;
	  if (xml_char_sptr s =
	      xml::build_sptr(xmlGetProp(n, BAD_CAST("type-id"))))
	    type_id = CHAR_STR(s);
	  if (!type_id.empty())
	    fn_type->set_return_type(ctxt.build_or_get_type_decl
				     (type_id, true));
	}
    }

  fn_type->set_parameters(parms);

  return fn_type;
}

/// Build a array_type_def::subrange_type from a 'subrange' xml node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to build the
/// array_type_def::subrange_type from.
///
///
/// @return a pointer to a newly built array_type_def::subrange_type
/// upon successful completion, a null pointer otherwise.
static array_type_def::subrange_sptr
build_subrange_type(read_context&	ctxt,
		    const xmlNodePtr	node)
{
  array_type_def::subrange_sptr nil;

  if (!node || !xmlStrEqual(node->name, BAD_CAST("subrange")))
    return nil;

  if (decl_base_sptr d = ctxt.get_decl_for_xml_node(node))
    {
      array_type_def::subrange_sptr result =
	dynamic_pointer_cast<array_type_def::subrange_type>(d);
      ABG_ASSERT(result);
      return result;
    }

  string id;
  // Note that in early implementations, the subrange didn't carry its
  // own ID as the subrange was just a detail of an array.  So we
  // still need to support the abixml emitted by those early
  // implementations.
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    id = CHAR_STR(s);

  if (!id.empty())
    if (type_base_sptr d = ctxt.get_type_decl(id))
      {
	array_type_def::subrange_sptr ty = is_subrange_type(d);
	ABG_ASSERT(ty);
	return ty;
      }

  string name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    name = CHAR_STR(s);

  uint64_t length = 0;
  string length_str;
  bool is_infinite = false;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "length"))
    {
      if (string(CHAR_STR(s)) == "infinite")
	is_infinite = true;
      else
	length = strtoull(CHAR_STR(s), NULL, 0);
    }

  int64_t lower_bound = 0, upper_bound = 0;
  bool bounds_present = false;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "lower-bound"))
    {
      lower_bound = strtoll(CHAR_STR(s), NULL, 0);
      s = XML_NODE_GET_ATTRIBUTE(node, "upper-bound");
      if (!string(CHAR_STR(s)).empty())
	upper_bound = strtoll(CHAR_STR(s), NULL, 0);
      bounds_present = true;
      ABG_ASSERT(is_infinite
		 || (length == (uint64_t) upper_bound - lower_bound + 1));
    }

  string underlying_type_id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
    underlying_type_id = CHAR_STR(s);

  type_base_sptr underlying_type;
  if (!underlying_type_id.empty())
    {
      underlying_type = ctxt.build_or_get_type_decl(underlying_type_id, true);
      ABG_ASSERT(underlying_type);
    }

  location loc;
  read_location(ctxt, node, loc);

  // Note that DWARF would actually have a lower_bound of -1 for an
  // array of length 0.
  array_type_def::subrange_type::bound_value max_bound;
  array_type_def::subrange_type::bound_value min_bound;
  if (!is_infinite)
    if (length > 0)
      // By default, if no 'lower-bound/upper-bound' attributes are
      // set, we assume that the lower bound is 0 and the upper bound
      // is length - 1.
      max_bound.set_signed(length - 1);

  if (bounds_present)
    {
      // So lower_bound/upper_bound are set.  Let's set them rather
      // than assume that mind_bound is zero.
      min_bound.set_signed(lower_bound);
      max_bound.set_signed(upper_bound);
    }

  array_type_def::subrange_sptr p
    (new array_type_def::subrange_type(ctxt.get_environment(),
				       name, min_bound, max_bound,
				       underlying_type, loc));
  maybe_set_artificial_location(ctxt, node, p);
  p->is_infinite(is_infinite);

  return p;
}

/// Build a array_type_def from a 'array-type-def' xml node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to build the array_type_def from.
///
/// @param add_to_current_scope if set to yes, the resulting of
/// this function is added to its current scope.
///
/// @return a pointer to a newly built array_type_def upon
/// successful completion, a null pointer otherwise.
static array_type_def_sptr
build_array_type_def(read_context&	ctxt,
		     const		xmlNodePtr node,
		     bool		add_to_current_scope)
{

  array_type_def_sptr nil;

  if (!xmlStrEqual(node->name, BAD_CAST("array-type-def")))
    return nil;

  if (decl_base_sptr d = ctxt.get_decl_for_xml_node(node))
    {
      array_type_def_sptr result =
	dynamic_pointer_cast<array_type_def>(d);
      ABG_ASSERT(result);
      return result;
    }

  string id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    id = CHAR_STR(s);
  ABG_ASSERT(!id.empty());

  if (type_base_sptr d = ctxt.get_type_decl(id))
    {
      array_type_def_sptr ty = is_array_type(d);
      ABG_ASSERT(ty);
      return ty;
    }

  int dimensions = 0;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "dimensions"))
    dimensions = atoi(CHAR_STR(s));

  string type_id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
    type_id = CHAR_STR(s);

  // maybe building the type of array elements triggered building this
  // one in the mean time ...
  if (decl_base_sptr d = ctxt.get_decl_for_xml_node(node))
    {
      array_type_def_sptr result =
	dynamic_pointer_cast<array_type_def>(d);
      ABG_ASSERT(result);
      return result;
    }

  size_t size_in_bits = 0, alignment_in_bits = 0;
  bool has_size_in_bits = false;
  char *endptr;

  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "size-in-bits"))
    {
      size_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
      if (*endptr != '\0')
	{
	  if (!strcmp(CHAR_STR(s), "infinite"))
	    size_in_bits = (size_t) -1;
	  else
	    return nil;
	}
      has_size_in_bits = true;
    }

  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "alignment-in-bits"))
    {
      alignment_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
      if (*endptr != '\0')
	return nil;
    }

  location loc;
  read_location(ctxt, node, loc);
  array_type_def::subranges_type subranges;

  for (xmlNodePtr n = xmlFirstElementChild(node);
       n;
       n = xmlNextElementSibling(n))
    if (xmlStrEqual(n->name, BAD_CAST("subrange")))
      {
	if (array_type_def::subrange_sptr s =
	    build_subrange_type(ctxt, n))
	  {
	    MAYBE_MAP_TYPE_WITH_TYPE_ID(s, n);
	    if (add_to_current_scope)
	      {
		add_decl_to_scope(s, ctxt.get_cur_scope());
		ctxt.maybe_canonicalize_type(s);
	      }
	    subranges.push_back(s);
	  }
      }

  // The type of array elements.
  type_base_sptr type =
    ctxt.build_or_get_type_decl(type_id, true);
  ABG_ASSERT(type);

  array_type_def_sptr ar_type(new array_type_def(type, subranges, loc));
  maybe_set_artificial_location(ctxt, node, ar_type);
  if (ctxt.push_and_key_type_decl(ar_type, id, add_to_current_scope))
    ctxt.map_xml_node_to_decl(node, ar_type);
  RECORD_ARTIFACT_AS_USED_BY(ctxt, type, ar_type);

  if (dimensions != ar_type->get_dimension_count()
      || (alignment_in_bits
	  != ar_type->get_element_type()->get_alignment_in_bits()))
    return nil;

  if (has_size_in_bits && size_in_bits != (size_t) -1
      && size_in_bits != ar_type->get_size_in_bits())
    {
      // We have a potential discrepancy between calculated and recorded sizes.
      size_t element_size = ar_type->get_element_type()->get_size_in_bits();
      if (element_size && element_size != (size_t)-1)
	{
	  // Older versions miscalculated multidimensional array sizes.
	  size_t bad_count = 0;
	  for (vector<array_type_def::subrange_sptr>::const_iterator i =
		 subranges.begin();
	       i != subranges.end();
	       ++i)
	    bad_count += (*i)->get_length();
	  if (size_in_bits == bad_count * element_size)
	    {
	      static bool reported = false;
	      if (!reported)
		{
		  std::cerr << "notice: Found incorrectly calculated array "
			    << "sizes in XML - this is benign.\nOlder versions "
			    << "of libabigail miscalculated multidimensional "
			    << "array sizes." << std::endl;
		  reported = true;
		}
	    }
	  else
	    {
	      std::cerr << "error: Found incorrectly calculated array size in "
			<< "XML (id=\"" << id <<  "\")." << std::endl;
	      ABG_ASSERT_NOT_REACHED;
	    }
	}
    }

  return ar_type;
}

/// Build an @ref enum_type_decl from the XML node that represents it,
/// if it was not suppressed by a supression specification present in
/// the current read_context.
///
/// @param ctxt the read_context to take into account.
///
/// @param node the XML node representing the @ref enum_type_decl to
/// build.
///
/// @param add_to_current_scope whether to add the built @ref
/// enum_type_decl to the current scope.
///
/// @return the newly built @ref enum_type_decl iff it was effectively
/// built.
static enum_type_decl_sptr
build_enum_type_decl_if_not_suppressed(read_context&	ctxt,
				       const xmlNodePtr node,
				       bool		add_to_current_scope)
{
  enum_type_decl_sptr enum_type;
  if (!type_is_suppressed(ctxt, node))
    enum_type = build_enum_type_decl(ctxt, node, add_to_current_scope);
  return enum_type;
}

/// Build an enum_type_decl from an 'enum-type-decl' xml node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to build the enum_type_decl from.
///
/// param add_to_current_scope if set to yes, the resulting of this
/// function is added to its current scope.
///
/// @return a pointer to a newly built enum_type_decl upon successful
/// completion, a null pointer otherwise.
static enum_type_decl_sptr
build_enum_type_decl(read_context&	ctxt,
		     const xmlNodePtr	node,
		     bool		add_to_current_scope)
{
  enum_type_decl_sptr nil;

  if (!xmlStrEqual(node->name, BAD_CAST("enum-decl")))
    return nil;

  if (decl_base_sptr d = ctxt.get_decl_for_xml_node(node))
    {
      enum_type_decl_sptr result =
	dynamic_pointer_cast<enum_type_decl>(d);
      ABG_ASSERT(result);
      return result;
    }

  string name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    name = xml::unescape_xml_string(CHAR_STR(s));

  string linkage_name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "linkage-name"))
    linkage_name = xml::unescape_xml_string(CHAR_STR(s));

  location loc;
  read_location(ctxt, node, loc);

  bool is_decl_only = false;
  read_is_declaration_only(node, is_decl_only);

  bool is_anonymous = false;
  read_is_anonymous(node, is_anonymous);

  bool is_artificial = false;
  read_is_artificial(node, is_artificial);

  string id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    id = CHAR_STR(s);

  ABG_ASSERT(!id.empty());

  const environment* env = ctxt.get_environment();
  ABG_ASSERT(env);

  string base_type_id;
  enum_type_decl::enumerators enums;
  for (xmlNodePtr n = xmlFirstElementChild(node);
       n;
       n = xmlNextElementSibling(n))
    {
      if (xmlStrEqual(n->name, BAD_CAST("underlying-type")))
	{
	  xml_char_sptr a = xml::build_sptr(xmlGetProp(n, BAD_CAST("type-id")));
	  if (a)
	    base_type_id = CHAR_STR(a);
	  continue;
	}

      if (xmlStrEqual(n->name, BAD_CAST("enumerator")))
	{
	  string name;
	  int64_t value = 0;

	  xml_char_sptr a = xml::build_sptr(xmlGetProp(n, BAD_CAST("name")));
	  if (a)
	    name = xml::unescape_xml_string(CHAR_STR(a));

	  a = xml::build_sptr(xmlGetProp(n, BAD_CAST("value")));
	  if (a)
	    {
	      value = strtoll(CHAR_STR(a), NULL, 0);
	      // when strtoll encounters overflow or underflow, errno
	      // is set to ERANGE and the returned value is either
	      // LLONG_MIN or LLONG_MAX.
	      if ((errno == ERANGE)
		  && (value == LLONG_MIN || value == LLONG_MAX))
		return nil;
	    }

	  enums.push_back(enum_type_decl::enumerator(env, name, value));
	}
    }

  type_base_sptr underlying_type =
    ctxt.build_or_get_type_decl(base_type_id, true);
  ABG_ASSERT(underlying_type);

  enum_type_decl_sptr t(new enum_type_decl(name, loc,
					   underlying_type,
					   enums, linkage_name));
  maybe_set_artificial_location(ctxt, node, t);
  t->set_is_anonymous(is_anonymous);
  t->set_is_artificial(is_artificial);
  t->set_is_declaration_only(is_decl_only);
  if (ctxt.push_and_key_type_decl(t, id, add_to_current_scope))
    {
      maybe_set_naming_typedef(ctxt, node, t);
      ctxt.map_xml_node_to_decl(node, t);
      RECORD_ARTIFACT_AS_USED_BY(ctxt, underlying_type, t);
      return t;
    }

  return nil;
}

/// Build a typedef_decl from a 'typedef-decl' xml node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to build the typedef_decl from.
///
/// @return a pointer to a newly built typedef_decl upon successful
/// completion, a null pointer otherwise.
static shared_ptr<typedef_decl>
build_typedef_decl(read_context&	ctxt,
		   const xmlNodePtr	node,
		   bool		add_to_current_scope)
{
  shared_ptr<typedef_decl> nil;

  if (!xmlStrEqual(node->name, BAD_CAST("typedef-decl")))
    return nil;

  if (decl_base_sptr d = ctxt.get_decl_for_xml_node(node))
    {
      typedef_decl_sptr result = is_typedef(d);
      ABG_ASSERT(result);
      return result;
    }

  string id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    id = CHAR_STR(s);
  ABG_ASSERT(!id.empty());

  if (type_base_sptr t = ctxt.get_type_decl(id))
    {
      typedef_decl_sptr result = is_typedef(t);
      ABG_ASSERT(result);
      return result;
    }

  string name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    name = xml::unescape_xml_string(CHAR_STR(s));

  location loc;
  read_location(ctxt, node, loc);

  string type_id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
    type_id = CHAR_STR(s);
  ABG_ASSERT(!type_id.empty());

  type_base_sptr underlying_type(ctxt.build_or_get_type_decl(type_id, true));
  ABG_ASSERT(underlying_type);

  typedef_decl_sptr t(new typedef_decl(name, underlying_type, loc));
  maybe_set_artificial_location(ctxt, node, t);
  ctxt.push_and_key_type_decl(t, id, add_to_current_scope);
  ctxt.map_xml_node_to_decl(node, t);
  RECORD_ARTIFACT_AS_USED_BY(ctxt, underlying_type, t);

  return t;
}

/// Build a class from its XML node if it is not suppressed by a
/// suppression specification that is present in the read context.
///
/// @param ctxt the read context to consider.
///
/// @param node the XML node to consider.
///
/// @param add_to_current_scope whether to add the built class to the
/// current context or not.
///
/// @return true iff the class was built.
static class_decl_sptr
build_class_decl_if_not_suppressed(read_context&	ctxt,
				   const xmlNodePtr	node,
				   bool		add_to_current_scope)
{
  class_decl_sptr class_type;
  if (!type_is_suppressed(ctxt, node))
    class_type = build_class_decl(ctxt, node, add_to_current_scope);
  return class_type;
}

/// Build a @ref union_decl from its XML node if it is not suppressed
/// by a suppression specification that is present in the read
/// context.
///
/// @param ctxt the read context to consider.
///
/// @param node the XML node to consider.
///
/// @param add_to_current_scope whether to add the built @ref
/// union_decl to the current context or not.
///
/// @return true iff the @ref union_decl was built.
static union_decl_sptr
build_union_decl_if_not_suppressed(read_context&	ctxt,
				   const xmlNodePtr	node,
				   bool		add_to_current_scope)
{
  union_decl_sptr union_type;
  if (!type_is_suppressed(ctxt, node))
    union_type = build_union_decl(ctxt, node, add_to_current_scope);
  return union_type;
}

/// Build a class_decl from a 'class-decl' xml node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to build the class_decl from.
///
/// @param add_to_current_scope if yes, the resulting class node
/// hasn't triggered voluntarily the adding of the resulting
/// class_decl_sptr to the current scope.
///
/// @return a pointer to class_decl upon successful completion, a null
/// pointer otherwise.
static class_decl_sptr
build_class_decl(read_context&		ctxt,
		 const xmlNodePtr	node,
		 bool			add_to_current_scope)
{
  class_decl_sptr nil;

  if (!xmlStrEqual(node->name, BAD_CAST("class-decl")))
    return nil;

  if (decl_base_sptr d = ctxt.get_decl_for_xml_node(node))
    {
      class_decl_sptr result = dynamic_pointer_cast<class_decl>(d);
      ABG_ASSERT(result);
      return result;
    }

  string name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    name = xml::unescape_xml_string(CHAR_STR(s));

  size_t size_in_bits = 0, alignment_in_bits = 0;
  read_size_and_alignment(node, size_in_bits, alignment_in_bits);

  decl_base::visibility vis = decl_base::VISIBILITY_NONE;
  read_visibility(node, vis);

  bool is_artificial = false;
  read_is_artificial(node, is_artificial);

  string id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    id = CHAR_STR(s);

  location loc;
  read_location(ctxt, node, loc);

  class_decl::member_types mbrs;
  class_decl::data_members data_mbrs;
  class_decl::member_functions mbr_functions;
  class_decl::base_specs  bases;

  class_decl_sptr decl;

  bool is_decl_only = false;
  read_is_declaration_only(node, is_decl_only);

  bool is_struct = false;
  read_is_struct(node, is_struct);

  bool is_anonymous = false;
  read_is_anonymous(node, is_anonymous);

  ABG_ASSERT(!id.empty());

  class_decl_sptr previous_definition, previous_declaration;
  if (!is_anonymous)
    if (type_base_sptr t = ctxt.get_type_decl(id))
      {
	previous_definition  = is_class_type(t);
	ABG_ASSERT(previous_definition);
      }

  const vector<type_base_sptr> *types_ptr = 0;
  if (!is_anonymous && !previous_definition)
    types_ptr = ctxt.get_all_type_decls(id);
  if (types_ptr)
    {
      // Lets look at the previous declarations and the first previous
      // definition of this type that we've already seen while parsing
      // this corpus.
      for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
	   i != types_ptr->end();
	   ++i)
	{
	  class_decl_sptr klass = is_class_type(*i);
	  ABG_ASSERT(klass);
	  if (klass->get_is_declaration_only()
	      && !klass->get_definition_of_declaration())
	    previous_declaration = klass;
	  else if (!klass->get_is_declaration_only()
		   && !previous_definition)
	    previous_definition = klass;
	  if (previous_definition && previous_declaration)
	    break;
	}

      if (previous_declaration)
	ABG_ASSERT(previous_declaration->get_name() == name);

      if (previous_definition)
	ABG_ASSERT(previous_definition->get_name() == name);

      if (is_decl_only && previous_declaration)
	return previous_declaration;
    }

  const environment* env = ctxt.get_environment();
  ABG_ASSERT(env);

  if (!is_decl_only && previous_definition)
    // We are in the case where we've read this class definition
    // before, but we might need to update it to add some new stuff to
    // it; we might thus find the new stuff to add in the current
    // (new) incarnation of that definition that we are currently
    // reading.
    decl = previous_definition;
  else
    {
      if (is_decl_only)
	{
	  decl.reset(new class_decl(env, name, is_struct));
	  if (size_in_bits)
	    decl->set_size_in_bits(size_in_bits);
	  if (is_anonymous)
	    decl->set_is_anonymous(is_anonymous);
	  decl->set_location(loc);
	}
      else
	decl.reset(new class_decl(env, name, size_in_bits, alignment_in_bits,
				  is_struct, loc, vis, bases, mbrs,
				  data_mbrs, mbr_functions, is_anonymous));
    }

  maybe_set_artificial_location(ctxt, node, decl);
  decl->set_is_artificial(is_artificial);

  string def_id;
  bool is_def_of_decl = false;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "def-of-decl-id"))
    def_id = CHAR_STR(s);

  if (!def_id.empty())
    {
      decl_base_sptr d = is_decl(ctxt.get_type_decl(def_id));
      if (d && d->get_is_declaration_only())
	{
	  is_def_of_decl = true;
	  decl->set_earlier_declaration(d);
	  d->set_definition_of_declaration(decl);
	}
    }

  if (!is_decl_only
      && decl
      && !decl->get_is_declaration_only()
      && previous_declaration)
    {
      // decl is the definition of the previous declaration
      // previous_declaration.
      //
      // Let's link them.
      decl->set_earlier_declaration(is_decl(previous_declaration));
      for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
	   i != types_ptr->end();
	   ++i)
	{
	  class_decl_sptr d = is_class_type(*i);
	  ABG_ASSERT(d);
	  if (d->get_is_declaration_only()
	      && !d->get_definition_of_declaration())
	    {
	      previous_declaration->set_definition_of_declaration(decl);
	      is_def_of_decl = true;
	    }
	}
    }

  if (is_decl_only && previous_definition)
    {
      // decl is a declaration of the previous definition
      // previous_definition.  Let's link them.
      ABG_ASSERT(decl->get_is_declaration_only()
	     && !decl->get_definition_of_declaration());
      decl->set_definition_of_declaration(previous_definition);
    }

  ABG_ASSERT(!is_decl_only || !is_def_of_decl);

  ctxt.push_decl_to_current_scope(decl, add_to_current_scope);

  ctxt.map_xml_node_to_decl(node, decl);
  ctxt.key_type_decl(decl, id);

  // If this class has a naming typedef, get it and refer to it.
  maybe_set_naming_typedef(ctxt, node, decl);

  for (xmlNodePtr n = xmlFirstElementChild(node);
       !is_decl_only && n;
       n = xmlNextElementSibling(n))
    {
      if (xmlStrEqual(n->name, BAD_CAST("base-class")))
	{
	  access_specifier access =
	    is_struct
	    ? public_access
	    : private_access;
	  read_access(n, access);

	  string type_id;
	  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(n, "type-id"))
	    type_id = CHAR_STR(s);
	  shared_ptr<class_decl> b =
	    dynamic_pointer_cast<class_decl>
	    (ctxt.build_or_get_type_decl(type_id, true));
	  ABG_ASSERT(b);

	  if (decl->find_base_class(b->get_qualified_name()))
	    // We are in updating mode for this class.  The version of
	    // the class we have already has this base class, so we
	    // are not going to add it again.
	    continue;

	  size_t offset_in_bits = 0;
	  bool offset_present = read_offset_in_bits (n, offset_in_bits);

	  bool is_virtual = false;
	  read_is_virtual (n, is_virtual);

	  shared_ptr<class_decl::base_spec> base (new class_decl::base_spec
						  (b, access,
						   offset_present
						   ? (long) offset_in_bits
						   : -1,
						   is_virtual));
	  decl->add_base_specifier(base);
	}
      else if (xmlStrEqual(n->name, BAD_CAST("member-type")))
	{
	  access_specifier access =
	    is_struct
	    ? public_access
	    : private_access;
	  read_access(n, access);

	  ctxt.map_xml_node_to_decl(n, decl);

	  for (xmlNodePtr p = xmlFirstElementChild(n);
	       p;
	       p = xmlNextElementSibling(p))
	    {
	      if (type_base_sptr t =
		  build_type(ctxt, p, /*add_to_current_scope=*/true))
		{
		  decl_base_sptr td = get_type_declaration(t);
		  ABG_ASSERT(td);
		  set_member_access_specifier(td, access);
		  ctxt.maybe_canonicalize_type(t, !add_to_current_scope);
		  xml_char_sptr i= XML_NODE_GET_ATTRIBUTE(p, "id");
		  string id = CHAR_STR(i);
		  ABG_ASSERT(!id.empty());
		  ctxt.key_type_decl(t, id);
		  ctxt.map_xml_node_to_decl(p, td);
		}
	    }
	}
      else if (xmlStrEqual(n->name, BAD_CAST("data-member")))
	{
	  ctxt.map_xml_node_to_decl(n, decl);

	  access_specifier access =
	    is_struct
	    ? public_access
	    : private_access;
	  read_access(n, access);

	  bool is_laid_out = false;
	  size_t offset_in_bits = 0;
	  if (read_offset_in_bits(n, offset_in_bits))
	    is_laid_out = true;

	  bool is_static = false;
	  read_static(n, is_static);

	  for (xmlNodePtr p = xmlFirstElementChild(n);
	       p;
	       p = xmlNextElementSibling(p))
	    {
	      if (var_decl_sptr v =
		  build_var_decl(ctxt, p, /*add_to_cur_scope=*/false))
		{
		  if (decl->find_data_member(v))
		    {
		      // We are in updating mode and the current
		      // version of this class already has this data
		      // member, so we are not going to add it again.
		      // So we need to discard the data member we have
		      // built (and that was pushed to the current
		      // stack of decls built) and move on.
		      decl_base_sptr d = ctxt.pop_decl();
		      ABG_ASSERT(is_var_decl(d));
		      continue;
		    }

		  if (!variable_is_suppressed(ctxt, decl.get(), *v))
		    {
		      decl->add_data_member(v, access,
					    is_laid_out,
					    is_static,
					    offset_in_bits);
		      if (is_static)
			ctxt.maybe_add_var_to_exported_decls(v.get());
		      // Now let's record the fact that the data
		      // member uses its type and that the class being
		      // built uses the data member.
		      if (is_anonymous_data_member(v))
			// This data member is anonymous so recording
			// that it uses its type is useless because we
			// can't name it.  Rather, let's record that
			// the class being built uses the type of the
			// (anonymous) data member.
			RECORD_ARTIFACT_AS_USED_BY(ctxt, v->get_type(), decl);
		      else
			{
			  RECORD_ARTIFACT_AS_USED_BY(ctxt, v->get_type(), v);
			  RECORD_ARTIFACT_AS_USED_BY(ctxt, v, decl);
			}
		    }
		}
	    }
	}
      else if (xmlStrEqual(n->name, BAD_CAST("member-function")))
	{
	  ctxt.map_xml_node_to_decl(n, decl);

	  access_specifier access =
	    is_struct
	    ? public_access
	    : private_access;
	  read_access(n, access);

	  bool is_virtual = false;
	  ssize_t vtable_offset = -1;
	  if (xml_char_sptr s =
	      XML_NODE_GET_ATTRIBUTE(n, "vtable-offset"))
	    {
	      is_virtual = true;
	      vtable_offset = atoi(CHAR_STR(s));
	    }

	  bool is_static = false;
	  read_static(n, is_static);

	  bool is_ctor = false, is_dtor = false, is_const = false;
	  read_cdtor_const(n, is_ctor, is_dtor, is_const);

	  for (xmlNodePtr p = xmlFirstElementChild(n);
	       p;
	       p = xmlNextElementSibling(p))
	    {
	      if (function_decl_sptr f =
		  build_function_decl_if_not_suppressed(ctxt, p, decl,
							/*add_to_cur_sc=*/true))
		{
		  method_decl_sptr m = is_method_decl(f);
		  ABG_ASSERT(m);
		  set_member_access_specifier(m, access);
		  set_member_is_static(m, is_static);
		  if (vtable_offset != -1)
		    set_member_function_vtable_offset(m, vtable_offset);
		  set_member_function_is_virtual(m, is_virtual);
		  set_member_function_is_ctor(m, is_ctor);
		  set_member_function_is_dtor(m, is_dtor);
		  set_member_function_is_const(m, is_const);
		  break;
		}
	    }
	}
      else if (xmlStrEqual(n->name, BAD_CAST("member-template")))
	{
	  ctxt.map_xml_node_to_decl(n, decl);

	  access_specifier access =
	    is_struct
	    ? public_access
	    : private_access;
	  read_access(n, access);

	  bool is_static = false;
	  read_static(n, is_static);

	  bool is_ctor = false, is_dtor = false, is_const = false;
	  read_cdtor_const(n, is_ctor, is_dtor, is_const);

	  for (xmlNodePtr p = xmlFirstElementChild(n);
	       p;
	       p = xmlNextElementSibling(p))
	    {
	      if (shared_ptr<function_tdecl> f =
		  build_function_tdecl(ctxt, p,
				       /*add_to_current_scope=*/true))
		{
		  shared_ptr<member_function_template> m
		    (new member_function_template(f, access, is_static,
						  is_ctor, is_const));
		  ABG_ASSERT(f->get_scope());
		  decl->add_member_function_template(m);
		}
	      else if (shared_ptr<class_tdecl> c =
		       build_class_tdecl(ctxt, p,
					 /*add_to_current_scope=*/true))
		{
		  member_class_template_sptr m(new member_class_template(c,
									 access,
									 is_static));
		  ABG_ASSERT(c->get_scope());
		  decl->add_member_class_template(m);
		}
	    }
	}
    }

  ctxt.pop_scope_or_abort(decl);

  return decl;
}

/// Build a union_decl from a 'union-decl' xml node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to build the union_decl from.
///
/// @param add_to_current_scope if yes, the resulting union node
/// hasn't triggered voluntarily the adding of the resulting
/// union_decl_sptr to the current scope.
///
/// @return a pointer to union_decl upon successful completion, a null
/// pointer otherwise.
static union_decl_sptr
build_union_decl(read_context& ctxt,
		 const xmlNodePtr node,
		 bool add_to_current_scope)
{
  union_decl_sptr nil;

  if (!xmlStrEqual(node->name, BAD_CAST("union-decl")))
    return nil;

  if (decl_base_sptr d = ctxt.get_decl_for_xml_node(node))
    {
      union_decl_sptr result = dynamic_pointer_cast<union_decl>(d);
      ABG_ASSERT(result);
      return result;
    }

  string name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    name = xml::unescape_xml_string(CHAR_STR(s));

  size_t size_in_bits = 0, alignment_in_bits = 0;
  read_size_and_alignment(node, size_in_bits, alignment_in_bits);

  decl_base::visibility vis = decl_base::VISIBILITY_NONE;
  read_visibility(node, vis);

  bool is_artificial = false;
  read_is_artificial(node, is_artificial);

  string id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    id = CHAR_STR(s);

  location loc;
  read_location(ctxt, node, loc);

  union_decl::member_types mbrs;
  union_decl::data_members data_mbrs;
  union_decl::member_functions mbr_functions;

  union_decl_sptr decl;

  bool is_decl_only = false;
  read_is_declaration_only(node, is_decl_only);

  bool is_anonymous = false;
  read_is_anonymous(node, is_anonymous);

  ABG_ASSERT(!id.empty());
  union_decl_sptr previous_definition, previous_declaration;
  const vector<type_base_sptr> *types_ptr = 0;
  if (!is_anonymous)
    types_ptr = ctxt.get_all_type_decls(id);
  if (types_ptr)
    {
      // Lets look at the previous declarations and the first previous
      // definition of this type that we've already seen while parsing
      // this corpus.
      for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
	   i != types_ptr->end();
	   ++i)
	{
	  union_decl_sptr onion = is_union_type(*i);
	  ABG_ASSERT(onion);
	  if (onion->get_is_declaration_only()
	      && !onion->get_definition_of_declaration())
	    previous_declaration = onion;
	  else if (!onion->get_is_declaration_only()
		   && !previous_definition)
	    previous_definition = onion;
	  if (previous_definition && previous_declaration)
	    break;
	}

      if (previous_declaration)
	ABG_ASSERT(previous_declaration->get_name() == name);

      if (previous_definition)
	ABG_ASSERT(previous_definition->get_name() == name);

      if (is_decl_only && previous_declaration)
	return previous_declaration;
    }

  const environment* env = ctxt.get_environment();
  ABG_ASSERT(env);

  if (!is_decl_only && previous_definition)
    // We are in the case where we've read this class definition
    // before, but we might need to update it to add some new stuff to
    // it; we might thus find the new stuff to add in the current
    // (new) incarnation of that definition that we are currently
    // reading.
    decl = previous_definition;
  else
    {
      if (is_decl_only)
	decl.reset(new union_decl(env, name));
      else
	decl.reset(new union_decl(env, name,
				  size_in_bits,
				  loc, vis, mbrs,
				  data_mbrs,
				  mbr_functions,
				  is_anonymous));
    }

  maybe_set_artificial_location(ctxt, node, decl);
  decl->set_is_artificial(is_artificial);

  string def_id;
  bool is_def_of_decl = false;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "def-of-decl-id"))
    def_id = CHAR_STR(s);

  if (!def_id.empty())
    {
      class_decl_sptr d =
	dynamic_pointer_cast<class_decl>(ctxt.get_type_decl(def_id));
      if (d && d->get_is_declaration_only())
	{
	  is_def_of_decl = true;
	  decl->set_earlier_declaration(d);
	  d->set_definition_of_declaration(decl);
	}
    }

  if (!is_decl_only
      && decl
      && !decl->get_is_declaration_only()
      && previous_declaration)
    {
      // decl is the definition of the previous declaration
      // previous_declaration.
      //
      // Let's link them.
      decl->set_earlier_declaration(previous_declaration);
      for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
	   i != types_ptr->end();
	   ++i)
	{
	  union_decl_sptr d = is_union_type(*i);
	  ABG_ASSERT(d);
	  if (d->get_is_declaration_only()
	      && !d->get_definition_of_declaration())
	    {
	      previous_declaration->set_definition_of_declaration(decl);
	      is_def_of_decl = true;
	    }
	}
    }

  if (is_decl_only && previous_definition)
    {
      // decl is a declaration of the previous definition
      // previous_definition.  Let's link them.
      ABG_ASSERT(decl->get_is_declaration_only()
	     && !decl->get_definition_of_declaration());
      decl->set_definition_of_declaration(previous_definition);
    }

  ABG_ASSERT(!is_decl_only || !is_def_of_decl);

  ctxt.push_decl_to_current_scope(decl, add_to_current_scope);

  ctxt.map_xml_node_to_decl(node, decl);
  ctxt.key_type_decl(decl, id);

  maybe_set_naming_typedef(ctxt, node, decl);

  for (xmlNodePtr n = xmlFirstElementChild(node);
       !is_decl_only && n;
       n = xmlNextElementSibling(n))
    {
      if (xmlStrEqual(n->name, BAD_CAST("member-type")))
	{
	  access_specifier access = private_access;
	  read_access(n, access);

	  ctxt.map_xml_node_to_decl(n, decl);

	  for (xmlNodePtr p = xmlFirstElementChild(n);
	       p;
	       p = xmlNextElementSibling(p))
	    {
	      if (type_base_sptr t =
		  build_type(ctxt, p, /*add_to_current_scope=*/true))
		{
		  decl_base_sptr td = get_type_declaration(t);
		  ABG_ASSERT(td);
		  set_member_access_specifier(td, access);
		  ctxt.maybe_canonicalize_type(t, !add_to_current_scope);
		  xml_char_sptr i= XML_NODE_GET_ATTRIBUTE(p, "id");
		  string id = CHAR_STR(i);
		  ABG_ASSERT(!id.empty());
		  ctxt.key_type_decl(t, id);
		  ctxt.map_xml_node_to_decl(p, td);
		}
	    }
	}
      else if (xmlStrEqual(n->name, BAD_CAST("data-member")))
	{
	  ctxt.map_xml_node_to_decl(n, decl);

	  access_specifier access = private_access;
	  read_access(n, access);

	  bool is_laid_out = true;
	  size_t offset_in_bits = 0;
	  bool is_static = false;
	  read_static(n, is_static);

	  for (xmlNodePtr p = xmlFirstElementChild(n);
	       p;
	       p = xmlNextElementSibling(p))
	    {
	      if (var_decl_sptr v =
		  build_var_decl(ctxt, p, /*add_to_cur_scope=*/false))
		{
		  if (decl->find_data_member(v))
		    {
		      // We are in updating mode and the current
		      // version of this class already has this data
		      // member, so we are not going to add it again.
		      // So we need to discard the data member we have
		      // built (and that was pushed to the current
		      // stack of decls built) and move on.
		      decl_base_sptr d = ctxt.pop_decl();
		      ABG_ASSERT(is_var_decl(d));
		      continue;
		    }
		  if (!is_static
		      || !variable_is_suppressed(ctxt, decl.get(), *v))
		    {
		      decl->add_data_member(v, access,
					    is_laid_out,
					    is_static,
					    offset_in_bits);
		      // Now let's record the fact that the data
		      // member uses its type and that the union being
		      // built uses the data member.
		      if (is_anonymous_data_member(v))
			// This data member is anonymous so recording
			// that it uses its type is useless because we
			// can't name it.  Rather, let's record that
			// the class being built uses the type of the
			// (anonymous) data member.
			RECORD_ARTIFACT_AS_USED_BY(ctxt, v->get_type(), decl);
		      else
			{
			  RECORD_ARTIFACT_AS_USED_BY(ctxt, v->get_type(), v);
			  RECORD_ARTIFACT_AS_USED_BY(ctxt, v, decl);
			}
		    }
		}
	    }
	}
      else if (xmlStrEqual(n->name, BAD_CAST("member-function")))
	{
	  ctxt.map_xml_node_to_decl(n, decl);

	  access_specifier access = private_access;
	  read_access(n, access);

	  bool is_static = false;
	  read_static(n, is_static);

	  bool is_ctor = false, is_dtor = false, is_const = false;
	  read_cdtor_const(n, is_ctor, is_dtor, is_const);

	  for (xmlNodePtr p = xmlFirstElementChild(n);
	       p;
	       p = xmlNextElementSibling(p))
	    {
	      if (function_decl_sptr f =
		  build_function_decl_if_not_suppressed(ctxt, p, decl,
							/*add_to_cur_sc=*/true))
		{
		  method_decl_sptr m = is_method_decl(f);
		  ABG_ASSERT(m);
		  set_member_access_specifier(m, access);
		  set_member_is_static(m, is_static);
		  set_member_function_is_ctor(m, is_ctor);
		  set_member_function_is_dtor(m, is_dtor);
		  set_member_function_is_const(m, is_const);
		  break;
		}
	    }
	}
      else if (xmlStrEqual(n->name, BAD_CAST("member-template")))
	{
	  ctxt.map_xml_node_to_decl(n, decl);

	  access_specifier access = private_access;
	  read_access(n, access);

	  bool is_static = false;
	  read_static(n, is_static);

	  bool is_ctor = false, is_dtor = false, is_const = false;
	  read_cdtor_const(n, is_ctor, is_dtor, is_const);

	  for (xmlNodePtr p = xmlFirstElementChild(n);
	       p;
	       p = xmlNextElementSibling(p))
	    {
	      if (function_tdecl_sptr f =
		  build_function_tdecl(ctxt, p,
				       /*add_to_current_scope=*/true))
		{
		  member_function_template_sptr m
		    (new member_function_template(f, access, is_static,
						  is_ctor, is_const));
		  ABG_ASSERT(f->get_scope());
		  decl->add_member_function_template(m);
		}
	      else if (class_tdecl_sptr c =
		       build_class_tdecl(ctxt, p,
					 /*add_to_current_scope=*/true))
		{
		  member_class_template_sptr m(new member_class_template(c,
									 access,
									 is_static));
		  ABG_ASSERT(c->get_scope());
		  decl->add_member_class_template(m);
		}
	    }
	}
    }

  ctxt.pop_scope_or_abort(decl);

  return decl;
}

/// Build an intance of function_tdecl, from an
/// 'function-template-decl' xml element node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to parse from.
///
/// @param add_to_current_scope if set to yes, the resulting of
/// this function is added to its current scope.
///
/// @return the newly built function_tdecl upon successful
/// completion, a null pointer otherwise.
static shared_ptr<function_tdecl>
build_function_tdecl(read_context& ctxt,
		     const xmlNodePtr node,
		     bool add_to_current_scope)
{
  shared_ptr<function_tdecl> nil, result;

  if (!xmlStrEqual(node->name, BAD_CAST("function-template-decl")))
    return nil;

  string id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    id = CHAR_STR(s);
  if (id.empty() || ctxt.get_fn_tmpl_decl(id))
    return nil;

  location loc;
  read_location(ctxt, node, loc);

  decl_base::visibility vis = decl_base::VISIBILITY_NONE;
  read_visibility(node, vis);

  decl_base::binding bind = decl_base::BINDING_NONE;
  read_binding(node, bind);

  const environment* env = ctxt.get_environment();
  ABG_ASSERT(env);

  function_tdecl_sptr fn_tmpl_decl(new function_tdecl(env, loc, vis, bind));
  maybe_set_artificial_location(ctxt, node, fn_tmpl_decl);

  ctxt.push_decl_to_current_scope(fn_tmpl_decl, add_to_current_scope);

  unsigned parm_index = 0;
  for (xmlNodePtr n = xmlFirstElementChild(node);
       n;
       n = xmlNextElementSibling(n))
    {
      if (template_parameter_sptr parm =
	  build_template_parameter(ctxt, n, parm_index, fn_tmpl_decl))
	{
	  fn_tmpl_decl->add_template_parameter(parm);
	  ++parm_index;
	}
      else if (function_decl_sptr f =
	       build_function_decl_if_not_suppressed(ctxt, n, class_decl_sptr(),
					 /*add_to_current_scope=*/true))
	fn_tmpl_decl->set_pattern(f);
    }

  ctxt.key_fn_tmpl_decl(fn_tmpl_decl, id);

  return fn_tmpl_decl;
}

/// Build an intance of class_tdecl, from a
/// 'class-template-decl' xml element node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to parse from.
///
/// @param add_to_current_scope if set to yes, the resulting of this
/// function is added to its current scope.
///
/// @return the newly built function_tdecl upon successful
/// completion, a null pointer otherwise.
static shared_ptr<class_tdecl>
build_class_tdecl(read_context&	ctxt,
		  const xmlNodePtr	node,
		  bool			add_to_current_scope)
{
  shared_ptr<class_tdecl> nil, result;

  if (!xmlStrEqual(node->name, BAD_CAST("class-template-decl")))
    return nil;

  string id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    id = CHAR_STR(s);
  if (id.empty() || ctxt.get_class_tmpl_decl(id))
    return nil;

  location loc;
  read_location(ctxt, node, loc);

  decl_base::visibility vis = decl_base::VISIBILITY_NONE;
  read_visibility(node, vis);

  const environment* env = ctxt.get_environment();
  ABG_ASSERT(env);

  class_tdecl_sptr class_tmpl (new class_tdecl(env, loc, vis));
  maybe_set_artificial_location(ctxt, node, class_tmpl);

  ctxt.push_decl_to_current_scope(class_tmpl, add_to_current_scope);

  unsigned parm_index = 0;
  for (xmlNodePtr n = xmlFirstElementChild(node);
       n;
       n = xmlNextElementSibling(n))
    {
      if (template_parameter_sptr parm=
	  build_template_parameter(ctxt, n, parm_index, class_tmpl))
	{
	  class_tmpl->add_template_parameter(parm);
	  ++parm_index;
	}
      else if (class_decl_sptr c =
	       build_class_decl_if_not_suppressed(ctxt, n,
						  add_to_current_scope))
	{
	  if (c->get_scope())
	    ctxt.maybe_canonicalize_type(c, /*force_delay=*/false);
	  class_tmpl->set_pattern(c);
	}
    }

  ctxt.key_class_tmpl_decl(class_tmpl, id);

  return class_tmpl;
}

/// Build a type_tparameter from a 'template-type-parameter'
/// xml element node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to parse from.
///
/// @param index the index (occurrence index, starting from 0) of the
/// template parameter.
///
/// @param tdecl the enclosing template declaration that holds the
/// template type parameter.
///
/// @return a pointer to a newly created instance of
/// type_tparameter, a null pointer otherwise.
static type_tparameter_sptr
build_type_tparameter(read_context&		ctxt,
		      const xmlNodePtr		node,
		      unsigned			index,
		      template_decl_sptr	tdecl)
{
  type_tparameter_sptr nil, result;

  if (!xmlStrEqual(node->name, BAD_CAST("template-type-parameter")))
    return nil;

  string id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    id = CHAR_STR(s);
  if (!id.empty())
    ABG_ASSERT(!ctxt.get_type_decl(id));

  string type_id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
    type_id = CHAR_STR(s);
  if (!type_id.empty()
      && !(result = dynamic_pointer_cast<type_tparameter>
	   (ctxt.build_or_get_type_decl(type_id, true))))
    abort();

  string name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    name = xml::unescape_xml_string(CHAR_STR(s));

  location loc;
  read_location(ctxt, node,loc);

  result.reset(new type_tparameter(index, tdecl, name, loc));
  maybe_set_artificial_location(ctxt, node, result);

  if (id.empty())
    ctxt.push_decl_to_current_scope(dynamic_pointer_cast<decl_base>(result),
				    /*add_to_current_scope=*/true);
  else
    ctxt.push_and_key_type_decl(result, id, /*add_to_current_scope=*/true);

  ABG_ASSERT(result->get_environment());

  ctxt.maybe_canonicalize_type(result, /*force_delay=*/false);

  return result;
}

/// Build a tmpl_parm_type_composition from a
/// "template-parameter-type-composition" xml element node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to parse from.
///
/// @param index the index of the previous normal template parameter.
///
/// @param tdecl the enclosing template declaration that holds this
/// template parameter type composition.
///
/// @return a pointer to a new instance of tmpl_parm_type_composition
/// upon successful completion, a null pointer otherwise.
static type_composition_sptr
build_type_composition(read_context&		ctxt,
		       const xmlNodePtr	node,
		       unsigned		index,
		       template_decl_sptr	tdecl)
{
  type_composition_sptr nil, result;

  if (!xmlStrEqual(node->name, BAD_CAST("template-parameter-type-composition")))
    return nil;

  type_base_sptr composed_type;
  result.reset(new type_composition(index, tdecl, composed_type));
  ctxt.push_decl_to_current_scope(dynamic_pointer_cast<decl_base>(result),
				  /*add_to_current_scope=*/true);

  for (xmlNodePtr n = xmlFirstElementChild(node);
       n;
       n = xmlNextElementSibling(n))
    {
      if ((composed_type =
	   build_pointer_type_def(ctxt, n,
				  /*add_to_current_scope=*/true))
	  ||(composed_type =
	     build_reference_type_def(ctxt, n,
				      /*add_to_current_scope=*/true))
	  ||(composed_type =
	     build_array_type_def(ctxt, n,
				  /*add_to_current_scope=*/true))
	  || (composed_type =
	      build_qualified_type_decl(ctxt, n,
					/*add_to_current_scope=*/true)))
	{
	  ctxt.maybe_canonicalize_type(composed_type,
				       /*force_delay=*/true);
	  result->set_composed_type(composed_type);
	  break;
	}
    }

  return result;
}

/// Build an instance of non_type_tparameter from a
/// 'template-non-type-parameter' xml element node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to parse from.
///
/// @param index the index of the parameter.
///
/// @param tdecl the enclosing template declaration that holds this
/// non type template parameter.
///
/// @return a pointer to a newly created instance of
/// non_type_tparameter upon successful completion, a null
/// pointer code otherwise.
static non_type_tparameter_sptr
build_non_type_tparameter(read_context&	ctxt,
			  const xmlNodePtr	node,
			  unsigned		index,
			  template_decl_sptr	tdecl)
{
  non_type_tparameter_sptr r;

  if (!xmlStrEqual(node->name, BAD_CAST("template-non-type-parameter")))
    return r;

  string type_id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
    type_id = CHAR_STR(s);
  type_base_sptr type;
  if (type_id.empty()
      || !(type = ctxt.build_or_get_type_decl(type_id, true)))
    abort();

  string name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    name = xml::unescape_xml_string(CHAR_STR(s));

  location loc;
  read_location(ctxt, node,loc);

  r.reset(new non_type_tparameter(index, tdecl, name, type, loc));
  maybe_set_artificial_location(ctxt, node, r);
  ctxt.push_decl_to_current_scope(dynamic_pointer_cast<decl_base>(r),
				  /*add_to_current_scope=*/true);

  return r;
}

/// Build an intance of template_tparameter from a
/// 'template-template-parameter' xml element node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to parse from.
///
/// @param index the index of the template parameter.
///
/// @param tdecl the enclosing template declaration that holds this
/// template template parameter.
///
/// @return a pointer to a new instance of template_tparameter
/// upon successful completion, a null pointer otherwise.
static template_tparameter_sptr
build_template_tparameter(read_context&	ctxt,
			  const xmlNodePtr	node,
			  unsigned		index,
			  template_decl_sptr	tdecl)
{
  template_tparameter_sptr nil;

  if (!xmlStrEqual(node->name, BAD_CAST("template-template-parameter")))
    return nil;

  string id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
    id = CHAR_STR(s);
  // Bail out if a type with the same ID already exists.
  ABG_ASSERT(!id.empty());

  string type_id;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
    type_id = CHAR_STR(s);
  // Bail out if no type with this ID exists.
  if (!type_id.empty()
      && !(dynamic_pointer_cast<template_tparameter>
	   (ctxt.build_or_get_type_decl(type_id, true))))
    abort();

  string name;
  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
    name = xml::unescape_xml_string(CHAR_STR(s));

  location loc;
  read_location(ctxt, node, loc);

  template_tparameter_sptr result(new template_tparameter(index, tdecl,
							  name, loc));
  maybe_set_artificial_location(ctxt, node, result);
  ctxt.push_decl_to_current_scope(result, /*add_to_current_scope=*/true);

  // Go parse template parameters that are children nodes
  int parm_index = 0;
  for (xmlNodePtr n = xmlFirstElementChild(node);
       n;
       n = xmlNextElementSibling(n))
    if (shared_ptr<template_parameter> p =
	build_template_parameter(ctxt, n, parm_index, result))
      {
	result->add_template_parameter(p);
	++parm_index;
      }

  if (result)
    {
      ctxt.key_type_decl(result, id);
      ctxt.maybe_canonicalize_type(result, /*force_delay=*/false);
    }

  return result;
}

/// Build a template parameter type from several possible xml elment
/// nodes representing a serialized form a template parameter.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml element node to parse from.
///
/// @param index the index of the template parameter we are parsing.
///
/// @param tdecl the enclosing template declaration that holds this
/// template parameter.
///
/// @return a pointer to a newly created instance of
/// template_parameter upon successful completion, a null pointer
/// otherwise.
static template_parameter_sptr
build_template_parameter(read_context&		ctxt,
			 const xmlNodePtr	node,
			 unsigned		index,
			 template_decl_sptr	tdecl)
{
  shared_ptr<template_parameter> r;
  ((r = build_type_tparameter(ctxt, node, index, tdecl))
   || (r = build_non_type_tparameter(ctxt, node, index, tdecl))
   || (r = build_template_tparameter(ctxt, node, index, tdecl))
   || (r = build_type_composition(ctxt, node, index, tdecl)));

  return r;
}

/// Build a type from an xml node.
///
/// @param ctxt the context of the parsing.
///
/// @param node the xml node to build the type_base from.
///
/// @return a pointer to the newly built type_base upon successful
/// completion, a null pointer otherwise.
static type_base_sptr
build_type(read_context&	ctxt,
	   const xmlNodePtr	node,
	   bool		add_to_current_scope)
{
  type_base_sptr t;

  ((t = build_type_decl(ctxt, node, add_to_current_scope))
   || (t = build_qualified_type_decl(ctxt, node, add_to_current_scope))
   || (t = build_pointer_type_def(ctxt, node, add_to_current_scope))
   || (t = build_reference_type_def(ctxt, node , add_to_current_scope))
   || (t = build_function_type(ctxt, node, add_to_current_scope))
   || (t = build_array_type_def(ctxt, node, add_to_current_scope))
   || (t = build_enum_type_decl_if_not_suppressed(ctxt, node,
						  add_to_current_scope))
   || (t = build_typedef_decl(ctxt, node, add_to_current_scope))
   || (t = build_class_decl_if_not_suppressed(ctxt, node,
					      add_to_current_scope))
   || (t = build_union_decl_if_not_suppressed(ctxt, node,
					      add_to_current_scope)));

  if (ctxt.tracking_non_reachable_types() && t)
    {
      corpus_sptr abi = ctxt.get_corpus();
      ABG_ASSERT(abi);
      bool is_non_reachable_type = false;
      read_is_non_reachable_type(node, is_non_reachable_type);
      if (!is_non_reachable_type)
	abi->record_type_as_reachable_from_public_interfaces(*t);
    }

  MAYBE_MAP_TYPE_WITH_TYPE_ID(t, node);

  if (t)
    ctxt.maybe_canonicalize_type(t,/*force_delay=*/false );
  return t;
}

/// Parses 'type-decl' xml element.
///
/// @param ctxt the parsing context.
///
/// @return true upon successful parsing, false otherwise.
static decl_base_sptr
handle_type_decl(read_context&	ctxt,
		 xmlNodePtr	node,
		 bool		add_to_current_scope)
{
  type_decl_sptr decl = build_type_decl(ctxt, node, add_to_current_scope);
  MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
  if (decl && decl->get_scope())
    ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
  return decl;
}

/// Parses 'namespace-decl' xml element.
///
/// @param ctxt the parsing context.
///
/// @return true upon successful parsing, false otherwise.
static decl_base_sptr
handle_namespace_decl(read_context&	ctxt,
		      xmlNodePtr	node,
		      bool		add_to_current_scope)
{
  namespace_decl_sptr d = build_namespace_decl(ctxt, node,
					       add_to_current_scope);
  return d;
}

/// Parse a qualified-type-def xml element.
///
/// @param ctxt the parsing context.
///
/// @return true upon successful parsing, false otherwise.
static decl_base_sptr
handle_qualified_type_decl(read_context&	ctxt,
			   xmlNodePtr		node,
			   bool		add_to_current_scope)
{
  qualified_type_def_sptr decl =
    build_qualified_type_decl(ctxt, node,
			      add_to_current_scope);
  MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
  if (decl && decl->get_scope())
    ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
  return decl;
}

/// Parse a pointer-type-decl element.
///
/// @param ctxt the context of the parsing.
///
/// @return true upon successful completion, false otherwise.
static decl_base_sptr
handle_pointer_type_def(read_context&	ctxt,
			xmlNodePtr	node,
			bool		add_to_current_scope)
{
  pointer_type_def_sptr decl = build_pointer_type_def(ctxt, node,
						      add_to_current_scope);
  MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
  if (decl && decl->get_scope())
    ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
  return decl;
}

/// Parse a reference-type-def element.
///
/// @param ctxt the context of the parsing.
///
/// reference_type_def is added to.
static decl_base_sptr
handle_reference_type_def(read_context& ctxt,
			  xmlNodePtr	node,
			  bool		add_to_current_scope)
{
  reference_type_def_sptr decl = build_reference_type_def(ctxt, node,
							  add_to_current_scope);
  MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
  if (decl && decl->get_scope())
    ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
  return decl;
}

/// Parse a function-type element.
///
/// @param ctxt the context of the parsing.
///
/// function_type is added to.
static type_base_sptr
handle_function_type(read_context&	ctxt,
		     xmlNodePtr	node,
		     bool		add_to_current_scope)
{
  function_type_sptr type = build_function_type(ctxt, node,
						  add_to_current_scope);
  MAYBE_MAP_TYPE_WITH_TYPE_ID(type, node);
  ctxt.maybe_canonicalize_type(type, /*force_delay=*/true);
  return type;
}

/// Parse a array-type-def element.
///
/// @param ctxt the context of the parsing.
///
/// array_type_def is added to.
static decl_base_sptr
handle_array_type_def(read_context&	ctxt,
		      xmlNodePtr	node,
		      bool		add_to_current_scope)
{
  array_type_def_sptr decl = build_array_type_def(ctxt, node,
						  add_to_current_scope);
  MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
  ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
  return decl;
}

/// Parse an enum-decl element.
///
/// @param ctxt the context of the parsing.
static decl_base_sptr
handle_enum_type_decl(read_context&	ctxt,
		      xmlNodePtr	node,
		      bool		add_to_current_scope)
{
  enum_type_decl_sptr decl =
    build_enum_type_decl_if_not_suppressed(ctxt, node,
					   add_to_current_scope);
  MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
  if (decl && decl->get_scope())
    ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
  return decl;
}

/// Parse a typedef-decl element.
///
/// @param ctxt the context of the parsing.
static decl_base_sptr
handle_typedef_decl(read_context&	ctxt,
		    xmlNodePtr		node,
		    bool		add_to_current_scope)
{
  typedef_decl_sptr decl = build_typedef_decl(ctxt, node,
					      add_to_current_scope);
  MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
  if (decl && decl->get_scope())
    ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
  return decl;
}

/// Parse a var-decl element.
///
/// @param ctxt the context of the parsing.
///
/// @param node the node to read & parse from.
///
/// @param add_to_current_scope if set to yes, the resulting of this
/// function is added to its current scope.
static decl_base_sptr
handle_var_decl(read_context&	ctxt,
		xmlNodePtr	node,
		bool		add_to_current_scope)
{
  decl_base_sptr decl = build_var_decl_if_not_suppressed(ctxt, node,
							 add_to_current_scope);
  ctxt.maybe_add_var_to_exported_decls(is_var_decl(decl));
  return decl;
}

/// Parse a function-decl element.
///
/// @param ctxt the context of the parsing
///
/// @return true upon successful completion of the parsing, false
/// otherwise.
static decl_base_sptr
handle_function_decl(read_context&	ctxt,
		     xmlNodePtr	node,
		     bool		add_to_current_scope)
{
  return build_function_decl_if_not_suppressed(ctxt, node, class_decl_sptr(),
					       add_to_current_scope);
}

/// Parse a 'class-decl' xml element.
///
/// @param ctxt the context of the parsing.
///
/// @return the resulting @ref class_decl built from the XML element
/// upon successful completion of the parsing, nil otherwise.
static decl_base_sptr
handle_class_decl(read_context& ctxt,
		  xmlNodePtr	node,
		  bool		add_to_current_scope)
{
  class_decl_sptr decl =
    build_class_decl_if_not_suppressed(ctxt, node, add_to_current_scope);
  MAYBE_MAP_TYPE_WITH_TYPE_ID(is_type(decl), node);
  if (decl && decl->get_scope())
    ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
  return decl;
}

/// Parse a 'union-decl' xml element.
///
/// @param ctxt the context of the parsing.
///
/// @return the resulting @ref union_decl built from the XML element
/// upon successful completion of the parsing, nil otherwise.
static decl_base_sptr
handle_union_decl(read_context& ctxt,
		  xmlNodePtr	node,
		  bool		add_to_current_scope)
{
  union_decl_sptr decl =
    build_union_decl_if_not_suppressed(ctxt, node, add_to_current_scope);
  MAYBE_MAP_TYPE_WITH_TYPE_ID(is_type(decl), node);
  if (decl && decl->get_scope())
    ctxt.maybe_canonicalize_type(decl, /*force_delay=*/false);
  return decl;
}

/// Parse a 'function-template-decl' xml element.
///
/// @param ctxt the parsing context.
///
/// @return true upon successful completion of the parsing, false
/// otherwise.
static decl_base_sptr
handle_function_tdecl(read_context&	ctxt,
		      xmlNodePtr	node,
		      bool		add_to_current_scope)
{
  function_tdecl_sptr d = build_function_tdecl(ctxt, node,
					       add_to_current_scope);
  return d;
}

/// Parse a 'class-template-decl' xml element.
///
/// @param ctxt the context of the parsing.
///
/// @return true upon successful completion, false otherwise.
static decl_base_sptr
handle_class_tdecl(read_context&	ctxt,
		   xmlNodePtr		node,
		   bool		add_to_current_scope)
{
  class_tdecl_sptr decl = build_class_tdecl(ctxt, node,
					    add_to_current_scope);
  return decl;
}

/// De-serialize a translation unit from an ABI Instrumentation xml
/// file coming from an input stream.
///
/// @param in a pointer to the input stream.
///
/// @param env the environment to use.
///
/// @return the translation unit resulting from the parsing upon
/// successful completion, or nil.
translation_unit_sptr
read_translation_unit_from_istream(istream* in, environment* env)
{
  read_context read_ctxt(xml::new_reader_from_istream(in), env);
  return read_translation_unit_from_input(read_ctxt);
}
template<typename T>
struct array_deleter
{
  void
  operator()(T* a)
  {
    delete [] a;
  }
};//end array_deleter


/// Create an xml_reader::read_context to read a native XML ABI file.
///
/// @param path the path to the native XML file to read.
///
/// @param env the environment to use.
///
/// @return the created context.
read_context_sptr
create_native_xml_read_context(const string& path, environment *env)
{
  read_context_sptr result(new read_context(xml::new_reader_from_file(path),
					    env));
  corpus_sptr corp(new corpus(env));
  result->set_corpus(corp);
#ifdef WITH_DEBUG_SELF_COMPARISON
  if (env->self_comparison_debug_is_on())
    env->set_self_comparison_debug_input(result->get_corpus());
#endif
  result->set_path(path);
  return result;
}

/// Create an xml_reader::read_context to read a native XML ABI from
/// an input stream..
///
/// @param in the input stream that contains the native XML file to read.
///
/// @param env the environment to use.
///
/// @return the created context.
read_context_sptr
create_native_xml_read_context(std::istream* in, environment* env)
{
  read_context_sptr result(new read_context(xml::new_reader_from_istream(in),
					    env));
  corpus_sptr corp(new corpus(env, ""));
  result->set_corpus(corp);
#ifdef WITH_DEBUG_SELF_COMPARISON
  if (env->self_comparison_debug_is_on())
    env->set_self_comparison_debug_input(result->get_corpus());
#endif
  return result;
}

/// Getter for the path to the binary this @ref read_context is for.
///
/// @return the path to the binary the @ref read_context is for.
const string&
read_context_get_path(const read_context& ctxt)
{return ctxt.get_path();}

/// De-serialize an ABI corpus from an input XML document which root
/// node is 'abi-corpus'.
///
/// @param in the input stream to read the XML document from.
///
/// @param env the environment to use.  Note that the life time of
/// this environment must be greater than the lifetime of the
/// resulting corpus as the corpus uses resources that are allocated
/// in the environment.
///
/// @return the resulting corpus de-serialized from the parsing.  This
/// is non-null iff the parsing resulted in a valid corpus.
corpus_sptr
read_corpus_from_native_xml(std::istream* in,
			    environment* env)
{
  read_context_sptr read_ctxt = create_native_xml_read_context(in, env);
  return read_corpus_from_input(*read_ctxt);
}

/// De-serialize an ABI corpus from an XML document file which root
/// node is 'abi-corpus'.
///
/// @param path the path to the input file to read the XML document
/// from.
///
/// @param env the environment to use.  Note that the life time of
/// this environment must be greater than the lifetime of the
/// resulting corpus as the corpus uses resources that are allocated
/// in the environment.
///
/// @return the resulting corpus de-serialized from the parsing.  This
/// is non-null if the parsing successfully resulted in a corpus.
corpus_sptr
read_corpus_from_native_xml_file(const string& path,
				 environment* env)
{
  read_context_sptr read_ctxt = create_native_xml_read_context(path, env);
  corpus_sptr corp = read_corpus_from_input(*read_ctxt);
  return corp;
}

}//end namespace xml_reader

#ifdef WITH_DEBUG_SELF_COMPARISON
/// Load the map that is stored at
/// environment::get_type_id_canonical_type_map().
///
/// That map associates type-ids to the pointer value of the canonical
/// types they correspond to.  The map is loaded from a file that was
/// stored on disk by some debugging primitive that is activated when
/// the command "abidw --debug-abidiff <binary>' is used."
///
/// The function that stored the map in that file is
/// write_canonical_type_ids.
///
/// @param ctxt the read context to use.
///
/// @param file_path the path to the file containing the type-ids <->
/// canonical type mapping.
///
/// @return true iff the loading was successful.
bool
load_canonical_type_ids(xml_reader::read_context& ctxt, const string &file_path)
{
  xmlDocPtr doc = xmlReadFile(file_path.c_str(), NULL, XML_PARSE_NOERROR);
  if (!doc)
    return false;

  xmlNodePtr node = xmlDocGetRootElement(doc);
  if (!node)
    return false;

  // We expect a file which content looks like:
  //
  // <abixml-types-check>
  //     <type>
  //       <id>type-id-573</id>
  //       <c>0x262ee28</c>
  //     </type>
  //     <type>
  //       <id>type-id-569</id>
  //       <c>0x2628298</c>
  //     </type>
  //     <type>
  //       <id>type-id-575</id>
  //       <c>0x25f9ba8</c>
  //     </type>
  // <abixml-types-check>
  //
  // So let's parse it!

  if (xmlStrcmp(node->name, (xmlChar*) "abixml-types-check"))
    return false;

  for (node = xmlFirstElementChild(node);
       node;
       node = xmlNextElementSibling(node))
    {
      if (xmlStrcmp(node->name, (xmlChar*) "type"))
	continue;

      string id, canonical_address;
      xmlNodePtr data = xmlFirstElementChild(node);
      if (data && !xmlStrcmp(data->name, (xmlChar*) "id")
	  && data->children && xmlNodeIsText(data->children))
	id = (char*) XML_GET_CONTENT(data->children);

      data = xmlNextElementSibling(data);
      if (data && !xmlStrcmp(data->name, (xmlChar*) "c")
	  && data->children && xmlNodeIsText(data->children))
	{
	  canonical_address = (char*) XML_GET_CONTENT(data->children);
	  std::stringstream s;
	  s << canonical_address;
	  uintptr_t v = 0;
	  s >>  std::hex >> v;
	  if (!id.empty()
	      // 0xdeadbabe is the special value the hash of types
	      // that are not canonicalized.  Look into function
	      // hash_as_canonical_type_or_constant for the details.
	      && v != 0xdeadbabe)
	    ctxt.get_environment()->get_type_id_canonical_type_map()[id] = v;
	}
    }
  return true;
}
#endif

}//end namespace abigail
