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

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

#include "config.h"
#include <assert.h>
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <memory>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <vector>

#include "abg-tools-utils.h"

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

#include "abg-config.h"
#include "abg-corpus.h"
#include "abg-diff-utils.h"
#include "abg-hash.h"
#include "abg-sptr-utils.h"

#if WITH_ZIP_ARCHIVE
#include "abg-libzip-utils.h"
#endif

#include "abg-writer.h"
#include "abg-libxml-utils.h"

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

namespace abigail
{
using std::cerr;
using std::shared_ptr;
using std::dynamic_pointer_cast;
using std::static_pointer_cast;
using std::ofstream;
using std::ostream;
using std::ostringstream;
using std::list;
using std::vector;
using std::stack;
using std::unordered_map;
using abigail::sptr_utils::noop_deleter;

#if WITH_ZIP_ARCHIVE
using zip_utils::zip_sptr;
using zip_utils::zip_file_sptr;
using zip_utils::open_archive;
using zip_utils::open_file_in_archive;
#endif // WITH_ZIP_ARCHIVE

/// The namespace for the native XML file format writer.
///
/// It contains utilities to serialize ABI artifacts from the @ref ir
/// namespace into the native XML format.
namespace xml_writer
{

class id_manager
{
  const environment* m_env;
  mutable unsigned long long m_cur_id;

  unsigned long long
  get_new_id() const
  { return ++m_cur_id; }

public:
  id_manager(const environment* env)
    : m_env(env),
      m_cur_id(0) {}

  const environment*
  get_environment() const
  {return m_env;}

  /// Return a unique string representing a numerical id.
  interned_string
  get_id() const
  {
    ostringstream o;
    o << get_new_id();
    const environment* env = get_environment();
    ABG_ASSERT(env);
    return env->intern(o.str());
  }

  /// Return a unique string representing a numerical ID, prefixed by
  /// prefix.
  ///
  /// @param prefix the prefix of the returned unique id.
  interned_string
  get_id_with_prefix(const string& prefix) const
  {
    ostringstream o;
    o << prefix << get_new_id();
    const environment* env = get_environment();
    ABG_ASSERT(env);
    return env->intern(o.str());
  }
};

/// A hashing functor that should be as fast as possible.
struct type_hasher
{
  size_t
  operator()(const type_base* t) const
  {return hash_type(t);}
}; // end struct type_hasher

/// A convenience typedef for a map that associates a pointer to type
/// to a string.  The pointer to type is hashed as fast as possible.
typedef unordered_map<type_base*,
		      interned_string,
		      type_hasher,
		      abigail::diff_utils::deep_ptr_eq_functor> type_ptr_map;

// A convenience typedef for a set of type_base*.
typedef unordered_set<const type_base*, type_hasher,
		      abigail::diff_utils::deep_ptr_eq_functor>
type_ptr_set_type;

/// A convenience typedef for a set of function type*.
typedef unordered_set<function_type*, type_hasher,
		      abigail::diff_utils::deep_ptr_eq_functor>
fn_type_ptr_set_type;

typedef unordered_map<shared_ptr<function_tdecl>,
		      string,
		      function_tdecl::shared_ptr_hash> fn_tmpl_shared_ptr_map;

typedef unordered_map<shared_ptr<class_tdecl>,
		      string,
		      class_tdecl::shared_ptr_hash> class_tmpl_shared_ptr_map;

class write_context
{
  const environment*			m_env;
  id_manager				m_id_manager;
  config				m_config;
  ostream*				m_ostream;
  bool					m_annotate;
  bool					m_show_locs;
  bool					m_write_architecture;
  bool					m_write_corpus_path;
  bool					m_write_comp_dir;
  bool					m_write_elf_needed;
  bool					m_write_parameter_names;
  bool					m_short_locs;
  bool					m_write_default_sizes;
  type_id_style_kind			m_type_id_style;
  mutable type_ptr_map			m_type_id_map;
  mutable unordered_set<uint32_t>	m_used_type_id_hashes;
  mutable type_ptr_set_type		m_emitted_type_set;
  type_ptr_set_type			m_emitted_decl_only_set;
  // A map of types that are referenced by emitted pointers,
  // references or typedefs
  type_ptr_set_type			m_referenced_types_set;
  fn_type_ptr_set_type			m_referenced_fn_types_set;
  type_ptr_set_type			m_referenced_non_canonical_types_set;
  fn_tmpl_shared_ptr_map		m_fn_tmpl_id_map;
  class_tmpl_shared_ptr_map		m_class_tmpl_id_map;
  string_elf_symbol_sptr_map_type	m_fun_symbol_map;
  string_elf_symbol_sptr_map_type	m_var_symbol_map;
  mutable unordered_map<interned_string,
			bool,
			hash_interned_string> m_emitted_decls_map;

  write_context();

public:

  /// Constructor.
  ///
  /// @param env the enviroment we are operating from.
  ///
  /// @param os the output stream to write to.
  write_context(const environment* env, ostream& os)
    : m_env(env),
      m_id_manager(env),
      m_ostream(&os),
      m_annotate(false),
      m_show_locs(true),
      m_write_architecture(true),
      m_write_corpus_path(true),
      m_write_comp_dir(true),
      m_write_elf_needed(true),
      m_write_parameter_names(true),
      m_short_locs(false),
      m_write_default_sizes(true),
      m_type_id_style(SEQUENCE_TYPE_ID_STYLE)
  {}

  /// Getter of the environment we are operating from.
  ///
  /// @return the environment we are operating from.
  const environment*
  get_environment() const
  {return m_env;}

  const config&
  get_config() const
  {return m_config;}

  /// Getter for the current ostream
  ///
  /// @return a reference to the current ostream
  ostream&
  get_ostream()
  {return *m_ostream;}

  /// Setter for the current ostream
  ///
  /// @param os the new ostream
  void
  set_ostream(ostream& os)
  {m_ostream = &os;}

  /// Getter of the annotation option.
  ///
  /// @return true iff ABIXML annotations are turned on
  bool
  get_annotate()
  {return m_annotate;}

  /// Setter of the annotation option.
  ///
  /// @param f the new value of the flag.
  void
  set_annotate(bool f)
  {m_annotate = f;}

  /// Getter of the write-architecture option.
  ///
  /// @return true iff architecture information shall be emitted
  bool
  get_write_architecture()
  {return m_write_architecture;}

  /// Setter of the write-architecture option
  ///
  /// @param f the new value of the flag.
  void
  set_write_architecture(bool f)
  {m_write_architecture = f;}

  /// Getter of the elf-needed option.
  ///
  /// @return true iff elf needed information shall be emitted
  bool
  get_write_elf_needed()
  {return m_write_elf_needed;}

  /// Setter of the elf-needed option.
  ///
  /// @param f the new value of the flag.
  void
  set_write_elf_needed(bool f)
  {m_write_elf_needed = f;}

  /// Getter of the default-sizes option.
  ///
  /// @return true iff default size-in-bits needs to be emitted
  bool
  get_write_default_sizes()
  {return m_write_default_sizes;}

  /// Setter of the default-sizes option.
  ///
  /// @param f the new value of the flag.
  void
  set_write_default_sizes(bool f)
  {m_write_default_sizes = f;}

  /// Getter of the write-corpus-path option.
  ///
  /// @return true iff corpus-path information shall be emitted
  bool
  get_write_corpus_path()
  {return m_write_corpus_path;}

  /// Setter of the write-corpus-path option
  ///
  /// @param f the new value of the flag.
  void
  set_write_corpus_path(bool f)
  {m_write_corpus_path = f;}

  /// Getter of the comp-dir-path option.
  ///
  /// @return true iff compilation dir information shall be emitted
  bool
  get_write_comp_dir()
  {return m_write_comp_dir;}

  /// Setter of the comp-dir-path option
  ///
  /// @param f the new value of the flag.
  void
  set_write_comp_dir(bool f)
  {m_write_comp_dir = f;}

  /// Getter of the short-locs option.
  ///
  /// @return true iff short locations shall be emitted
  bool
  get_short_locs()
  {return m_short_locs;}

  /// Setter of the short-locs option
  ///
  /// @param f the new value of the flag.
  void
  set_short_locs(bool f)
  {m_short_locs = f;}

  /// Getter of the parameter-names option.
  ///
  /// @return true iff parameter names shall be emitted
  bool
  get_write_parameter_names() const
  {return m_write_parameter_names;}

  /// Setter of the parameter-names option
  ///
  /// @param f the new value of the flag.
  void
  set_write_parameter_names(bool f)
  {m_write_parameter_names = f;}

  /// Getter of the "show-locs" option.
  ///
  /// When this option is true then the XML writer emits location
  /// information for emitted ABI artifacts.
  ///
  /// @return the value of the "show-locs" option.
  bool
  get_show_locs() const
  {return m_show_locs;}

  /// Setter of the "show-locs" option.
  ///
  /// When this option is true then the XML writer emits location
  /// information for emitted ABI artifacts.
  ///
  /// @param f the new value of the "show-locs" option.
  void
  set_show_locs(bool f)
  {m_show_locs = f;}

  /// Getter of the "type-id-style" option.
  ///
  /// This option controls the kind of type ids used in XML output.
  ///
  /// @return the value of the "type-id-style" option.
  type_id_style_kind
  get_type_id_style() const
  {return m_type_id_style;}

  /// Setter of the "type-id-style" option.
  ///
  /// This option controls the kind of type ids used in XML output.
  ///
  /// @param style the new value of the "type-id-style" option.
  void
  set_type_id_style(type_id_style_kind style)
  {m_type_id_style = style;}

  /// Getter of the @ref id_manager.
  ///
  /// @return the @ref id_manager used by the current instance of @ref
  /// write_context.
  const id_manager&
  get_id_manager() const
  {return m_id_manager;}

  id_manager&
  get_id_manager()
  {return m_id_manager;}

  /// @return true iff type has already been assigned an ID.
  bool
  type_has_existing_id(type_base_sptr type) const
  {return type_has_existing_id(type.get());}

  /// @return true iff type has already been assigned an ID.
  bool
  type_has_existing_id(type_base* type) const
  {
    type_base *c = type->get_naked_canonical_type();
    if (c == 0)
      c = const_cast<type_base*>(type);
    return (m_type_id_map.find(c) != m_type_id_map.end());
  }

  /// Associate a unique id to a given type.  For that, put the type
  /// in a hash table, hashing the type.  So if the type has no id
  /// associated to it, create a new one and return it.  Otherwise,
  /// return the existing id for that type.
  interned_string
  get_id_for_type(const type_base_sptr& t)
  {return get_id_for_type(t.get());}

  /// Associate a unique id to a given type.  For that, put the type
  /// in a hash table, hashing the type.  So if the type has no id
  /// associated to it, create a new one and return it.  Otherwise,
  /// return the existing id for that type.
  interned_string
  get_id_for_type(const type_base* t) const
  {
    type_base *c = t->get_naked_canonical_type();
    if (c == 0)
      c = const_cast<type_base*>(t);

    type_ptr_map::const_iterator it = m_type_id_map.find(c);
    if (it != m_type_id_map.end())
      return it->second;

    switch (m_type_id_style)
      {
      case SEQUENCE_TYPE_ID_STYLE:
	{
	  interned_string id = get_id_manager().get_id_with_prefix("type-id-");
	  return m_type_id_map[c] = id;
	}
      case HASH_TYPE_ID_STYLE:
	{
	  interned_string pretty = c->get_cached_pretty_representation(true);
	  size_t hash = hashing::fnv_hash(pretty);
	  while (!m_used_type_id_hashes.insert(hash).second)
	    ++hash;
	  std::ostringstream os;
	  os << std::hex << std::setfill('0') << std::setw(8) << hash;
	  return m_type_id_map[c] = c->get_environment()->intern(os.str());
	}
      }
    ABG_ASSERT_NOT_REACHED;
    return interned_string();
  }

  string
  get_id_for_fn_tmpl(const function_tdecl_sptr& f)
  {
    fn_tmpl_shared_ptr_map::const_iterator it = m_fn_tmpl_id_map.find(f);
    if (it == m_fn_tmpl_id_map.end())
      {
	string id = get_id_manager().get_id_with_prefix("fn-tmpl-id-");
	m_fn_tmpl_id_map[f] = id;
	return id;
      }
    return m_fn_tmpl_id_map[f];
  }

  string
  get_id_for_class_tmpl(const class_tdecl_sptr& c)
  {
    class_tmpl_shared_ptr_map::const_iterator it = m_class_tmpl_id_map.find(c);
    if (it == m_class_tmpl_id_map.end())
      {
	string id = get_id_manager().get_id_with_prefix("class-tmpl-id-");
	m_class_tmpl_id_map[c] = id;
	return id;
      }
    return m_class_tmpl_id_map[c];
  }

  void
  clear_type_id_map()
  {m_type_id_map.clear();}


  /// Getter of the set of types that were referenced by a pointer,
  /// reference or typedef.
  ///
  /// This set contains only types that do have canonical types and
  /// which are not function types.
  ///
  /// @return the set of types that were referenced.
  const type_ptr_set_type&
  get_referenced_types() const
  {return m_referenced_types_set;}

  /// Getter of the set of function types that were referenced by a
  /// pointer, reference or typedef.
  ///
  /// @return the set of function types that were referenced.
  const fn_type_ptr_set_type&
  get_referenced_function_types() const
  {return m_referenced_fn_types_set;}

  /// Getter of the set of types which have no canonical types and
  /// which were referenced by a pointer, reference or typedef.
  ///
  /// @return the of referenced type that have no canonical types.
  const type_ptr_set_type&
  get_referenced_non_canonical_types() const
  {return m_referenced_non_canonical_types_set;}

  /// Record a given type as being referenced by a pointer, a
  /// reference or a typedef type that is being emitted to the XML
  /// output.
  ///
  /// @param t a shared pointer to a type
  void
  record_type_as_referenced(const type_base_sptr& t)
  {
    // If the type is a function type, record it in a dedicated data
    // structure.
    if (function_type* f = is_function_type(t.get()))
      m_referenced_fn_types_set.insert(f);
    else if (!t->get_naked_canonical_type())
      // If the type doesn't have a canonical type, record it in a
      // dedicated data structure.
      m_referenced_non_canonical_types_set.insert(t.get());
    else
      m_referenced_types_set.insert(t.get());
  }

  /// Test if a given type has been referenced by a pointer, a
  /// reference or a typedef type that was emitted to the XML output.
  ///
  /// @param f a shared pointer to a type
  ///
  /// @return true if the type has been referenced, false
  /// otherwise.
  bool
  type_is_referenced(const type_base_sptr& t)
  {
    if (function_type *f = is_function_type(t.get()))
      return (m_referenced_fn_types_set.find(f)
	      != m_referenced_fn_types_set.end());
    else if (!t->get_naked_canonical_type())
      return (m_referenced_non_canonical_types_set.find(t.get())
	      != m_referenced_non_canonical_types_set.end());
    else
      return m_referenced_types_set.find
	(t.get()) != m_referenced_types_set.end();
  }

  /// A comparison functor to compare pointers to @ref type_base.
  ///
  /// What is compared is the string representation of the pointed-to
  /// type.
  struct type_ptr_cmp
  {
    type_ptr_map *map;
    type_ptr_cmp(type_ptr_map *m)
      : map(m)
    {}

    /// The comparison operator of the functor.
    ///
    /// @param l the first type to consider.
    ///
    /// @param r the second type to consider.
    ///
    /// @return true if the string representation of type @p l is
    /// considered to be "less than" the string representation of the
    /// type @p r.
    ///
    /// But when the two string representations are equal (for
    /// instance, for typedefs that have the same string
    /// representation), this function compares the type-ids of the
    /// types.  This allows for a stable result.
    bool
    operator()(const type_base* l, const type_base* r) const
    {
      if (!l && r)
	return true;
      if (l && !r)
	return false;
      if (!l && !r)
	return false;

      string r1 = ir::get_pretty_representation(l),
	r2 = ir::get_pretty_representation(r);

      if (r1 == r2)
	{
	  type_ptr_map::const_iterator i =
	    map->find(const_cast<type_base*>(l));
	  if (i != map->end())
	    r1 = i->second;
	  i = map->find(const_cast<type_base*>(r));
	  if (i != map->end())
	    r2 = i->second;
	}

      return r1 < r2;
    }

    /// The comparison operator of the functor.
    ///
    /// @param l the first type to consider.
    ///
    /// @param r the second type to consider.
    ///
    /// @return true if the string representation of type @p l is
    /// considered to be "less than" the string representation of the
    /// type @p r.
    ///
    /// But when the two string representations are equal (for
    /// instance, for typedefs that have the same string
    /// representation), this function compares the type-ids of the
    /// types.  This allows for a stable result.
    bool
    operator()(const type_base_sptr& l, const type_base_sptr& r) const
    {return operator()(l.get(), r.get());}
  }; // end struct type_ptr_cmp

  /// Sort the content of a map of type pointers into a vector.
  ///
  /// The pointers are sorted by using their string representation as
  /// the key to sort, lexicographically.
  ///
  /// @param types the map to sort.
  ///
  /// @param sorted the resulted sorted vector.  It's set by this
  /// function with the result of the sorting.
  void
  sort_types(type_ptr_set_type& types,
	     vector<type_base*>& sorted)
  {
    string id;
    for (type_ptr_set_type::const_iterator i = types.begin();
	 i != types.end();
	 ++i)
      sorted.push_back(const_cast<type_base*>(*i));
    type_ptr_cmp comp(&m_type_id_map);
    sort(sorted.begin(), sorted.end(), comp);
  }

  /// Sort the content of a map of type pointers into a vector.
  ///
  /// The pointers are sorted by using their string representation as
  /// the key to sort, lexicographically.
  ///
  /// @param types the map to sort.
  ///
  /// @param sorted the resulted sorted vector.  It's set by this
  /// function with the result of the sorting.
  void
  sort_types(const istring_type_base_wptr_map_type& types,
	     vector<type_base_sptr> &sorted)
  {
    for (istring_type_base_wptr_map_type::const_iterator i = types.begin();
	 i != types.end();
	 ++i)
      sorted.push_back(type_base_sptr(i->second));
    type_ptr_cmp comp(&m_type_id_map);
    sort(sorted.begin(), sorted.end(), comp);
  }

  /// Sort the content of a vector of function types into a vector of
  /// types.
  ///
  /// The pointers are sorted by using their string representation as
  /// the key to sort, lexicographically.
  ///
  /// @param types the vector of function types to store.
  ///
  /// @param sorted the resulted sorted vector.  It's set by this
  /// function with the result of the sorting.
  void
  sort_types(const vector<function_type_sptr>& types,
	     vector<type_base_sptr> &sorted)
  {
    for (vector<function_type_sptr>::const_iterator i = types.begin();
	 i != types.end();
	 ++i)
      sorted.push_back(*i);
    type_ptr_cmp comp(&m_type_id_map);
    sort(sorted.begin(), sorted.end(), comp);
  }

  /// Flag a type as having been written out to the XML output.
  ///
  /// @param t the type to flag.
  void
  record_type_as_emitted(const type_base_sptr &t)
  {record_type_as_emitted(t.get());}

  /// Flag a type as having been written out to the XML output.
  ///
  /// @param t the type to flag.
  void
  record_type_as_emitted(const type_base *t)
  {
    type_base *c = t->get_naked_canonical_type();
    if (c == 0)
      c = const_cast<type_base*>(t);
    m_emitted_type_set.insert(c);
  }

  /// Test if a given type has been written out to the XML output.
  ///
  /// @param the type to test for.
  ///
  /// @return true if the type has already been emitted, false
  /// otherwise.
  bool
  type_is_emitted(const type_base *t)
  {
    return m_emitted_type_set.find(t) != m_emitted_type_set.end();
  }

  /// Test if a given type has been written out to the XML output.
  ///
  /// @param the type to test for.
  ///
  /// @return true if the type has already been emitted, false
  /// otherwise.
  bool
  type_is_emitted(const type_base_sptr& t)
  {return type_is_emitted(t.get());}

  /// Test if the name of a given decl has been written out to the XML
  /// output.
  ///
  /// @param the decl to consider.
  ///
  /// @return true if the decl has already been emitted, false
  /// otherwise.
  bool
  decl_name_is_emitted(const interned_string& name) const
  {return m_emitted_decls_map.find(name) != m_emitted_decls_map.end();}

  /// Test if a given decl has been written out to the XML output.
  ///
  /// @param the decl to consider.
  ///
  /// @return true if the decl has already been emitted, false
  /// otherwise.
  bool
  decl_is_emitted(decl_base_sptr& decl) const
  {
    if (is_type(decl))
      return false;

    string repr = get_pretty_representation(decl, true);
    interned_string irepr = decl->get_environment()->intern(repr);
    bool is_emitted = decl_name_is_emitted(irepr);
    return is_emitted;
  }

  /// Record a declaration-only class as being emitted.
  ///
  /// For now, this function expects a declaration-only class,
  /// otherwise, it aborts.
  ///
  /// @param t the declaration-only class to report as emitted.
  void
  record_decl_only_type_as_emitted(type_base* t)
  {
    class_or_union* cl = is_class_or_union_type(t);
    ABG_ASSERT(cl && cl->get_is_declaration_only());
    m_emitted_decl_only_set.insert(t);
  }

  /// Record a declaration-only class as being emitted.
  ///
  /// For now, this function expects a declaration-only class,
  /// otherwise, it aborts.
  ///
  /// @param t the declaration-only class to report as emitted.
  void
  record_decl_only_type_as_emitted(const type_base_sptr& t)
  {record_decl_only_type_as_emitted(t.get());}

  /// Test if a declaration-only class has been emitted.
  ///
  /// @param t the declaration-only class to test for.
  ///
  /// @return true iff the declaration-only class @p t has been
  /// emitted.
  bool
  decl_only_type_is_emitted(const type_base* t)
  {
    type_ptr_set_type::const_iterator i = m_emitted_decl_only_set.find(t);
    if (i == m_emitted_decl_only_set.end())
      return false;
    return true;
  }

  /// Test if a declaration-only class has been emitted.
  ///
  /// @param t the declaration-only class to test for.
  ///
  /// @return true iff the declaration-only class @p t has been
  /// emitted.
  bool
  decl_only_type_is_emitted(const type_base_sptr& t)
  {return decl_only_type_is_emitted(t.get());}

  /// Record a declaration as emitted in the abixml output.
  ///
  /// @param decl the decl to consider.
  void
  record_decl_as_emitted(const decl_base_sptr &decl)const
  {
    string repr = get_pretty_representation(decl, true);
    interned_string irepr = decl->get_environment()->intern(repr);
    m_emitted_decls_map[irepr] = true;
  }

  /// Clear the map that contains the IDs of the types that has been
  /// recorded as having been written out to the XML output.
  void
  clear_referenced_types()
  {
    m_referenced_types_set.clear();
    m_referenced_non_canonical_types_set.clear();
    m_referenced_fn_types_set.clear();
  }

  const string_elf_symbol_sptr_map_type&
  get_fun_symbol_map() const
  {return m_fun_symbol_map;}

  string_elf_symbol_sptr_map_type&
  get_fun_symbol_map()
  {return m_fun_symbol_map;}

};//end write_context

static void write_location(const location&, write_context&);
static void write_location(const decl_base_sptr&, write_context&);
static bool write_visibility(const decl_base_sptr&, ostream&);
static bool write_binding(const decl_base_sptr&, ostream&);
static bool write_is_artificial(const decl_base_sptr&, ostream&);
static bool write_is_non_reachable(const type_base_sptr&, ostream&);
static bool write_tracking_non_reachable_types(const corpus_sptr&, ostream&);
static void write_array_size_and_alignment(const array_type_def_sptr,
					   ostream&);
static void write_size_and_alignment(const type_base_sptr, ostream&,
				     size_t default_size = 0,
				     size_t default_alignment = 0);
static void write_access(access_specifier, ostream&);
static void write_layout_offset(var_decl_sptr, ostream&);
static void write_layout_offset(class_decl::base_spec_sptr, ostream&);
static void write_cdtor_const_static(bool, bool, bool, bool, ostream&);
static void write_voffset(function_decl_sptr, ostream&);
static void write_elf_symbol_type(elf_symbol::type, ostream&);
static void write_elf_symbol_binding(elf_symbol::binding, ostream&);
static bool write_elf_symbol_aliases(const elf_symbol&, ostream&);
static bool write_elf_symbol_reference(const elf_symbol&, ostream&);
static bool write_elf_symbol_reference(const elf_symbol_sptr, ostream&);
static void write_is_declaration_only(const decl_base_sptr&, ostream&);
static void write_is_struct(const class_decl_sptr&, ostream&);
static void write_is_anonymous(const decl_base_sptr&, ostream&);
static void write_naming_typedef(const class_decl_sptr&, write_context&);
static bool write_decl(const decl_base_sptr&, write_context&, unsigned);
static void write_decl_in_scope(const decl_base_sptr&,
				write_context&, unsigned);
static bool write_type_decl(const type_decl_sptr&, write_context&, unsigned);
static bool write_namespace_decl(const namespace_decl_sptr&,
				 write_context&, unsigned);
static bool write_qualified_type_def(const qualified_type_def_sptr&,
				     write_context&, unsigned);
static bool write_pointer_type_def(const pointer_type_def_sptr&,
				   write_context&, unsigned);
static bool write_reference_type_def(const reference_type_def_sptr&,
				     write_context&, unsigned);
static bool write_array_type_def(const array_type_def_sptr&,
			         write_context&, unsigned);
static bool write_enum_type_decl(const enum_type_decl_sptr&,
				 write_context&, unsigned);
static bool write_typedef_decl(const typedef_decl_sptr&,
			       write_context&, unsigned);
static bool write_elf_symbol(const elf_symbol_sptr&,
			     write_context&, unsigned);
static bool write_elf_symbols_table(const elf_symbols&,
				    write_context&, unsigned);
static bool write_var_decl(const var_decl_sptr&,
			   write_context&, bool, unsigned);
static bool write_function_decl(const function_decl_sptr&,
				write_context&, bool, unsigned);
static bool write_function_type(const function_type_sptr&,
				write_context&, unsigned);
static bool write_member_type_opening_tag(const type_base_sptr&,
					  write_context&, unsigned);
static bool write_member_type(const type_base_sptr&,
			      write_context&, unsigned);
static bool write_class_decl_opening_tag(const class_decl_sptr&, const string&,
					 write_context&, unsigned, bool);
static bool write_class_decl(const class_decl_sptr&,
			     write_context&, unsigned);
static bool write_union_decl_opening_tag(const union_decl_sptr&, const string&,
					 write_context&, unsigned, bool);
static bool write_union_decl(const union_decl_sptr&, const string&,
			     write_context&, unsigned);
static bool write_union_decl(const union_decl_sptr&, write_context&, unsigned);
static bool write_type_tparameter
(const shared_ptr<type_tparameter>, write_context&, unsigned);
static bool write_non_type_tparameter
(const shared_ptr<non_type_tparameter>, write_context&, unsigned);
static bool write_template_tparameter
(const shared_ptr<template_tparameter>, write_context&, unsigned);
static bool write_type_composition
(const shared_ptr<type_composition>, write_context&, unsigned);
static bool write_template_parameter(const shared_ptr<template_parameter>,
				     write_context&, unsigned);
static void write_template_parameters(const shared_ptr<template_decl>,
				      write_context&, unsigned);
static bool write_function_tdecl
(const shared_ptr<function_tdecl>,
 write_context&, unsigned);
static bool write_class_tdecl
(const shared_ptr<class_tdecl>,
 write_context&, unsigned);
static void	do_indent(ostream&, unsigned);
static void	do_indent_to_level(write_context&, unsigned, unsigned);
static unsigned get_indent_to_level(write_context&, unsigned, unsigned);

/// Emit nb_whitespaces white spaces into the output stream.
void
do_indent(ostream& o, unsigned nb_whitespaces)
{
  for (unsigned i = 0; i < nb_whitespaces; ++i)
    o << ' ';
}

/// Indent initial_indent + level number of xml element indentation.
///
/// @param ctxt the context of the parsing.
///
/// @param initial_indent the initial number of white space to indent to.
///
/// @param level the number of indentation level to indent to.
static void
do_indent_to_level(write_context& ctxt,
		   unsigned initial_indent,
		   unsigned level)
{
  do_indent(ctxt.get_ostream(),
	    get_indent_to_level(ctxt, initial_indent, level));
}

/// Return the number of white space of indentation that
/// #do_indent_to_level would have used.
///
/// @param ctxt the context of the parsing.
///
/// @param initial_indent the initial number of white space to indent to.
///
/// @param level the number of indentation level to indent to.
static unsigned
get_indent_to_level(write_context& ctxt, unsigned initial_indent,
		    unsigned level)
{
    int nb_ws = initial_indent +
      level * ctxt.get_config().get_xml_element_indent();
    return nb_ws;
}

/// Annotate a declaration in form of an ABIXML comment.
///
/// This function is further specialized for declarations and types
/// with special requirements.
///
/// @tparam T shall be of type decl_base_sptr or a shared pointer to a
/// type derived from it, for the instantiation to be syntactically
/// correct.
///
/// @param decl_sptr the shared pointer to the declaration of type T.
///
/// @param ctxt the context of the parsing.
///
/// @param indent the amount of white space to indent to.
///
/// @return true iff decl is valid.
template <typename T>
static bool
annotate(const T&	decl,
	 write_context& ctxt,
	 unsigned	indent)
{
  if (!decl)
    return false;

  if (!ctxt.get_annotate())
    return true;

  ostream& o = ctxt.get_ostream();

  do_indent(o, indent);

  o << "<!-- "
    << xml::escape_xml_comment(decl->get_pretty_representation())
    << " -->\n";

  return true;
}

/// Annotate an elf symbol in form of an ABIXML comment, effectively
/// writing out its demangled form.
///
/// @param sym the symbol, whose name should be demangled.
///
/// @param ctxt the context of the parsing.
///
/// @param indent the amount of white space to indent to.
///
/// @return true iff decl is valid
template<>
bool
annotate(const elf_symbol_sptr& sym,
	 write_context&	ctxt,
	 unsigned		indent)
{
  if (!sym)
    return false;

  if (!ctxt.get_annotate())
    return true;

  ostream& o = ctxt.get_ostream();

  do_indent(o, indent);
  o << "<!-- "
    << xml::escape_xml_comment(abigail::ir::demangle_cplus_mangled_name(sym->get_name()))
    << " -->\n";

  return true;
}

/// Annotate a typedef declaration in form of an ABIXML comment.
///
/// @param typedef_decl the typedef to annotate.
///
/// @param ctxt the context of the parsing.
///
/// @param indent the amount of white space to indent to.
///
/// @return true iff decl is valid
template<>
bool
annotate(const typedef_decl_sptr&	typedef_decl,
	 write_context&		ctxt,
	 unsigned			indent)
{
  if (!typedef_decl)
    return false;

  if (!ctxt.get_annotate())
    return true;

  ostream& o = ctxt.get_ostream();

  do_indent(o, indent);

  o << "<!-- typedef "
    << get_type_name(typedef_decl->get_underlying_type())
    << " "
    << get_type_name(typedef_decl)
    << " -->\n";

  return true;
}

/// Annotate a function type in form of an ABIXML comment.
///
/// @param function_type the function type to annotate.
///
/// @param ctxt the context of the parsing.
///
/// @param indent the amount of white space to indent to.
///
/// @param skip_first_parm if true, do not serialize the first
/// parameter of the function decl.
//
/// @return true iff decl is valid
bool
annotate(const function_type_sptr&	function_type,
	 write_context&		ctxt,
	 unsigned			indent)
{
  if (!function_type)
    return false;

  if (!ctxt.get_annotate())
    return true;

  ostream& o = ctxt.get_ostream();

  do_indent(o, indent);
  o << "<!-- "
    << xml::escape_xml_comment(get_type_name(function_type->get_return_type()))
    << " (";

  vector<shared_ptr<function_decl::parameter> >::const_iterator pi =
    function_type->get_first_non_implicit_parm();

  for (; pi != function_type->get_parameters().end(); ++pi)
    {
      o << xml::escape_xml_comment((*pi)->get_type_name());
      // emit a comma after a param type, unless it's the last one
      if (distance(pi, function_type->get_parameters().end()) > 1)
	o << ", ";
    }
  o << ") -->\n";

  return true;
}

/// Annotate a function declaration in form of an ABIXML comment.
///
/// @param fn the function decl to annotate.
///
/// @param ctxt the context of the parsing.
///
/// @param indent the amount of white space to indent to.
///
/// @param skip_first_parm if true, do not serialize the first
/// parameter of the function decl.
//
/// @return true iff decl is valid
static bool
annotate(const function_decl_sptr&	fn,
	 write_context&		ctxt,
	 unsigned			indent)
{
  if (!fn)
    return false;

  if (!ctxt.get_annotate())
    return true;

  ostream& o = ctxt.get_ostream();

  do_indent(o, indent);
  o << "<!-- ";

  if (is_member_function(fn)
      && (get_member_function_is_ctor(fn) || get_member_function_is_dtor(fn)))
    ; // we don't emit return types for ctor or dtors
  else
    o << xml::escape_xml_comment(get_type_name(fn->get_return_type()))
      << " ";

  o << xml::escape_xml_comment(fn->get_qualified_name()) << "(";

  vector<function_decl::parameter_sptr>::const_iterator pi =
    fn->get_first_non_implicit_parm();

  for (; pi != fn->get_parameters().end(); ++pi)
    {
      o << xml::escape_xml_comment((*pi)->get_type_name());
      // emit a comma after a param type, unless it's the last one
      if (distance(pi, fn->get_parameters().end()) > 1)
	o << ", ";
    }
  o << ") -->\n";

  return true;
}

/// Annotate a function parameter in form of an ABIXML comment.
///
/// @param parm the function parameter to annotate.
///
/// @param ctxt the context of the parsing.
///
/// @param indent the amount of white space to indent to.
///
/// @return true iff decl is valid
template<>
bool
annotate(const function_decl::parameter_sptr&	parm,
	 write_context&			ctxt,
	 unsigned				indent)
{
  if (!parm)
    return false;

  if (!ctxt.get_annotate())
    return true;

  ostream &o = ctxt.get_ostream();

  do_indent(o, indent);

  o << "<!-- ";

  if (parm->get_variadic_marker())
    o << "variadic parameter";
  else
    {
      if (parm->get_is_artificial())
	{
	  if (parm->get_index() == 0)
	    o << "implicit ";
	  else
	    o << "artificial ";
	}
      o << "parameter of type '"
	<< xml::escape_xml_comment(get_pretty_representation(parm->get_type()));
    }

  o << "' -->\n";

  return true;
}

/// Write a location to the output stream.
///
/// If the location is empty, nothing is written.
///
/// @param loc the location to consider.
///
/// @param tu the translation unit the location belongs to.
///
/// @param ctxt the writer context to use.
static void
write_location(const location& loc, write_context& ctxt)
{
  if (!loc)
    return;

  if (!ctxt.get_show_locs())
    return;

  string filepath;
  unsigned line = 0, column = 0;

  loc.expand(filepath, line, column);

  ostream &o = ctxt.get_ostream();

  if (ctxt.get_short_locs())
    tools_utils::base_name(filepath, filepath);

  o << " filepath='" << xml::escape_xml_string(filepath) << "'"
    << " line='"     << line     << "'"
    << " column='"   << column   << "'";
}

/// Write the location of a decl to the output stream.
///
/// If the location is empty, nothing is written.
///
/// @param decl the decl to consider.
///
/// @param ctxt the @ref writer_context to use.
static void
write_location(const decl_base_sptr&	decl,
	       write_context&		ctxt)
{
  if (!decl)
    return;

  location loc = decl->get_location();
  if (!loc)
    return;

  write_location(loc, ctxt);
}

/// Serialize the visibility property of the current decl as the
/// 'visibility' attribute for the current xml element.
///
/// @param decl the instance of decl_base to consider.
///
/// @param o the output stream to serialize the property to.
///
/// @return true upon successful completion, false otherwise.
static bool
write_visibility(const shared_ptr<decl_base>&	decl, ostream& o)
{
  if (!decl)
    return false;

  decl_base::visibility v = decl->get_visibility();
  string str;

  switch (v)
    {
    case decl_base::VISIBILITY_NONE:
      return true;
    case decl_base::VISIBILITY_DEFAULT:
      str = "default";
      break;
    case decl_base::VISIBILITY_PROTECTED:
      str = "protected";
      break;
    case decl_base::VISIBILITY_HIDDEN:
      str = "hidden";
      break;
    case decl_base::VISIBILITY_INTERNAL:
	str = "internal";
	break;
    }

  if (str.empty())
    return false;

  o << " visibility='" << str << "'";

  return true;
}

/// Serialize the 'binding' property of the current decl.
///
/// @param decl the decl to consider.
///
/// @param o the output stream to serialize the property to.
static bool
write_binding(const shared_ptr<decl_base>& decl, ostream& o)
{
  if (!decl)
    return false;

  decl_base::binding bind = decl_base::BINDING_NONE;

  shared_ptr<var_decl> var =
    dynamic_pointer_cast<var_decl>(decl);
  if (var)
    bind = var->get_binding();
  else
    {
      shared_ptr<function_decl> fun =
	dynamic_pointer_cast<function_decl>(decl);
      if (fun)
	bind = fun->get_binding();
    }

  string str;
  switch (bind)
    {
    case decl_base::BINDING_NONE:
      break;
    case decl_base::BINDING_LOCAL:
      str = "local";
      break;
    case decl_base::BINDING_GLOBAL:
	str = "global";
      break;
    case decl_base::BINDING_WEAK:
      str = "weak";
      break;
    }

  if (!str.empty())
    o << " binding='" << str << "'";

  return true;
}

/// Write the "is-artificial" attribute of the @ref decl.
///
/// @param decl the declaration to consider.
///
/// @param o the output stream to emit the "is-artificial" attribute
/// to.
///
/// @return true iff the "is-artificial" attribute was emitted.
static bool
write_is_artificial(const decl_base_sptr& decl, ostream& o)
{
  if (!decl)
    return false;

  if (decl->get_is_artificial())
    o << " is-artificial='yes'";

  return true;
}

/// Write the 'is-non-reachable' attribute if a given type we are
/// looking at is not reachable from global functions and variables
/// and if the user asked us to track that information.
///
/// @param t the type to consider.
///
/// @param o the output stream to write the 'is-non-reachable'
/// attribute to.
static bool
write_is_non_reachable(const type_base_sptr& t, ostream& o)
{
  if (!t)
    return false;

  corpus* c = t->get_corpus();
  if (!c)
    return false;

  if (!c->recording_types_reachable_from_public_interface_supported()
      || c->type_is_reachable_from_public_interfaces(*t))
    return false;

  o << " is-non-reachable='yes'";

  return true;
}

/// Write the 'tracking-non-reachable-types' attribute if for a given
/// corpus, the user wants us to track non-reachable types.
///
/// @param corpus the ABI corpus to consider.
///
/// @param o the output parameter to write the
/// 'tracking-non-reachable-types' attribute to.
static bool
write_tracking_non_reachable_types(const corpus_sptr& corpus,
				   ostream& o)
{
  corpus_group* group = corpus->get_group();
  if (!group)
    if (corpus->recording_types_reachable_from_public_interface_supported())
      {
	o << " tracking-non-reachable-types='yes'";
	return true;
      }

  return false;
}

/// Serialize the size and alignment attributes of a given type.
///
/// @param decl the type to consider.
///
/// @param o the output stream to serialize to.
///
/// @param default_size size in bits that is the default for the type.
///                     No size-in-bits attribute is written if it
///                     would be the default value.
///
/// @param default_alignment alignment in bits that is the default for
///                     the type.  No alignment-in-bits attribute is
///                     written if it would be the default value.
static void
write_size_and_alignment(const shared_ptr<type_base> decl, ostream& o,
			 size_t default_size, size_t default_alignment)
{
  size_t size_in_bits = decl->get_size_in_bits();
  if (size_in_bits != default_size)
    o << " size-in-bits='" << size_in_bits << "'";

  size_t alignment_in_bits = decl->get_alignment_in_bits();
  if (alignment_in_bits != default_alignment)
    o << " alignment-in-bits='" << alignment_in_bits << "'";
}

/// Serialize the size and alignment attributes of a given type.
/// @param decl the type to consider.
///
/// @param o the output stream to serialize to.
static void
write_array_size_and_alignment(const shared_ptr<array_type_def> decl, ostream& o)
{
  if (decl->is_infinite())
    o << " size-in-bits='" << "infinite" << "'";
  else {
    size_t size_in_bits = decl->get_size_in_bits();
    if (size_in_bits)
      o << " size-in-bits='" << size_in_bits << "'";
  }

  size_t alignment_in_bits = decl->get_alignment_in_bits();
  if (alignment_in_bits)
    o << " alignment-in-bits='" << alignment_in_bits << "'";
}
/// Serialize the access specifier.
///
/// @param a the access specifier to serialize.
///
/// @param o the output stream to serialize it to.
static void
write_access(access_specifier a, ostream& o)
{
  string access_str = "private";

  switch (a)
    {
    case private_access:
      access_str = "private";
      break;

    case protected_access:
      access_str = "protected";
      break;

    case public_access:
      access_str = "public";
      break;

    default:
      break;
    }

  o << " access='" << access_str << "'";
}

/// Serialize the layout offset of a data member.
static void
write_layout_offset(var_decl_sptr member, ostream& o)
{
  if (!is_data_member(member))
    return;

  if (get_data_member_is_laid_out(member))
    o << " layout-offset-in-bits='"
      << get_data_member_offset(member)
      << "'";
}

/// Serialize the layout offset of a base class
static void
write_layout_offset(shared_ptr<class_decl::base_spec> base, ostream& o)
{
  if (!base)
    return;

  if (base->get_offset_in_bits() >= 0)
    o << " layout-offset-in-bits='" << base->get_offset_in_bits() << "'";
}

/// Serialize the access specifier of a class member.
///
/// @param member a pointer to the class member to consider.
///
/// @param o the ostream to serialize the member to.
static void
write_access(decl_base_sptr member, ostream& o)
{write_access(get_member_access_specifier(member), o);}

/// Write the voffset of a member function if it's non-zero
///
/// @param fn the member function to consider
///
/// @param o the output stream to write to
static void
write_voffset(function_decl_sptr fn, ostream&o)
{
  if (!fn)
    return;

  if (get_member_function_is_virtual(fn))
    {
      ssize_t voffset = get_member_function_vtable_offset(fn);
      o << " vtable-offset='" << voffset << "'";
    }
}

/// Serialize an elf_symbol::type into an XML node attribute named
/// 'type'.
///
/// @param t the elf_symbol::type to serialize.
///
/// @param o the output stream to serialize it to.
static void
write_elf_symbol_type(elf_symbol::type t, ostream& o)
{
  string repr;

  switch (t)
    {
    case elf_symbol::NOTYPE_TYPE:
      repr = "no-type";
      break;
    case elf_symbol::OBJECT_TYPE:
      repr = "object-type";
      break;
    case elf_symbol::FUNC_TYPE:
      repr = "func-type";
      break;
    case elf_symbol::SECTION_TYPE:
      repr = "section-type";
      break;
    case elf_symbol::FILE_TYPE:
      repr = "file-type";
      break;
    case elf_symbol::COMMON_TYPE:
      repr = "common-type";
      break;
    case elf_symbol::TLS_TYPE:
      repr = "tls-type";
      break;
    case elf_symbol::GNU_IFUNC_TYPE:
      repr = "gnu-ifunc-type";
      break;
    default:
      repr = "no-type";
      break;
    }

  o << " type='" << repr << "'";
}

/// Serialize an elf_symbol::binding into an XML element attribute of
/// name 'binding'.
///
/// @param b the elf_symbol::binding to serialize.
///
/// @param o the output stream to serialize the binding to.
static void
write_elf_symbol_binding(elf_symbol::binding b, ostream& o)
{
  string repr;

  switch (b)
    {
    case elf_symbol::LOCAL_BINDING:
      repr = "local-binding";
      break;
    case elf_symbol::GLOBAL_BINDING:
      repr = "global-binding";
      break;
    case elf_symbol::WEAK_BINDING:
      repr = "weak-binding";
      break;
    case elf_symbol::GNU_UNIQUE_BINDING:
      repr = "gnu-unique-binding";
      break;
    default:
      repr = "no-binding";
      break;
    }

  o << " binding='" << repr << "'";
}

/// Serialize an elf_symbol::binding into an XML element attribute of
/// name 'binding'.
///
/// @param b the elf_symbol::binding to serialize.
///
/// @param o the output stream to serialize the binding to.
static void
write_elf_symbol_visibility(elf_symbol::visibility v, ostream& o)
{
  string repr;

  switch (v)
    {
    case elf_symbol::DEFAULT_VISIBILITY:
      repr = "default-visibility";
      break;
    case elf_symbol::PROTECTED_VISIBILITY:
      repr = "protected-visibility";
      break;
    case elf_symbol::HIDDEN_VISIBILITY:
      repr = "hidden-visibility";
      break;
    case elf_symbol::INTERNAL_VISIBILITY:
      repr = "internal-visibility";
      break;
    default:
      repr = "default-visibility";
      break;
    }

  o << " visibility='" << repr << "'";
}

/// Write alias attributes for the aliases of a given symbol.
///
/// @param sym the symbol to write the attributes for.
///
/// @param o the output stream to write the attributes to.
///
/// @return true upon successful completion.
static bool
write_elf_symbol_aliases(const elf_symbol& sym, ostream& out)
{
  if (!sym.is_main_symbol() || !sym.has_aliases())
    return false;


  std::vector<std::string> aliases;
  for (elf_symbol_sptr s = sym.get_next_alias(); s && !s->is_main_symbol();
       s = s->get_next_alias())
    {
      if (s->is_suppressed())
	continue;

      if (sym.is_in_ksymtab() != s->is_in_ksymtab())
	continue;

      aliases.push_back(s->get_id_string());
    }

  if (!aliases.empty())
    {
      out << " alias='";
      std::string separator;
      for (const auto& alias : aliases)
	{
	  out << separator << alias;
	  separator = ",";
	}

      out << "'";
      return true;
    }

  return false;
}

/// Write an XML attribute for the reference to a symbol for the
/// current decl.
///
/// @param sym the symbol to consider.
///
/// @param o the output stream to write the attribute to.
///
/// @return true upon successful completion.
static bool
write_elf_symbol_reference(const elf_symbol& sym, ostream& o)
{
  o << " elf-symbol-id='" << sym.get_id_string() << "'";
  return true;
}

/// Write an XML attribute for the reference to a symbol for the
/// current decl.
///
/// @param sym the symbol to consider.
///
/// @param o the output stream to write the attribute to.
///
/// @return true upon successful completion.
static bool
write_elf_symbol_reference(const elf_symbol_sptr sym, ostream& o)
{
  if (!sym)
    return false;

  return write_elf_symbol_reference(*sym, o);
}

/// Serialize the attributes "constructor", "destructor" or "static"
/// if they have true value.
///
/// @param is_ctor if set to true, the "constructor='true'" string is
/// emitted.
///
/// @param is_dtor if set to true the "destructor='true' string is
/// emitted.
///
/// @param is_static if set to true the "static='true'" string is
/// emitted.
///
/// @param o the output stream to use for the serialization.
static void
write_cdtor_const_static(bool is_ctor,
			 bool is_dtor,
			 bool is_const,
			 bool is_static,
			 ostream& o)
{
  if (is_static)
    o << " static='yes'";
  if (is_ctor)
    o << " constructor='yes'";
  else if (is_dtor)
    o << " destructor='yes'";
  if (is_const)
    o << " const='yes'";
}

/// Serialize the attribute "is-declaration-only", if the
/// decl_base_sptr has its 'is_declaration_only property set.
///
/// @param t the pointer to instance of @ref decl_base to consider.
///
/// @param o the output stream to serialize to.
static void
write_is_declaration_only(const decl_base_sptr& d, ostream& o)
{
  if (d->get_is_declaration_only())
    o << " is-declaration-only='yes'";
}

/// Serialize the attribute "is-struct", if the current instance of
/// class_decl is a struct.
///
/// @param klass a pointer to the instance of class_decl to consider.
///
/// @param o the output stream to serialize to.
static void
write_is_struct(const class_decl_sptr& klass, ostream& o)
{
  if (klass->is_struct())
    o << " is-struct='yes'";
}

/// Serialize the attribute "is-anonymous", if the current instance of
/// decl is anonymous
///
/// @param dcl a pointer to the instance of @ref decl_base to consider.
///
/// @param o the output stream to serialize to.
static void
write_is_anonymous(const decl_base_sptr& decl, ostream& o)
{
  if (decl->get_is_anonymous())
    o << " is-anonymous='yes'";
}

/// Serialize the "naming-typedef-id" attribute, if the current
/// instance of @ref class_decl has a naming typedef.
///
/// @param klass the @ref class_decl to consider.
///
/// @param ctxt the write context to use.
static void
write_naming_typedef(const class_decl_sptr& klass, write_context& ctxt)
{
  if (!klass)
    return;

  ostream &o = ctxt.get_ostream();

  if (typedef_decl_sptr typedef_type = klass->get_naming_typedef())
    {
      string id = ctxt.get_id_for_type(typedef_type);
      o << " naming-typedef-id='" << id << "'";
    }
}

/// Helper to serialize a type artifact.
///
/// @param type the type to serialize.
///
/// @param ctxt the @ref write_context to use.
///
/// @param indent the number of white space to use for indentation.
///
/// @return true upon successful completion.
static bool
write_type(const type_base_sptr& type, write_context& ctxt, unsigned indent)
{
  if (write_type_decl(dynamic_pointer_cast<type_decl> (type),
		      ctxt, indent)
      || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
				   (type),
				   ctxt, indent)
      || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(type),
				ctxt, indent)
      || write_reference_type_def(dynamic_pointer_cast
				  <reference_type_def>(type), ctxt, indent)
      || write_array_type_def(dynamic_pointer_cast
			      <array_type_def>(type), ctxt, indent)
      || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(type),
			      ctxt, indent)
      || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(type),
			    ctxt, indent)
      || write_class_decl(is_class_type(type), ctxt, indent)
      || write_union_decl(is_union_type(type), ctxt, indent)
      || (write_function_tdecl
	  (dynamic_pointer_cast<function_tdecl>(type), ctxt, indent))
      || (write_class_tdecl
	  (dynamic_pointer_cast<class_tdecl>(type), ctxt, indent)))
    return true;

  return false;
}

/// Serialize a pointer to an of decl_base into an output stream.
///
/// @param decl the pointer to decl_base to serialize
///
/// @param ctxt the context of the serialization.  It contains e.g, the
/// output stream to serialize to.
///
/// @param indent how many indentation spaces to use during the
/// serialization.
///
/// @return true upon successful completion, false otherwise.
static bool
write_decl(const decl_base_sptr& decl, write_context& ctxt, unsigned indent)
{
  if (write_type_decl(dynamic_pointer_cast<type_decl> (decl),
		      ctxt, indent)
      || write_namespace_decl(dynamic_pointer_cast<namespace_decl>(decl),
			      ctxt, indent)
      || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
				   (decl),
				   ctxt, indent)
      || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(decl),
				ctxt, indent)
      || write_reference_type_def(dynamic_pointer_cast
				  <reference_type_def>(decl), ctxt, indent)
      || write_array_type_def(dynamic_pointer_cast
			      <array_type_def>(decl), ctxt, indent)
      || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(decl),
			      ctxt, indent)
      || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(decl),
			    ctxt, indent)
      || write_var_decl(dynamic_pointer_cast<var_decl>(decl), ctxt,
			/*write_linkage_name=*/true, indent)
      || write_function_decl(dynamic_pointer_cast<method_decl>
			     (decl), ctxt, /*skip_first_parameter=*/true,
			     indent)
      || write_function_decl(dynamic_pointer_cast<function_decl>(decl),
			     ctxt, /*skip_first_parameter=*/false, indent)
      || write_class_decl(is_class_type(decl), ctxt, indent)
      || write_union_decl(is_union_type(decl), ctxt, indent)
      || (write_function_tdecl
	  (dynamic_pointer_cast<function_tdecl>(decl), ctxt, indent))
      || (write_class_tdecl
	  (dynamic_pointer_cast<class_tdecl>(decl), ctxt, indent)))
    return true;

  return false;
}

/// Emit a declaration, along with its scope.
///
/// This function is called at the end of emitting a translation unit,
/// to emit type declarations that were referenced by types that were
/// emitted in the TU already, but that were not emitted themselves.
///
/// @param decl the decl to emit.
///
/// @param ctxt the write context to use.
///
/// @param initial_indent the number of indentation spaces to use.
static void
write_decl_in_scope(const decl_base_sptr&	decl,
		    write_context&		ctxt,
		    unsigned			initial_indent)
{
  type_base_sptr type = is_type(decl);
  ABG_ASSERT(type);

  if (ctxt.type_is_emitted(type))
    return;

  list<scope_decl*> scopes;
  for (scope_decl* s = decl->get_scope();
       s && !is_global_scope(s);
       s = s->get_scope())
    scopes.push_front(s);

  ostream& o = ctxt.get_ostream();
  const config& c = ctxt.get_config();
  stack<string> closing_tags;
  stack<unsigned> closing_indents;
  unsigned indent = initial_indent;
  for (list<scope_decl*>::const_iterator i = scopes.begin();
       i != scopes.end();
       ++i)
    {
      ABG_ASSERT(!is_global_scope(*i));

      // A type scope is either a namespace ...
      if (namespace_decl* n = is_namespace(*i))
	{
	  do_indent(o, indent);
	  o << "<namespace-decl name='"
	    << xml::escape_xml_string(n->get_name())
	    << "'>\n";
	  closing_tags.push("</namespace-decl>");
	  closing_indents.push(indent);
	}
      // ... or a class.
      else if (class_decl* c = is_class_type(*i))
	{
	  class_decl_sptr class_type(c, noop_deleter());
	  write_class_decl_opening_tag(class_type, "", ctxt, indent,
				       /*prepare_to_handle_members=*/false);
	  closing_tags.push("</class-decl>");
	  closing_indents.push(indent);

	  unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
	  write_member_type_opening_tag(type, ctxt, nb_ws);
	  indent = nb_ws;
	  closing_tags.push("</member-type>");
	  closing_indents.push(nb_ws);
	}
      else if (union_decl *u = is_union_type(*i))
	{
	  union_decl_sptr union_type(u, noop_deleter());
	  write_union_decl_opening_tag(union_type, "", ctxt, indent,
				       /*prepare_to_handle_members=*/false);
	  closing_tags.push("</union-decl>");
	  closing_indents.push(indent);

	  unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
	  write_member_type_opening_tag(type, ctxt, nb_ws);
	  indent = nb_ws;
	  closing_tags.push("</member-type>");
	  closing_indents.push(nb_ws);
	}
      else
	// We should never reach this point.
	abort();
      indent += c.get_xml_element_indent();
    }

  write_decl(decl, ctxt, indent);

  while (!closing_tags.empty())
    {
      do_indent(o, closing_indents.top());
      o << closing_tags.top() << "\n";
      closing_tags.pop();
      closing_indents.pop();
    }
}

/// Create a @ref write_context object that can be used to emit abixml
/// files.
///
/// @param env the environment for the @ref write_context object to use.
///
/// @param default_output_stream the default output stream to use.
///
/// @return the new @ref write_context object.
write_context_sptr
create_write_context(const environment *env,
		     ostream& default_output_stream)
{
  write_context_sptr ctxt(new write_context(env, default_output_stream));
  return ctxt;
}

/// Set the "show-locs" flag.
///
/// When this flag is set then the XML writer emits location (///
/// information (file name, line and column) for the ABI artifacts
/// that it emits.
///
/// @param ctxt the @ref write_context to set the option for.
///
/// @param flag the new value of the option.
void
set_show_locs(write_context& ctxt, bool flag)
{ctxt.set_show_locs(flag);}

/// Set the 'annotate' flag.
///
/// When this flag is set then the XML writer annotates ABI artifacts
/// with a human readable description.
///
/// @param ctxt the context to set this flag on to.
///
/// @param flag the new value of the 'annotate' flag.
void
set_annotate(write_context& ctxt, bool flag)
{ctxt.set_annotate(flag);}

/// Set the new ostream.
///
/// The ostream refers to the object, writers should stream new output to.
///
/// @param ctxt the context to set this to.
///
/// @param os the new ostream
void
set_ostream(write_context& ctxt, ostream& os)
{ctxt.set_ostream(os);}

/// Set the 'write-architecture' flag.
///
/// When this flag is set then the XML writer will emit architecture
/// information
///
/// @param ctxt the context to set this flag on to.
///
/// @param flag the new value of the 'write-architecture' flag.
void
set_write_architecture(write_context& ctxt, bool flag)
{ctxt.set_write_architecture(flag);}

/// Set the 'write-corpus-path' flag.
///
/// When this flag is set then the XML writer will emit corpus-path
/// information
///
/// @param ctxt the context to set this flag on to.
///
/// @param flag the new value of the 'write-corpus-path' flag.
void
set_write_corpus_path(write_context& ctxt, bool flag)
{ctxt.set_write_corpus_path(flag);}

/// Set the 'write-comp-dir' flag.
///
/// When this flag is set then the XML writer will emit compilation dir
/// information
///
/// @param ctxt the context to set this flag on to.
///
/// @param flag the new value of the 'write-comp-dir' flag.
void
set_write_comp_dir(write_context& ctxt, bool flag)
{ctxt.set_write_comp_dir(flag);}

/// Set the 'short-locs' flag.
///
/// When this flag is set then the XML writer will emit only file names
/// rather than full paths.
///
/// @param ctxt the context to set this flag on to.
///
/// @param flag the new value of the 'short-locs' flag.
void
set_short_locs(write_context& ctxt, bool flag)
{ctxt.set_short_locs(flag);}

/// Set the 'parameter-names' flag.
///
/// When this flag is set then the XML writer will emit the names of
/// function parameters.
///
/// @param ctxt the context to set this flag on to.
///
/// @param flag the new value of the 'parameter-names' flag.
void
set_write_parameter_names(write_context& ctxt, bool flag)
{ctxt.set_write_parameter_names(flag);}

/// Set the 'elf-needed' flag.
///
/// When this flag is set then the XML writer will emit corpus
/// get_needed() (DT_NEEDED) information.
///
/// @param ctxt the context to set this flag on to.
///
/// @param flag the new value of the 'elf-needed' flag.
void
set_write_elf_needed(write_context& ctxt, bool flag)
{ctxt.set_write_elf_needed(flag);}

/// Set the 'default-sizes' flag.
///
/// When this flag is set then the XML writer will emit default
/// size-in-bits attributes for pointer type definitions, reference
/// type definitions, function declarations and function types even
/// when they are equal to the default address size of the translation
/// unit.
///
/// @param ctxt the context to set this flag on to.
///
/// @param flag the new value of the 'default-sizes' flag.
void
set_write_default_sizes(write_context& ctxt, bool flag)
{ctxt.set_write_default_sizes(flag);}

/// Set the 'type-id-style' property.
///
/// This property controls the kind of type ids used in XML output.
///
/// @param ctxt the context to set this property on.
///
/// @param style the new value of the 'type-id-style' property.
void
set_type_id_style(write_context& ctxt, type_id_style_kind style)
{ctxt.set_type_id_style(style);}

/// Serialize the canonical types of a given scope.
///
/// @param scope the scope to consider.
///
/// @param ctxt the write context to use.
///
/// @param indent the number of white space indentation to use.
 //
 // @param is_member_type if true, the canonical types are emitted as
 // member types (of a class).
 //
 // return true upon successful completion.
static bool
write_canonical_types_of_scope(const scope_decl	&scope,
			       write_context		&ctxt,
			       const unsigned		indent,
			       bool			is_member_type = false)
{
  const type_base_sptrs_type &canonical_types =
    scope.get_sorted_canonical_types();

  for (type_base_sptrs_type::const_iterator i = canonical_types.begin();
       i != canonical_types.end();
       ++i)
    {
      if (is_member_type)
	write_member_type(*i, ctxt, indent);
      else
	write_type(*i, ctxt, indent);
    }

  return true;
}

/// Serialize a translation unit to an output stream.
///
/// @param ctxt the context of the serialization.  It contains e.g,
/// the output stream to serialize to.
///
/// @param tu the translation unit to serialize.
///
/// @param indent how many indentation spaces to use during the
/// serialization.
///
/// @return true upon successful completion, false otherwise.
bool
write_translation_unit(write_context&	       ctxt,
		       const translation_unit& tu,
		       const unsigned	       indent)
{
  ostream& o = ctxt.get_ostream();
  const config& c = ctxt.get_config();

  do_indent(o, indent);

  o << "<abi-instr version='"
    << c.get_format_major_version_number()
    << "." << c.get_format_minor_version_number()
    << "'";

  if (tu.get_address_size() != 0)
    o << " address-size='" << static_cast<int>(tu.get_address_size()) << "'";

  std::string tu_path = tu.get_path();
  if (ctxt.get_short_locs())
    tools_utils::base_name(tu_path, tu_path);
  if (!tu_path.empty())
    o << " path='" << xml::escape_xml_string(tu_path) << "'";

  if (!tu.get_compilation_dir_path().empty() && ctxt.get_write_comp_dir())
    o << " comp-dir-path='"
      << xml::escape_xml_string(tu.get_compilation_dir_path()) << "'";

  if (tu.get_language() != translation_unit::LANG_UNKNOWN)
    o << " language='"
      << translation_unit_language_to_string(tu.get_language())
      <<"'";

  if (tu.is_empty())
    {
      o << "/>\n";
      return true;
    }

  o << ">\n";

  write_canonical_types_of_scope(*tu.get_global_scope(),
				 ctxt, indent + c.get_xml_element_indent());

  typedef scope_decl::declarations declarations;
  typedef declarations::const_iterator const_iterator;
  const declarations& d = tu.get_global_scope()->get_sorted_member_decls();

  for (const_iterator i = d.begin(); i != d.end(); ++i)
    {
      if (type_base_sptr t = is_type(*i))
	{
	  // Emit non-empty classes that are declaration-only. Those
	  // beasts are class that only contain member types.
	  if (class_decl_sptr class_type = is_class_type(t))
	    if (class_type->get_is_declaration_only()
		&& !class_type->is_empty()
		&& !ctxt.type_is_emitted(class_type))
	      write_type(class_type, ctxt,
			 indent + c.get_xml_element_indent());
	  continue;
	}

      if (decl_base_sptr d = is_decl(*i))
	if (ctxt.decl_is_emitted(d))
	  continue;
      write_decl(*i, ctxt, indent + c.get_xml_element_indent());
    }

  // Now let's handle types that were referenced, but not yet
  // emitted because they are either:
  //   1/ Types without canonical type
  //   2/ or function types (these might have no scope).

  // So this map of type -> string is to contain the referenced types
  // we need to emit.
  type_ptr_set_type referenced_types_to_emit;

  for (type_ptr_set_type::const_iterator i =
	 ctxt.get_referenced_types().begin();
       i != ctxt.get_referenced_types().end();
       ++i)
    if (!ctxt.type_is_emitted(*i)
	&& !ctxt.decl_only_type_is_emitted(*i))
	referenced_types_to_emit.insert(*i);

  for (fn_type_ptr_set_type::const_iterator i =
	 ctxt.get_referenced_function_types().begin();
       i != ctxt.get_referenced_function_types().end();
       ++i)
    if (!ctxt.type_is_emitted(*i)
	&& !ctxt.decl_only_type_is_emitted(*i))
      // A referenced type that was not emitted at all must be
      // emitted now.
      referenced_types_to_emit.insert(*i);

  for (type_ptr_set_type::const_iterator i =
	 ctxt.get_referenced_non_canonical_types().begin();
       i != ctxt.get_referenced_non_canonical_types().end();
       ++i)
    if (!ctxt.type_is_emitted(*i)
	&& !ctxt.decl_only_type_is_emitted(*i))
      // A referenced type that was not emitted at all must be
      // emitted now.
      referenced_types_to_emit.insert(*i);

  // Ok, now let's emit the referenced type for good.
  while (!referenced_types_to_emit.empty())
    {
      // But first, we need to sort them, otherwise, emitting the ABI
      // (in xml) of the same binary twice will yield different
      // results, because we'd be walking an *unordered* hash table.
      vector<type_base*> sorted_referenced_types;
      ctxt.sort_types(referenced_types_to_emit,
		      sorted_referenced_types);

      // Clear the types recorded as referenced by the process of
      // emitting the types out.  New types are going to be referenced
      // the process of emitting the types below.
      ctxt.clear_referenced_types();

      // Now, emit the referenced decls in a sorted order.
      for (vector<type_base*>::const_iterator i =
	     sorted_referenced_types.begin();
	   i != sorted_referenced_types.end();
	   ++i)
	{
	  // We handle types which have declarations *and* function
	  // types here.
	  type_base_sptr t(*i, noop_deleter());
	  if (!ctxt.type_is_emitted(t))
	    {
	      if (decl_base* d = get_type_declaration(*i))
		{
		  decl_base_sptr decl(d, noop_deleter());
		  write_decl_in_scope(decl, ctxt,
				      indent + c.get_xml_element_indent());
		}
	      else if (function_type_sptr fn_type = is_function_type(t))
		write_function_type(fn_type, ctxt,
				    indent + c.get_xml_element_indent());
	      else
		ABG_ASSERT_NOT_REACHED;
	    }
	}

      // So all the (referenced) types that we wanted to emit were
      // emitted.
      referenced_types_to_emit.clear();

      // But then, while emitting those referenced type, other types
      // might have been referenced by those referenced types
      // themselves!  So let's look at the sets of referenced type
      // that are maintained for the entire ABI corpus and see if
      // there are still some referenced types in there that are not
      // emitted yet.  If yes, then we'll emit those again.

      for (type_ptr_set_type::const_iterator i =
	     ctxt.get_referenced_types().begin();
	   i != ctxt.get_referenced_types().end();
	   ++i)
	if (!ctxt.type_is_emitted(*i)
	    && !ctxt.decl_only_type_is_emitted(*i))
	  // A referenced type that was not emitted at all must be
	  // emitted now.
	  referenced_types_to_emit.insert(*i);

      for (type_ptr_set_type::const_iterator i =
	     ctxt.get_referenced_non_canonical_types().begin();
	   i != ctxt.get_referenced_non_canonical_types().end();
	   ++i)
	if (!ctxt.type_is_emitted(*i)
	    && !ctxt.decl_only_type_is_emitted(*i))
	  // A referenced type that was not emitted at all must be
	  // emitted now.
	  referenced_types_to_emit.insert(*i);
    }

  // Now handle all function types that were not only referenced by
  // emitted types.
  const vector<function_type_sptr>& t = tu.get_live_fn_types();
  vector<type_base_sptr> sorted_types;
  ctxt.sort_types(t, sorted_types);

  for (vector<type_base_sptr>::const_iterator i = sorted_types.begin();
       i != sorted_types.end();
       ++i)
    {
      function_type_sptr fn_type = is_function_type(*i);

      if (!ctxt.type_is_referenced(fn_type) || ctxt.type_is_emitted(fn_type))
	// This function type is either not referenced by any emitted
	// pointer or reference type, or has already been emitted, so skip it.
	continue;

      ABG_ASSERT(fn_type);
      write_function_type(fn_type, ctxt, indent + c.get_xml_element_indent());
    }

  ctxt.clear_referenced_types();

  do_indent(o, indent);
  o << "</abi-instr>\n";

  return true;
}

/// Serialize a pointer to an instance of basic type declaration, into
/// an output stream.
///
/// @param d the basic type declaration to serialize.
///
/// @param ctxt the context of the serialization.  It contains e.g, the
/// output stream to serialize to.
///
/// @param indent how many indentation spaces to use during the
/// serialization.
///
/// @return true upon successful completion, false otherwise.
static bool
write_type_decl(const type_decl_sptr& d, write_context& ctxt, unsigned indent)
{
  if (!d)
    return false;

  ostream& o = ctxt.get_ostream();

  annotate(d, ctxt, indent);

  do_indent(o, indent);

  o << "<type-decl name='" << xml::escape_xml_string(d->get_name()) << "'";

  write_is_anonymous(d, o);

  write_size_and_alignment(d, o);

  write_is_declaration_only(d, o);

  write_location(d, ctxt);

  o << " id='" << ctxt.get_id_for_type(d) << "'" <<  "/>\n";

  ctxt.record_type_as_emitted(d);

  return true;
}

/// Serialize a namespace declaration int an output stream.
///
/// @param decl the namespace declaration to serialize.
///
/// @param ctxt the context of the serialization.  It contains e.g, the
/// output stream to serialize to.
///
/// @param indent how many indentation spaces to use during the
/// serialization.
///
/// @return true upon successful completion, false otherwise.
static bool
write_namespace_decl(const namespace_decl_sptr& decl,
		     write_context& ctxt, unsigned indent)
{
  if (!decl || decl->is_empty_or_has_empty_sub_namespaces())
    return false;

  ostream& o = ctxt.get_ostream();
  const config &c = ctxt.get_config();

  annotate(decl, ctxt, indent);

  do_indent(o, indent);

  o << "<namespace-decl name='"
    << xml::escape_xml_string(decl->get_name())
    << "'>\n";

  typedef scope_decl::declarations		declarations;
  typedef declarations::const_iterator const_iterator;
  const declarations& d = decl->get_member_decls();

  write_canonical_types_of_scope(*decl, ctxt,
				 indent + c.get_xml_element_indent());

  for (const_iterator i = d.begin(); i != d.end(); ++i)
    {
      if (type_base_sptr t = is_type(*i))
	if (ctxt.type_is_emitted(t))
	  // This type has already been emitted to the current
	  // translation unit so do not emit it again.
	  continue;
      write_decl(*i, ctxt, indent + c.get_xml_element_indent());
    }

  do_indent(o, indent);
  o << "</namespace-decl>\n";

  return true;
}

/// Serialize a qualified type declaration to an output stream.
///
/// @param decl the qualfied type declaration to write.
///
/// @param id the type id identitifier to use in the serialized
/// output.  If this is empty, the function will compute an
/// appropriate one.  This is useful when this function is called to
/// serialize the underlying type of a member type; in that case, the
/// caller has already computed the id of the *member type*, and that
/// id is the one to be written as the value of the 'id' attribute of
/// the XML element of the underlying type.
///
/// @param ctxt the write context.
///
/// @param indent the number of space to indent to during the
/// serialization.
///
/// @return true upon successful completion, false otherwise.
static bool
write_qualified_type_def(const qualified_type_def_sptr&	decl,
			 const string&				id,
			 write_context&			ctxt,
			 unsigned				indent)
{
  if (!decl)
    return false;

  ostream& o = ctxt.get_ostream();


  type_base_sptr underlying_type = decl->get_underlying_type();

  annotate(decl, ctxt, indent);

  do_indent(o, indent);
  o << "<qualified-type-def type-id='"
    << ctxt.get_id_for_type(underlying_type)
    << "'";

  ctxt.record_type_as_referenced(underlying_type);

  if (decl->get_cv_quals() & qualified_type_def::CV_CONST)
    o << " const='yes'";
  if (decl->get_cv_quals() & qualified_type_def::CV_VOLATILE)
    o << " volatile='yes'";
  if (decl->get_cv_quals() & qualified_type_def::CV_RESTRICT)
    o << " restrict='yes'";

  write_location(static_pointer_cast<decl_base>(decl), ctxt);

  string i = id;
  if (i.empty())
    i = ctxt.get_id_for_type(decl);

  o << " id='" << i << "'/>\n";

  ctxt.record_type_as_emitted(decl);

  return true;
}

/// Serialize a qualified type declaration to an output stream.
///
/// @param decl the qualfied type declaration to write.
///
/// @param ctxt the write context.
///
/// @param indent the number of space to indent to during the
/// serialization.
///
/// @return true upon successful completion, false otherwise.
static bool
write_qualified_type_def(const qualified_type_def_sptr&	decl,
			 write_context&			ctxt,
			 unsigned				indent)
{return write_qualified_type_def(decl, "", ctxt, indent);}

/// Serialize a pointer to an instance of pointer_type_def.
///
/// @param decl the pointer_type_def to serialize.
///
/// @param id the type id identitifier to use in the serialized
/// output.  If this is empty, the function will compute an
/// appropriate one.  This is useful when this function is called to
/// serialize the underlying type of a member type; in that case, the
/// caller has already computed the id of the *member type*, and that
/// id is the one to be written as the value of the 'id' attribute of
/// the XML element of the underlying type.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the number of indentation white spaces to use.
///
/// @return true upon succesful completion, false otherwise.
static bool
write_pointer_type_def(const pointer_type_def_sptr&	decl,
		       const string&			id,
		       write_context&			ctxt,
		       unsigned			indent)
{
  if (!decl)
    return false;

  ostream& o = ctxt.get_ostream();


  type_base_sptr pointed_to_type = decl->get_pointed_to_type();

  annotate(decl->get_canonical_type(), ctxt, indent);

  do_indent(o, indent);
  o << "<pointer-type-def type-id='"
    << ctxt.get_id_for_type(pointed_to_type)
    << "'";

  ctxt.record_type_as_referenced(pointed_to_type);

  write_size_and_alignment(decl, o,
			   (ctxt.get_write_default_sizes()
			    ? 0
			    : decl->get_translation_unit()->get_address_size()),
			   0);

  string i = id;
  if (i.empty())
    i = ctxt.get_id_for_type(decl);

  o << " id='" << i << "'";

  write_location(static_pointer_cast<decl_base>(decl), ctxt);
  o << "/>\n";

  ctxt.record_type_as_emitted(decl);

  return true;
}

/// Serialize a pointer to an instance of pointer_type_def.
///
/// @param decl the pointer_type_def to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the number of indentation white spaces to use.
///
/// @return true upon succesful completion, false otherwise.
static bool
write_pointer_type_def(const pointer_type_def_sptr&	decl,
		       write_context&			ctxt,
		       unsigned			indent)
{return write_pointer_type_def(decl, "", ctxt, indent);}

/// Serialize a pointer to an instance of reference_type_def.
///
/// @param decl the reference_type_def to serialize.
///
/// @param id the type id identitifier to use in the serialized
/// output.  If this is empty, the function will compute an
/// appropriate one.  This is useful when this function is called to
/// serialize the underlying type of a member type; in that case, the
/// caller has already computed the id of the *member type*, and that
/// id is the one to be written as the value of the 'id' attribute of
/// the XML element of the underlying type.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the number of indentation white spaces to use.
///
/// @return true upon succesful completion, false otherwise.
static bool
write_reference_type_def(const reference_type_def_sptr&	decl,
			 const string&				id,
			 write_context&			ctxt,
			 unsigned				indent)
{
  if (!decl)
    return false;

  annotate(decl->get_canonical_type(), ctxt, indent);

  ostream& o = ctxt.get_ostream();

  do_indent(o, indent);

  o << "<reference-type-def kind='";
  if (decl->is_lvalue())
    o << "lvalue";
  else
    o << "rvalue";
  o << "'";

  type_base_sptr pointed_to_type = decl->get_pointed_to_type();
  o << " type-id='" << ctxt.get_id_for_type(pointed_to_type) << "'";

  ctxt.record_type_as_referenced(pointed_to_type);

  if (function_type_sptr f = is_function_type(decl->get_pointed_to_type()))
    ctxt.record_type_as_referenced(f);

  write_size_and_alignment(decl, o,
			   (ctxt.get_write_default_sizes()
			    ? 0
			    : decl->get_translation_unit()->get_address_size()),
			   0);

  string i = id;
  if (i.empty())
    i = ctxt.get_id_for_type(decl);
  o << " id='" << i << "'";

  write_location(static_pointer_cast<decl_base>(decl), ctxt);

  o << "/>\n";

  ctxt.record_type_as_emitted(decl);

  return true;
}

/// Serialize a pointer to an instance of reference_type_def.
///
/// @param decl the reference_type_def to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the number of indentation white spaces to use.
///
/// @return true upon succesful completion, false otherwise.
static bool
write_reference_type_def(const reference_type_def_sptr&	decl,
			 write_context&			ctxt,
			 unsigned				indent)
{return write_reference_type_def(decl, "", ctxt, indent);}

/// Serialize an instance of @ref array_type_def::subrange_type.
///
/// @param decl the array_type_def::subrange_type to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the number of indentation white spaces to use.
///
/// return true upon successful completion, false otherwise.
static bool
write_array_subrange_type(const array_type_def::subrange_sptr&	decl,
			  write_context&			ctxt,
			  unsigned				indent)
{
  if (!decl)
    return false;

  annotate(decl, ctxt, indent);

  ostream& o = ctxt.get_ostream();

  do_indent(o, indent);

  o << "<subrange";

  if (!decl->get_name().empty())
    o << " name='" << decl->get_name() << "'";

  o << " length='";
  if (decl->is_infinite())
    o << "infinite";
  else
    o << decl->get_length();

  o << "'";

  if (decl->get_lower_bound())
    {
      ABG_ASSERT(decl->is_infinite()
		 || (decl->get_length() ==
		     (uint64_t) (decl->get_upper_bound()
				 - decl->get_lower_bound() + 1)));
      o << " lower-bound='" << decl->get_lower_bound() << "' upper-bound='"
	<< decl->get_upper_bound() << "'";
    }

  type_base_sptr underlying_type = decl->get_underlying_type();
  if (underlying_type)
    {
      o << " type-id='"
	<< ctxt.get_id_for_type(underlying_type)
	<< "'";
      ctxt.record_type_as_referenced(underlying_type);
    }

  o << " id='" << ctxt.get_id_for_type(decl) << "'";

  write_location(decl->get_location(), ctxt);

  o << "/>\n";

  return true;
}

/// Serialize a pointer to an instance of array_type_def.
///
/// @param decl the array_type_def to serialize.
///
/// @param id the type id identitifier to use in the serialized
/// output.  If this is empty, the function will compute an
/// appropriate one.  This is useful when this function is called to
/// serialize the underlying type of a member type; in that case, the
/// caller has already computed the id of the *member type*, and that
/// id is the one to be written as the value of the 'id' attribute of
/// the XML element of the underlying type.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the number of indentation white spaces to use.
///
/// @return true upon succesful completion, false otherwise.
static bool
write_array_type_def(const array_type_def_sptr&	decl,
		     const string&			id,
		     write_context&			ctxt,
		     unsigned				indent)
{
  if (!decl)
    return false;

  annotate(decl, ctxt, indent);

  ostream& o = ctxt.get_ostream();

  do_indent(o, indent);
  o << "<array-type-def";

  o << " dimensions='" << decl->get_dimension_count() << "'";

  type_base_sptr element_type = decl->get_element_type();
  o << " type-id='" << ctxt.get_id_for_type(element_type) << "'";

  ctxt.record_type_as_referenced(element_type);

  write_array_size_and_alignment(decl, o);

  string i = id;
  if (i.empty())
    i = ctxt.get_id_for_type(decl);
  o << " id='" << i << "'";

  write_location(static_pointer_cast<decl_base>(decl), ctxt);

  if (!decl->get_dimension_count())
    o << "/>\n";
  else
    {
      o << ">\n";

      vector<array_type_def::subrange_sptr>::const_iterator si;

      for (si = decl->get_subranges().begin();
           si != decl->get_subranges().end(); ++si)
        {
	  unsigned local_indent =
	    indent + ctxt.get_config().get_xml_element_indent();
	  write_array_subrange_type(*si, ctxt, local_indent);
	}

      do_indent(o, indent);
      o << "</array-type-def>\n";
    }

  ctxt.record_type_as_emitted(decl);

  return true;
}

/// Serialize a pointer to an instance of array_type_def.
///
/// @param decl the array_type_def to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the number of indentation white spaces to use.
///
/// @return true upon succesful completion, false otherwise.
static bool
write_array_type_def(const array_type_def_sptr& decl,
		     write_context&		ctxt,
		     unsigned			indent)
{return write_array_type_def(decl, "", ctxt, indent);}

/// Serialize a pointer to an instance of enum_type_decl.
///
/// @param decl the enum_type_decl to serialize.
///
/// @param id the type id identitifier to use in the serialized
/// output.  If this is empty, the function will compute an
/// appropriate one.  This is useful when this function is called to
/// serialize the underlying type of a member type; in that case, the
/// caller has already computed the id of the *member type*, and that
/// id is the one to be written as the value of the 'id' attribute of
/// the XML element of the underlying type.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the number of indentation white spaces to use.
///
/// @return true upon succesful completion, false otherwise.
static bool
write_enum_type_decl(const enum_type_decl_sptr& decl,
		     const string&		id,
		     write_context&		ctxt,
		     unsigned			indent)
{
  if (!decl)
    return false;

  annotate(decl->get_canonical_type(), ctxt, indent);

  ostream& o = ctxt.get_ostream();

  do_indent(o, indent);
  o << "<enum-decl name='" << xml::escape_xml_string(decl->get_name()) << "'";

  write_is_anonymous(decl, o);
  write_is_artificial(decl, o);
  write_is_non_reachable(is_type(decl), o);

  if (!decl->get_linkage_name().empty())
    o << " linkage-name='" << decl->get_linkage_name() << "'";

  write_location(decl, ctxt);
  write_is_declaration_only(decl, o);

  string i = id;
  if (i.empty())
    i = ctxt.get_id_for_type(decl);
  o << " id='" << i << "'>\n";

  do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
  o << "<underlying-type type-id='"
    << ctxt.get_id_for_type(decl->get_underlying_type())
    << "'/>\n";

  for (enum_type_decl::enumerators::const_iterator i =
	 decl->get_enumerators().begin();
       i != decl->get_enumerators().end();
       ++i)
    {
      do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
      o << "<enumerator name='"
	<< i->get_name()
	<< "' value='"
	<< i->get_value()
	<< "'/>\n";
    }

  do_indent(o, indent);
  o << "</enum-decl>\n";

  ctxt.record_type_as_emitted(decl);

  return true;
}

/// Serialize a pointer to an instance of enum_type_decl.
///
/// @param decl the enum_type_decl to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the number of indentation white spaces to use.
///
/// @return true upon succesful completion, false otherwise.
static bool
write_enum_type_decl(const enum_type_decl_sptr& decl,
		     write_context&		ctxt,
		     unsigned			indent)
{return write_enum_type_decl(decl, "", ctxt, indent);}

/// Serialize an @ref elf_symbol to an XML element of name
/// 'elf-symbol'.
///
/// @param sym the elf symbol to serialize.
///
/// @param ctxt the read context to use.
///
/// @param indent the number of white spaces to use as indentation.
///
/// @return true iff the function completed successfully.
static bool
write_elf_symbol(const elf_symbol_sptr&	sym,
		 write_context&		ctxt,
		 unsigned			indent)
{
  if (!sym)
    return false;

  ostream &o = ctxt.get_ostream();

  annotate(sym, ctxt, indent);
  do_indent(o, indent);
  o << "<elf-symbol name='" << sym->get_name() << "'";
  if (sym->is_variable() && sym->get_size())
  o << " size='" << sym->get_size() << "'";

  if (!sym->get_version().is_empty())
    {
      o << " version='" << sym->get_version().str() << "'";
      o << " is-default-version='";
      if (sym->get_version().is_default())
	o <<  "yes";
      else
	o << "no";
      o << "'";
    }

  write_elf_symbol_type(sym->get_type(), o);

  write_elf_symbol_binding(sym->get_binding(), o);

  write_elf_symbol_visibility(sym->get_visibility(), o);

  write_elf_symbol_aliases(*sym, o);

  o << " is-defined='";
  if (sym->is_defined())
    o << "yes";
  else
    o << "no";
  o << "'";

  if (sym->is_common_symbol())
    o << " is-common='yes'";

  o << "/>\n";

  return true;
}

/// Write the elf symbol database to the output associated to the
/// current context.
///
/// @param syms the sorted elf symbol data to write out.
///
/// @param ctxt the context to consider.
///
/// @param indent the number of white spaces to use as indentation.
///
/// @return true upon successful completion.
static bool
write_elf_symbols_table(const elf_symbols&	syms,
			write_context&		ctxt,
			unsigned		indent)
{
  if (syms.empty())
    return false;

  unordered_map<string, bool> emitted_syms;
  for (elf_symbols::const_iterator it = syms.begin(); it != syms.end(); ++it)
    write_elf_symbol(*it, ctxt, indent);

  return true;
}

/// Write a vector of dependency names for the current corpus we are
/// writting.
///
/// @param needed the vector of dependency names to write.
///
/// @param ctxt the write context to use for the writting.
///
/// @param indent the number of indendation spaces to use.
///
/// @return true upon successful completion, false otherwise.
static bool
write_elf_needed(const vector<string>&	needed,
		 write_context&	ctxt,
		 unsigned		indent)
{
  if (needed.empty())
    return false;

  ostream& o = ctxt.get_ostream();

  for (vector<string>::const_iterator i = needed.begin();
       i != needed.end();
       ++i)
    {
      do_indent(o, indent);
      o << "<dependency name='" << *i << "'/>\n";
    }
  return true;
}

/// Serialize a pointer to an instance of typedef_decl.
///
/// @param decl the typedef_decl to serialize.
///
/// @param id the type id identitifier to use in the serialized
/// output.  If this is empty, the function will compute an
/// appropriate one.  This is useful when this function is called to
/// serialize the underlying type of a member type; in that case, the
/// caller has already computed the id of the *member type*, and that
/// id is the one to be written as the value of the 'id' attribute of
/// the XML element of the underlying type.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the number of indentation white spaces to use.
///
/// @return true upon succesful completion, false otherwise.
static bool
write_typedef_decl(const typedef_decl_sptr&	decl,
		   const string&		id,
		   write_context&		ctxt,
		   unsigned			indent)
{
  if (!decl)
    return false;

  ostream &o = ctxt.get_ostream();

  annotate(decl, ctxt, indent);

  do_indent(o, indent);

  o << "<typedef-decl name='"
    << xml::escape_xml_string(decl->get_name())
    << "'";

  type_base_sptr underlying_type = decl->get_underlying_type();
  string type_id = ctxt.get_id_for_type(underlying_type);
  o << " type-id='" <<  type_id << "'";
  ctxt.record_type_as_referenced(underlying_type);

  write_location(decl, ctxt);

  string i = id;
  if (i.empty())
    i = ctxt.get_id_for_type(decl);

  o << " id='" << i << "'/>\n";

  ctxt.record_type_as_emitted(decl);

  return true;
}

/// Serialize a pointer to an instance of typedef_decl.
///
/// @param decl the typedef_decl to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the number of indentation white spaces to use.
///
/// @return true upon succesful completion, false otherwise.
static bool
write_typedef_decl(const typedef_decl_sptr&	decl,
		   write_context&		ctxt,
		   unsigned			indent)
{return write_typedef_decl(decl, "", ctxt, indent);}

/// Serialize a pointer to an instances of var_decl.
///
/// @param decl the var_decl to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param write_linkage_name if true, serialize the mangled name of
/// this variable.
///
/// @param indent the number of indentation white spaces to use.
///
/// @return true upon succesful completion, false otherwise.
static bool
write_var_decl(const var_decl_sptr& decl, write_context& ctxt,
	       bool write_linkage_name, unsigned indent)
{
  if (!decl)
    return false;

  annotate(decl, ctxt, indent);

  ostream &o = ctxt.get_ostream();

  do_indent(o, indent);

  o << "<var-decl name='" << xml::escape_xml_string(decl->get_name()) << "'";
  type_base_sptr var_type = decl->get_type();
  o << " type-id='" << ctxt.get_id_for_type(var_type) << "'";
  ctxt.record_type_as_referenced(var_type);

  if (write_linkage_name)
    {
      const string& linkage_name = decl->get_linkage_name();
      if (!linkage_name.empty())
	o << " mangled-name='" << linkage_name << "'";
    }

  write_visibility(decl, o);

  write_binding(decl, o);

  write_location(decl, ctxt);

  write_elf_symbol_reference(decl->get_symbol(), o);

  o << "/>\n";

  ctxt.record_decl_as_emitted(decl);

  return true;
}

/// Serialize a pointer to a function_decl.
///
/// @param decl the pointer to function_decl to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param skip_first_parm if true, do not serialize the first
/// parameter of the function decl.
///
/// @param indent the number of indentation white spaces to use.
///
/// @return true upon succesful completion, false otherwise.
static bool
write_function_decl(const function_decl_sptr& decl, write_context& ctxt,
		    bool skip_first_parm, unsigned indent)
{
  if (!decl)
    return false;

  annotate(decl, ctxt, indent);

  ostream &o = ctxt.get_ostream();

  do_indent(o, indent);

  o << "<function-decl name='"
    << xml::escape_xml_string(decl->get_name())
    << "'";

  if (!decl->get_linkage_name().empty())
    o << " mangled-name='"
      << xml::escape_xml_string(decl->get_linkage_name()) << "'";

  write_location(decl, ctxt);

  if (decl->is_declared_inline())
    o << " declared-inline='yes'";

  write_visibility(decl, o);

  write_binding(decl, o);

  write_size_and_alignment(decl->get_type(), o,
			   (ctxt.get_write_default_sizes()
			    ? 0
			    : decl->get_translation_unit()->get_address_size()),
			   0);
  write_elf_symbol_reference(decl->get_symbol(), o);

  o << ">\n";

  type_base_sptr parm_type;
  vector<shared_ptr<function_decl::parameter> >::const_iterator pi =
    decl->get_parameters().begin();
  for ((skip_first_parm && pi != decl->get_parameters().end()) ? ++pi: pi;
       pi != decl->get_parameters().end();
       ++pi)
    {
      if ((*pi)->get_variadic_marker())
        {
          do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
          o << "<parameter is-variadic='yes'";
        }
      else
	{
	  parm_type = (*pi)->get_type();

          annotate(*pi, ctxt,
		   indent + ctxt.get_config().get_xml_element_indent());

          do_indent(o, indent + ctxt.get_config().get_xml_element_indent());

	  o << "<parameter type-id='"
	    << ctxt.get_id_for_type(parm_type)
	    << "'";
	  ctxt.record_type_as_referenced(parm_type);

	  if (ctxt.get_write_parameter_names() && !(*pi)->get_name().empty())
	    o << " name='" << (*pi)->get_name() << "'";
	}
      write_is_artificial(*pi, o);
      write_location((*pi)->get_location(), ctxt);
      o << "/>\n";
    }

  if (shared_ptr<type_base> return_type = decl->get_return_type())
    {
      annotate(return_type , ctxt,
	       indent + ctxt.get_config().get_xml_element_indent());
      do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
      o << "<return type-id='" << ctxt.get_id_for_type(return_type) << "'/>\n";
      ctxt.record_type_as_referenced(return_type);
    }

  do_indent(o, indent);
  o << "</function-decl>\n";

  ctxt.record_decl_as_emitted(decl);

  return true;
}

/// Serialize a function_type.
///
/// @param decl the pointer to function_type to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the number of indentation white spaces to use.
///
/// @return true upon succesful completion, false otherwise.
static bool
write_function_type(const function_type_sptr& fn_type,
		    write_context& ctxt, unsigned indent)
{
  if (!fn_type)
    return false;

  ostream &o = ctxt.get_ostream();

  annotate(fn_type, ctxt, indent);

  do_indent(o, indent);

  o << "<function-type";

  write_size_and_alignment(fn_type, o,
			   (ctxt.get_write_default_sizes()
			    ? 0
			    : fn_type->get_translation_unit()->get_address_size()),
			   0);

  if (method_type_sptr method_type = is_method_type(fn_type))
    {
      o << " method-class-id='"
	<< ctxt.get_id_for_type(method_type->get_class_type())
	<< "'";

      write_cdtor_const_static(/*is_ctor=*/false, /*is_dtor=*/false,
			       /*is_const=*/method_type->get_is_const(),
			       /*is_static=*/false, o);
    }

  interned_string id = ctxt.get_id_for_type(fn_type);

  o << " id='"
    <<  id << "'"
    << ">\n";

  type_base_sptr parm_type;
  for (vector<function_decl::parameter_sptr>::const_iterator pi =
	 fn_type->get_parameters().begin();
       pi != fn_type->get_parameters().end();
       ++pi)
    {

      if ((*pi)->get_variadic_marker())
        {
          do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
          o << "<parameter is-variadic='yes'";
        }
      else
	{
	  parm_type = (*pi)->get_type();

          annotate(*pi, ctxt, indent + ctxt.get_config().get_xml_element_indent());

          do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
	  o << "<parameter type-id='"
	    << ctxt.get_id_for_type(parm_type)
	    << "'";
	  ctxt.record_type_as_referenced(parm_type);

	  if (!(*pi)->get_name().empty())
	    {
	      string name = xml::escape_xml_string((*pi)->get_name());
	      o << " name='" << name << "'";
	    }
	}
      write_is_artificial(*pi, o);
      o << "/>\n";
    }

  if (type_base_sptr return_type = fn_type->get_return_type())
    {
      annotate(return_type, ctxt, indent + ctxt.get_config().get_xml_element_indent());
      do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
      o << "<return type-id='" << ctxt.get_id_for_type(return_type) << "'/>\n";
      ctxt.record_type_as_referenced(return_type);
    }

  do_indent(o, indent);
  o << "</function-type>\n";

  ctxt.record_type_as_emitted(fn_type);
  return true;
}

/// Write the opening tag of a 'class-decl' element.
///
/// @param decl the class declaration to serialize.
///
/// @param the type ID to use for the 'class-decl' element,, or empty
/// if we need to build a new one.
///
/// @param ctxt the write context to use.
///
/// @param indent the number of white space to use for indentation.
///
/// @param prepare_to_handle_members if set to true, then this function
/// figures out if the opening tag should be for an empty element or
/// not.  If set to false, then the opening tag is unconditionnaly for
/// a non-empty element.
///
/// @return true upon successful completion.
static bool
write_class_decl_opening_tag(const class_decl_sptr&	decl,
			     const string&		id,
			     write_context&		ctxt,
			     unsigned			indent,
			     bool			prepare_to_handle_members)
{
  if (!decl)
    return false;

  ostream& o = ctxt.get_ostream();

  do_indent_to_level(ctxt, indent, 0);

  o << "<class-decl name='" << xml::escape_xml_string(decl->get_name()) << "'";

  write_size_and_alignment(decl, o);

  write_is_struct(decl, o);

  write_is_anonymous(decl, o);

  write_is_artificial(decl, o);

  write_is_non_reachable(is_type(decl), o);

  write_naming_typedef(decl, ctxt);

  write_visibility(decl, o);

  write_location(decl, ctxt);

  write_is_declaration_only(decl, o);

  if (decl->get_earlier_declaration())
    {
      // This instance is the definition of an earlier declaration.
      o << " def-of-decl-id='"
	<< ctxt.get_id_for_type(is_type(decl->get_earlier_declaration()))
	<< "'";
    }

  string i = id;
  if (i.empty())
    i = ctxt.get_id_for_type(decl);
  o << " id='" << i << "'";

  if (prepare_to_handle_members && decl->has_no_base_nor_member())
    o << "/>\n";
  else
    o << ">\n";

  return true;
}

/// Write the opening tag of a 'union-decl' element.
///
/// @param decl the union declaration to serialize.
///
/// @param the type ID to use for the 'union-decl' element, or empty
/// if we need to build a new one.
///
/// @param ctxt the write context to use.
///
/// @param indent the number of white space to use for indentation.
///
/// @param prepare_to_handle_members if set to true, then this function
/// figures out if the opening tag should be for an empty element or
/// not.  If set to false, then the opening tag is unconditionnaly for
/// a non-empty element.
///
/// @return true upon successful completion.
static bool
write_union_decl_opening_tag(const union_decl_sptr&	decl,
			     const string&		id,
			     write_context&		ctxt,
			     unsigned			indent,
			     bool			prepare_to_handle_members)
{
  if (!decl)
    return false;

  ostream& o = ctxt.get_ostream();

  do_indent_to_level(ctxt, indent, 0);

  o << "<union-decl name='" << xml::escape_xml_string(decl->get_name()) << "'";

  if (!decl->get_is_declaration_only())
    write_size_and_alignment(decl, o);

  write_is_anonymous(decl, o);

  write_visibility(decl, o);

  write_is_artificial(decl, o);

  write_is_non_reachable(is_type(decl), o);

  write_location(decl, ctxt);

  write_is_declaration_only(decl, o);

  string i = id;
  if (i.empty())
    i = ctxt.get_id_for_type(decl);
  o << " id='" << i << "'";

  if (prepare_to_handle_members && decl->has_no_member())
    o << "/>\n";
  else
    o << ">\n";

  return true;
}

/// Serialize a class_decl type.
///
/// @param d the pointer to class_decl to serialize.
///
/// @param id the type id identitifier to use in the serialized
/// output.  If this is empty, the function will compute an
/// appropriate one.  This is useful when this function is called to
/// serialize the underlying type of a member type; in that case, the
/// caller has already computed the id of the *member type*, and that
/// id is the one to be written as the value of the 'id' attribute of
/// the XML element of the underlying type.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the initial indentation to use.
static bool
write_class_decl(const class_decl_sptr& d,
		 const string&		id,
		 write_context&	ctxt,
		 unsigned		indent)
{
  if (!d)
    return false;

  class_decl_sptr decl = is_class_type(look_through_decl_only_class(d));

  annotate(decl, ctxt, indent);

  ostream& o = ctxt.get_ostream();

  write_class_decl_opening_tag(decl, id, ctxt, indent,
			       /*prepare_to_handle_members=*/true);

  if (!decl->has_no_base_nor_member())
    {
      unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
      type_base_sptr base_type;
      for (class_decl::base_specs::const_iterator base =
	     decl->get_base_specifiers().begin();
	   base != decl->get_base_specifiers().end();
	   ++base)
	{
	  annotate((*base)->get_base_class(), ctxt, nb_ws);
	  do_indent(o, nb_ws);
	  o << "<base-class";

	  write_access((*base)->get_access_specifier(), o);

	  write_layout_offset (*base, o);

	  if ((*base)->get_is_virtual ())
	    o << " is-virtual='yes'";

	  base_type = (*base)->get_base_class();
	  o << " type-id='"
	    << ctxt.get_id_for_type(base_type)
	    << "'/>\n";

	  ctxt.record_type_as_referenced(base_type);
	}

      write_canonical_types_of_scope(*decl, ctxt, nb_ws,
				     /*is_member_type=*/true);

      for (class_decl::member_types::const_iterator ti =
	     decl->get_member_types().begin();
	   ti != decl->get_member_types().end();
	   ++ti)
	if (!(*ti)->get_naked_canonical_type())
	  write_member_type(*ti, ctxt, nb_ws);

      for (class_decl::data_members::const_iterator data =
	     decl->get_data_members().begin();
	   data != decl->get_data_members().end();
	   ++data)
	{
	  do_indent(o, nb_ws);
	  o << "<data-member";
	  write_access(get_member_access_specifier(*data), o);

	  bool is_static = get_member_is_static(*data);
	  write_cdtor_const_static(/*is_ctor=*/false,
				   /*is_dtor=*/false,
				   /*is_const=*/false,
				   /*is_static=*/is_static,
				   o);
	  write_layout_offset(*data, o);
	  o << ">\n";

	  write_var_decl(*data, ctxt, is_static,
			 get_indent_to_level(ctxt, indent, 2));

	  do_indent_to_level(ctxt, indent, 1);
	  o << "</data-member>\n";
	}

      for (class_decl::member_functions::const_iterator f =
	     decl->get_member_functions().begin();
	   f != decl->get_member_functions().end();
	   ++f)
	{
	  function_decl_sptr fn = *f;
	  if (get_member_function_is_virtual(fn))
	    // All virtual member functions are emitted together,
	    // later.
	    continue;

	  ABG_ASSERT(!get_member_function_is_virtual(fn));

	  do_indent(o, nb_ws);
	  o << "<member-function";
	  write_access(get_member_access_specifier(fn), o);
	  write_cdtor_const_static( get_member_function_is_ctor(fn),
				    get_member_function_is_dtor(fn),
				    get_member_function_is_const(fn),
				    get_member_is_static(fn),
				    o);
	  o << ">\n";

	  write_function_decl(fn, ctxt,
			      /*skip_first_parameter=*/false,
			      get_indent_to_level(ctxt, indent, 2));

	  do_indent_to_level(ctxt, indent, 1);
	  o << "</member-function>\n";
	}

      for (class_decl::member_functions::const_iterator f =
	     decl->get_virtual_mem_fns().begin();
	   f != decl->get_virtual_mem_fns().end();
	   ++f)
	{
	  function_decl_sptr fn = *f;

	  ABG_ASSERT(get_member_function_is_virtual(fn));

	  do_indent(o, nb_ws);
	  o << "<member-function";
	  write_access(get_member_access_specifier(fn), o);
	  write_cdtor_const_static( get_member_function_is_ctor(fn),
				    get_member_function_is_dtor(fn),
				    get_member_function_is_const(fn),
				    get_member_is_static(fn),
				    o);
	  write_voffset(fn, o);
	  o << ">\n";

	  write_function_decl(fn, ctxt,
			      /*skip_first_parameter=*/false,
			      get_indent_to_level(ctxt, indent, 2));

	  do_indent_to_level(ctxt, indent, 1);
	  o << "</member-function>\n";
	}

      for (member_function_templates::const_iterator fn =
	     decl->get_member_function_templates().begin();
	   fn != decl->get_member_function_templates().end();
	   ++fn)
	{
	  do_indent(o, nb_ws);
	  o << "<member-template";
	  write_access((*fn)->get_access_specifier(), o);
	  write_cdtor_const_static((*fn)->is_constructor(),
				   /*is_dtor=*/false,
				   (*fn)->is_const(),
				   (*fn)->get_is_static(), o);
	  o << ">\n";
	  write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
			       get_indent_to_level(ctxt, indent, 2));
	  do_indent(o, nb_ws);
	  o << "</member-template>\n";
	}

      for (member_class_templates::const_iterator cl =
	     decl->get_member_class_templates().begin();
	   cl != decl->get_member_class_templates().end();
	   ++cl)
	{
	  do_indent(o, nb_ws);
	  o << "<member-template";
	  write_access((*cl)->get_access_specifier(), o);
	  write_cdtor_const_static(false, false, false,
				   (*cl)->get_is_static(), o);
	  o << ">\n";
	  write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
			    get_indent_to_level(ctxt, indent, 2));
	  do_indent(o, nb_ws);
	  o << "</member-template>\n";
	}

      do_indent_to_level(ctxt, indent, 0);

      o << "</class-decl>\n";
    }

  // We allow several *declarations* of the same class in the corpus,
  // but only one definition.
  if (!decl->get_is_declaration_only())
    ctxt.record_type_as_emitted(decl);
  else
    ctxt.record_decl_only_type_as_emitted(decl);

  return true;
}

/// Serialize a class_decl type.
///
/// @param decl the pointer to class_decl to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the initial indentation to use.
///
/// @return true upon successful completion.
static bool
write_class_decl(const class_decl_sptr& decl,
		 write_context&	ctxt,
		 unsigned		indent)
{return write_class_decl(decl, "", ctxt, indent);}

/// Serialize a @ref union_decl type.
///
/// @param d the pointer to @ref union_decl to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the initial indentation to use.
///
/// @return true upon successful completion.
static bool
write_union_decl(const union_decl_sptr& d,
		 const string& id,
		 write_context& ctxt,
		 unsigned indent)
{
  if (!d)
    return false;

  union_decl_sptr decl = is_union_type(look_through_decl_only_class(d));

  annotate(decl, ctxt, indent);

  ostream& o = ctxt.get_ostream();

  write_union_decl_opening_tag(decl, id, ctxt, indent,
			       /*prepare_to_handle_members=*/true);
  if (!decl->has_no_member())
    {
      unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
      for (class_decl::member_types::const_iterator ti =
	     decl->get_member_types().begin();
	   ti != decl->get_member_types().end();
	   ++ti)
	write_member_type(*ti, ctxt, nb_ws);

      for (union_decl::data_members::const_iterator data =
	     decl->get_data_members().begin();
	   data != decl->get_data_members().end();
	   ++data)
	{
	  do_indent(o, nb_ws);
	  o << "<data-member";
	  write_access(get_member_access_specifier(*data), o);

	  bool is_static = get_member_is_static(*data);
	  write_cdtor_const_static(/*is_ctor=*/false,
				   /*is_dtor=*/false,
				   /*is_const=*/false,
				   /*is_static=*/is_static,
				   o);
	  o << ">\n";

	  write_var_decl(*data, ctxt, is_static,
			 get_indent_to_level(ctxt, indent, 2));

	  do_indent_to_level(ctxt, indent, 1);
	  o << "</data-member>\n";
	}

      for (union_decl::member_functions::const_iterator f =
	     decl->get_member_functions().begin();
	   f != decl->get_member_functions().end();
	   ++f)
	{
	  function_decl_sptr fn = *f;
	  if (get_member_function_is_virtual(fn))
	    // All virtual member functions are emitted together,
	    // later.
	    continue;

	  ABG_ASSERT(!get_member_function_is_virtual(fn));

	  do_indent(o, nb_ws);
	  o << "<member-function";
	  write_access(get_member_access_specifier(fn), o);
	  write_cdtor_const_static( get_member_function_is_ctor(fn),
				    get_member_function_is_dtor(fn),
				    get_member_function_is_const(fn),
				    get_member_is_static(fn),
				    o);
	  o << ">\n";

	  write_function_decl(fn, ctxt,
			      /*skip_first_parameter=*/false,
			      get_indent_to_level(ctxt, indent, 2));

	  do_indent_to_level(ctxt, indent, 1);
	  o << "</member-function>\n";
	}

      for (member_function_templates::const_iterator fn =
	     decl->get_member_function_templates().begin();
	   fn != decl->get_member_function_templates().end();
	   ++fn)
	{
	  do_indent(o, nb_ws);
	  o << "<member-template";
	  write_access((*fn)->get_access_specifier(), o);
	  write_cdtor_const_static((*fn)->is_constructor(),
				   /*is_dtor=*/false,
				   (*fn)->is_const(),
				   (*fn)->get_is_static(), o);
	  o << ">\n";
	  write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
			       get_indent_to_level(ctxt, indent, 2));
	  do_indent(o, nb_ws);
	  o << "</member-template>\n";
	}

      for (member_class_templates::const_iterator cl =
	     decl->get_member_class_templates().begin();
	   cl != decl->get_member_class_templates().end();
	   ++cl)
	{
	  do_indent(o, nb_ws);
	  o << "<member-template";
	  write_access((*cl)->get_access_specifier(), o);
	  write_cdtor_const_static(false, false, false,
				   (*cl)->get_is_static(), o);
	  o << ">\n";
	  write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
			    get_indent_to_level(ctxt, indent, 2));
	  do_indent(o, nb_ws);
	  o << "</member-template>\n";
	}

      do_indent_to_level(ctxt, indent, 0);

      o << "</union-decl>\n";
    }

  // We allow several *declarations* of the same union in the corpus,
  // but only one definition.
  if (!decl->get_is_declaration_only())
    ctxt.record_type_as_emitted(decl);
  else
    ctxt.record_decl_only_type_as_emitted(decl);

  return true;
}

static bool
write_union_decl(const union_decl_sptr& decl,
		 write_context& ctxt,
		 unsigned indent)
{return write_union_decl(decl, "", ctxt, indent);}

/// Write the opening tag for a 'member-type' element.
///
/// @param t the member type to consider.
///
/// @param ctxt the write context to use.
///
/// @param indent the number of white spaces to use for indentation.
///
/// @return true upon successful completion.
static bool
write_member_type_opening_tag(const type_base_sptr& t,
			      write_context& ctxt,
			      unsigned indent)
{
  ostream& o = ctxt.get_ostream();

  do_indent_to_level(ctxt, indent, 0);

  decl_base_sptr decl = get_type_declaration(t);
  ABG_ASSERT(decl);

  o << "<member-type";
  write_access(decl, o);
  o << ">\n";

  return true;
}

/// Serialize a member type.
///
/// Note that the id written as the value of the 'id' attribute of the
/// underlying type is actually the id of the member type, not the one
/// for the underying type.  That id takes in account, the access
/// specifier and the qualified name of the member type.
///
/// @param decl the declaration of the member type to serialize.
///
/// @param ctxt the write context to use.
///
/// @param indent the number of levels to use for indentation
static bool
write_member_type(const type_base_sptr& t, write_context& ctxt, unsigned indent)
{
  if (!t)
    return false;

  ostream& o = ctxt.get_ostream();

  write_member_type_opening_tag(t, ctxt, indent);

  string id = ctxt.get_id_for_type(t);

  unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
  ABG_ASSERT(write_qualified_type_def(dynamic_pointer_cast<qualified_type_def>(t),
				  id, ctxt, nb_ws)
	 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(t),
				   id, ctxt, nb_ws)
	 || write_reference_type_def(dynamic_pointer_cast<reference_type_def>(t),
				     id, ctxt, nb_ws)
	 || write_array_type_def(dynamic_pointer_cast<array_type_def>(t),
			         id, ctxt, nb_ws)
	 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(t),
				 id, ctxt, nb_ws)
	 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(t),
			       id, ctxt, nb_ws)
	 || write_union_decl(dynamic_pointer_cast<union_decl>(t),
			     id, ctxt, nb_ws)
	 || write_class_decl(dynamic_pointer_cast<class_decl>(t),
			     id, ctxt, nb_ws));

  do_indent_to_level(ctxt, indent, 0);
  o << "</member-type>\n";

  return true;
}

/// Serialize an instance of type_tparameter.
///
/// @param decl the instance to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the initial indentation to use.
///
/// @return true upon successful completion, false otherwise.
static bool
write_type_tparameter(const type_tparameter_sptr	decl,
		      write_context&			ctxt,
		      unsigned				indent)
{
  if (!decl)
    return false;

  ostream &o = ctxt.get_ostream();
  do_indent_to_level(ctxt, indent, 0);

  string id_attr_name;
  if (ctxt.type_has_existing_id(decl))
    id_attr_name = "type-id";
  else
    id_attr_name = "id";

  o << "<template-type-parameter "
    << id_attr_name << "='" <<  ctxt.get_id_for_type(decl) << "'";

  std::string name = xml::escape_xml_string(decl->get_name ());
  if (!name.empty())
    o << " name='" << name << "'";

  write_location(decl, ctxt);

  o << "/>\n";

  ctxt.record_type_as_emitted(decl);

  return true;
}

/// Serialize an instance of non_type_tparameter.
///
/// @param decl the instance to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the intial indentation to use.
///
/// @return true open successful completion, false otherwise.
static bool
write_non_type_tparameter(
 const shared_ptr<non_type_tparameter>	decl,
 write_context&	ctxt, unsigned indent)
{
  if (!decl)
    return false;

  ostream &o = ctxt.get_ostream();
  do_indent_to_level(ctxt, indent, 0);

  o << "<template-non-type-parameter type-id='"
    << ctxt.get_id_for_type(decl->get_type())
    << "'";

  string name = xml::escape_xml_string(decl->get_name());
  if (!name.empty())
    o << " name='" << name << "'";

  write_location(decl, ctxt);

  o << "/>\n";

  return true;
}

/// Serialize an instance of template template parameter.
///
/// @param decl the instance to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the initial indentation to use.
///
/// @return true upon successful completion, false otherwise.

static bool
write_template_tparameter (const template_tparameter_sptr	decl,
			   write_context&			ctxt,
			   unsigned				indent)
{
  if (!decl)
    return false;

  ostream& o = ctxt.get_ostream();
  do_indent_to_level(ctxt, indent, 0);

  string id_attr_name = "id";
  if (ctxt.type_has_existing_id(decl))
    id_attr_name = "type-id";

  o << "<template-template-parameter " << id_attr_name << "='"
    << ctxt.get_id_for_type(decl) << "'";

  string name = xml::escape_xml_string(decl->get_name());
  if (!name.empty())
    o << " name='" << name << "'";

  o << ">\n";

  unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
  for (list<shared_ptr<template_parameter> >::const_iterator p =
	 decl->get_template_parameters().begin();
       p != decl->get_template_parameters().end();
       ++p)
    write_template_parameter(decl, ctxt, nb_spaces);

  do_indent_to_level(ctxt, indent, 0);
  o << "</template-template-parameter>\n";

  ctxt.record_type_as_emitted(decl);

  return true;
}

/// Serialize an instance of type_composition.
///
/// @param decl the decl to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the initial indentation to use.
///
/// @return true upon successful completion, false otherwise.
static bool
write_type_composition
(const shared_ptr<type_composition> decl,
 write_context& ctxt, unsigned indent)
{
  if (!decl)
    return false;

  ostream& o = ctxt.get_ostream();

  do_indent_to_level(ctxt, indent, 0);

  o << "<template-parameter-type-composition>\n";

  unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
  (write_pointer_type_def
   (dynamic_pointer_cast<pointer_type_def>(decl->get_composed_type()),
			  ctxt, nb_spaces)
   || write_reference_type_def
   (dynamic_pointer_cast<reference_type_def>(decl->get_composed_type()),
    ctxt, nb_spaces)
   || write_array_type_def
   (dynamic_pointer_cast<array_type_def>(decl->get_composed_type()),
    ctxt, nb_spaces)
   || write_qualified_type_def
   (dynamic_pointer_cast<qualified_type_def>(decl->get_composed_type()),
    ctxt, nb_spaces));

  do_indent_to_level(ctxt, indent, 0);
  o << "</template-parameter-type-composition>\n";

  return true;
}

/// Serialize an instance of template_parameter.
///
/// @param decl the instance to serialize.
///
/// @param ctxt the context of the serialization.
///
/// @param indent the initial indentation to use.
///
/// @return true upon successful completion, false otherwise.
static bool
write_template_parameter(const shared_ptr<template_parameter> decl,
			 write_context& ctxt, unsigned indent)
{
  if ((!write_type_tparameter
       (dynamic_pointer_cast<type_tparameter>(decl), ctxt, indent))
      && (!write_non_type_tparameter
	  (dynamic_pointer_cast<non_type_tparameter>(decl),
	   ctxt, indent))
      && (!write_template_tparameter
	  (dynamic_pointer_cast<template_tparameter>(decl),
	   ctxt, indent))
      && (!write_type_composition
	  (dynamic_pointer_cast<type_composition>(decl),
	   ctxt, indent)))
    return false;

  return true;
}

/// Serialize the template parameters of the a given template.
///
/// @param tmpl the template for which to emit the template parameters.
static void
write_template_parameters(const shared_ptr<template_decl> tmpl,
			  write_context& ctxt, unsigned indent)
{
  if (!tmpl)
    return;

  unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
  for (list<shared_ptr<template_parameter> >::const_iterator p =
	 tmpl->get_template_parameters().begin();
       p != tmpl->get_template_parameters().end();
       ++p)
    write_template_parameter(*p, ctxt, nb_spaces);
}

/// Serialize an instance of function_tdecl.
///
/// @param decl the instance to serialize.
///
/// @param ctxt the context of the serialization
///
/// @param indent the initial indentation.
static bool
write_function_tdecl(const shared_ptr<function_tdecl> decl,
		     write_context& ctxt, unsigned indent)
{
  if (!decl)
    return false;

  ostream& o = ctxt.get_ostream();

  do_indent_to_level(ctxt, indent, 0);

  o << "<function-template-decl id='" << ctxt.get_id_for_fn_tmpl(decl) << "'";

  write_location(decl, ctxt);

  write_visibility(decl, o);

  write_binding(decl, o);

  o << ">\n";

  write_template_parameters(decl, ctxt, indent);

  write_function_decl(decl->get_pattern(), ctxt,
		      /*skip_first_parameter=*/false,
		      get_indent_to_level(ctxt, indent, 1));

  do_indent_to_level(ctxt, indent, 0);

  o << "</function-template-decl>\n";

  return true;
}


/// Serialize an instance of class_tdecl
///
/// @param decl a pointer to the instance of class_tdecl to serialize.
///
/// @param ctxt the context of the serializtion.
///
/// @param indent the initial number of white space to use for
/// indentation.
///
/// @return true upon successful completion, false otherwise.
static bool
write_class_tdecl(const shared_ptr<class_tdecl> decl,
		  write_context& ctxt, unsigned indent)
{
  if (!decl)
    return false;

  ostream& o = ctxt.get_ostream();

  do_indent_to_level(ctxt, indent, 0);

  o << "<class-template-decl id='" << ctxt.get_id_for_class_tmpl(decl) << "'";

  write_location(decl, ctxt);

  write_visibility(decl, o);

  o << ">\n";

  write_template_parameters(decl, ctxt, indent);

  write_class_decl(decl->get_pattern(), ctxt,
		   get_indent_to_level(ctxt, indent, 1));

  do_indent_to_level(ctxt, indent, 0);

  o << "</class-template-decl>\n";

  return true;
}

#ifdef WITH_ZIP_ARCHIVE

/// A context used by functions that write a corpus out to disk in a
/// ZIP archive of ABI Instrumentation XML files.
///
/// The aim of this context file is to hold the buffers of data that
/// are to be written into a given zip object, until the zip object is
/// closed.  It's at that point that the buffers data is really
/// flushed into the zip archive.
///
/// When an instance of this context type is created for a given zip
/// object, is created, its life time should be longer than the @ref
/// zip_sptr object it holds.
///
/// The definition of this type is private and should remain hidden
/// from client code.
struct archive_write_ctxt
{
  list<string> serialized_tus;
  zip_sptr archive;

  archive_write_ctxt(zip_sptr ar)
    : archive(ar)
  {}
};
typedef shared_ptr<archive_write_ctxt> archive_write_ctxt_sptr;

/// Create a write context to a given archive.  The result of this
/// function is to be passed to the functions that are to write a
/// corpus to an archive, e.g, write_corpus_to_archive().
///
/// @param archive_path the path to the archive to create this write
/// context for.
///
/// @return the resulting write context to pass to the functions that
/// are to write a corpus to @ref archive_path.
static archive_write_ctxt_sptr
create_archive_write_context(const string& archive_path)
{
  if (archive_path.empty())
    return archive_write_ctxt_sptr();

  int error_code = 0;
  zip_sptr archive = open_archive(archive_path,
				  ZIP_CREATE|ZIP_TRUNCATE|ZIP_CHECKCONS,
				  &error_code);
  if (error_code)
    return archive_write_ctxt_sptr();

  archive_write_ctxt_sptr r(new archive_write_ctxt(archive));
  return r;
}

/// Write a translation unit to an on-disk archive.  The archive is a
/// zip archive of ABI Instrumentation files in XML format.
///
/// @param tu the translation unit to serialize.
///
/// @param ctxt the context of the serialization.  Contains
/// information about where the archive is on disk, the zip archive,
/// and the buffers holding the temporary data to be flushed into the archive.
///
/// @param annotate whether ABIXML output should be annotated.
///
/// @return true upon succesful serialization occured, false
/// otherwise.
static bool
write_translation_unit_to_archive(const translation_unit& tu,
				  archive_write_ctxt& ctxt,
                                  const bool annotate)
{
  if (!ctxt.archive)
    return false;

  ostringstream os;
  if (!write_translation_unit(tu, /*indent=*/0, os, annotate))
    return false;
  ctxt.serialized_tus.push_back(os.str());

  zip_source *source;
  if ((source = zip_source_buffer(ctxt.archive.get(),
				  ctxt.serialized_tus.back().c_str(),
				  ctxt.serialized_tus.back().size(),
				  false)) == 0)
    return false;

  if (zip_file_add(ctxt.archive.get(), tu.get_path().c_str(), source,
		   ZIP_FL_OVERWRITE|ZIP_FL_ENC_GUESS) < 0)
    {
      zip_source_free(source);
      return false;
    }

  return true;
}

 /// Serialize a given corpus to disk in a file at a given path.
 ///
 /// @param tu the translation unit to serialize.
 ///
 /// @param ctxt the context of the serialization.  Contains
 /// information about where the archive is on disk, the zip archive
 /// object, and the buffers holding the temporary data to be flushed
 /// into the archive.
 ///
 /// @param annotate whether ABIXML output should be annotated.
 ///
 /// @return true upon successful completion, false otherwise.
static bool
write_corpus_to_archive(const corpus& corp,
			archive_write_ctxt& ctxt,
                        const bool annotate)
{
  for (translation_units::const_iterator i =
	 corp.get_translation_units().begin();
       i != corp.get_translation_units().end();
       ++i)
    {
      if (! write_translation_unit_to_archive(**i, ctxt, annotate))
	return false;
    }

  // TODO: ensure abi-info descriptor is added to the archive.
  return true;
}

/// Serialize a given corpus to disk in an archive file at a given
/// path.
///
/// @param corp the ABI corpus to serialize.
///
 /// @param ctxt the context of the serialization.  Contains
 /// information about where the archive is on disk, the zip archive
 /// object, and the buffers holding the temporary data to be flushed
 /// into the archive.
 ///
 /// @param annotate whether ABIXML output should be annotated.
 ///
 /// @return upon successful completion, false otherwise.
static bool
write_corpus_to_archive(const corpus& corp,
			archive_write_ctxt_sptr ctxt,
                        const bool annotate)
{return write_corpus_to_archive(corp, *ctxt, annotate);}

 /// Serialize the current corpus to disk in a file at a given path.
 ///
 /// @param tu the translation unit to serialize.
 ///
 /// @param path the path of the file to serialize the
 /// translation_unit to.
 ///
 /// @param annotate whether ABIXML output should be annotated.
 ///
 /// @return true upon successful completion, false otherwise.
bool
write_corpus_to_archive(const corpus& corp,
			const string& path,
                        const bool annotate)
{
  archive_write_ctxt_sptr ctxt = create_archive_write_context(path);
  ABG_ASSERT(ctxt);
  return write_corpus_to_archive(corp, ctxt, annotate);
}

 /// Serialize the current corpus to disk in a file.  The file path is
 /// given by translation_unit::get_path().
 ///
 /// @param tu the translation unit to serialize.
 ///
 /// @param annotate whether ABIXML output should be annotated.
 ///
 /// @return true upon successful completion, false otherwise.
bool
write_corpus_to_archive(const corpus& corp, const bool annotate)
{return write_corpus_to_archive(corp, corp.get_path(), annotate);}

 /// Serialize the current corpus to disk in a file.  The file path is
 /// given by translation_unit::get_path().
 ///
 /// @param tu the translation unit to serialize.
 ///
 /// @param annotate whether ABIXML output should be annotated.
 ///
 /// @return true upon successful completion, false otherwise.
bool
write_corpus_to_archive(const corpus_sptr corp, const bool annotate)
{return write_corpus_to_archive(*corp, annotate);}

#endif //WITH_ZIP_ARCHIVE

/// Serialize an ABI corpus to a single native xml document.  The root
/// note of the resulting XML document is 'abi-corpus'.
///
/// Note: If either corpus is null or corpus does not contain serializable
///       content (i.e. corpus.is_empty()), nothing is emitted to the ctxt's
///       output stream.
///
/// @param ctxt the write context to use.
///
/// @param corpus the corpus to serialize.
///
/// @param indent the number of white space indentation to use.
///
/// @return true upon successful completion, false otherwise.
bool
write_corpus(write_context&	ctxt,
	     const corpus_sptr& corpus,
	     unsigned		indent,
	     bool		member_of_group)
{
  if (!corpus)
    return false;

  if (corpus->is_empty())
    return true;

  do_indent_to_level(ctxt, indent, 0);

  std::ostream& out = ctxt.get_ostream();

  out << "<abi-corpus";

  // For an abi-corpus as part of an abi-corpus group, only omit the path, but
  // keep the filename.
  std::string corpus_path = corpus->get_path();
  if (!ctxt.get_write_corpus_path())
    {
      if (member_of_group)
	tools_utils::base_name(corpus_path, corpus_path);
      else
	corpus_path.clear();
    }
  else
    {
      if (ctxt.get_short_locs())
	tools_utils::base_name(corpus_path, corpus_path);
    }
  if (!corpus_path.empty())
    out << " path='" << xml::escape_xml_string(corpus_path) << "'";

  if (!corpus->get_architecture_name().empty()
      && ctxt.get_write_architecture())
    out << " architecture='" << corpus->get_architecture_name()<< "'";

  if (!corpus->get_soname().empty())
    out << " soname='" << corpus->get_soname()<< "'";

  write_tracking_non_reachable_types(corpus, out);

  out << ">\n";

  // Write the list of needed corpora.

  if (ctxt.get_write_elf_needed () && !corpus->get_needed().empty())
    {
      do_indent_to_level(ctxt, indent, 1);
      out << "<elf-needed>\n";
      write_elf_needed(corpus->get_needed(), ctxt,
		       get_indent_to_level(ctxt, indent, 2));
      do_indent_to_level(ctxt, indent, 1);
      out << "</elf-needed>\n";
    }

  // Write the function symbols data base.
  if (!corpus->get_fun_symbol_map().empty())
    {
      do_indent_to_level(ctxt, indent, 1);
      out << "<elf-function-symbols>\n";

      write_elf_symbols_table(corpus->get_sorted_fun_symbols(), ctxt,
			      get_indent_to_level(ctxt, indent, 2));

      do_indent_to_level(ctxt, indent, 1);
      out << "</elf-function-symbols>\n";
    }

  // Write the variable symbols data base.
  if (!corpus->get_var_symbol_map().empty())
    {
      do_indent_to_level(ctxt, indent, 1);
      out << "<elf-variable-symbols>\n";

      write_elf_symbols_table(corpus->get_sorted_var_symbols(), ctxt,
			      get_indent_to_level(ctxt, indent, 2));

      do_indent_to_level(ctxt, indent, 1);
      out << "</elf-variable-symbols>\n";
    }

  // Now write the translation units.
  for (translation_units::const_iterator i =
	 corpus->get_translation_units().begin();
       i != corpus->get_translation_units().end();
       ++i)
    {
      translation_unit& tu = **i;
      if (!tu.is_empty())
	write_translation_unit(ctxt, tu, get_indent_to_level(ctxt, indent, 1));
    }

  do_indent_to_level(ctxt, indent, 0);
  out << "</abi-corpus>\n";

  return true;
}

/// Serialize an ABI corpus group to a single native xml document.
/// The root note of the resulting XML document is 'abi-corpus-group'.
///
/// @param ctxt the write context to use.
///
/// @param group the corpus group to serialize.
///
/// @param indent the number of white space indentation to use.
///
/// @return true upon successful completion, false otherwise.
bool
write_corpus_group(write_context&	    ctxt,
		   const corpus_group_sptr& group,
		   unsigned		    indent)

{
  if (!group)
    return false;

  do_indent_to_level(ctxt, indent, 0);

std::ostream& out = ctxt.get_ostream();

  out << "<abi-corpus-group";

  if (!group->get_path().empty() && ctxt.get_write_corpus_path())
    out << " path='" << xml::escape_xml_string(group->get_path()) << "'";

  if (!group->get_architecture_name().empty() && ctxt.get_write_architecture())
    out << " architecture='" << group->get_architecture_name()<< "'";

  write_tracking_non_reachable_types(group, out);

  if (group->is_empty())
    {
      out << "/>\n";
      return true;
    }

  out << ">\n";

  // Write the list of corpora
  for (corpus_group::corpora_type::const_iterator c =
	 group->get_corpora().begin();
       c != group->get_corpora().end();
       ++c)
    write_corpus(ctxt, *c, get_indent_to_level(ctxt, indent, 1), true);

  do_indent_to_level(ctxt, indent, 0);
  out << "</abi-corpus-group>\n";

  return true;
}

} //end namespace xml_writer

// <Debugging routines>

using namespace abigail::ir;

/// Serialize a pointer to decl_base to an output stream.
///
/// @param d the pointer to decl_base to serialize.
///
/// @param o the output stream to consider.
///
/// @param annotate whether ABIXML output should be annotated.
void
dump(const decl_base_sptr d, std::ostream& o, const bool annotate)
{
  xml_writer::write_context ctxt(d->get_environment(), o);
  xml_writer::set_annotate(ctxt, annotate);
  write_decl(d, ctxt, /*indent=*/0);
}

/// Serialize a pointer to decl_base to stderr.
///
/// @param d the pointer to decl_base to serialize.
///
/// @param annotate whether ABIXML output should be annotated.
void
dump(const decl_base_sptr d, const bool annotate)
{dump(d, cerr, annotate);}

/// Serialize a pointer to type_base to an output stream.
///
/// @param t the pointer to type_base to serialize.
///
/// @param o the output stream to serialize the @ref type_base to.
///
/// @param annotate whether ABIXML output should be annotated.
void
dump(const type_base_sptr t, std::ostream& o, const bool annotate)
{dump(get_type_declaration(t), o, annotate);}

/// Serialize a pointer to type_base to stderr.
///
/// @param t the pointer to type_base to serialize.
///
/// @param annotate whether ABIXML output should be annotated.
void
dump(const type_base_sptr t, const bool annotate)
{dump(t, cerr, annotate);}

/// Serialize a pointer to var_decl to an output stream.
///
/// @param v the pointer to var_decl to serialize.
///
/// @param o the output stream to serialize the @ref var_decl to.
///
/// @param annotate whether ABIXML output should be annotated.
void
dump(const var_decl_sptr v, std::ostream& o, const bool annotate)
{
  xml_writer::write_context ctxt(v->get_environment(), o);
  xml_writer::set_annotate(ctxt, annotate);
  write_var_decl(v, ctxt, /*linkage_name*/true, /*indent=*/0);
}

/// Serialize a pointer to var_decl to stderr.
///
/// @param v the pointer to var_decl to serialize.
///
/// @param annotate whether ABIXML output should be annotated.
void
dump(const var_decl_sptr v, const bool annotate)
{dump(v, cerr, annotate);}

/// Serialize a @ref translation_unit to an output stream.
///
/// @param t the translation_unit to serialize.
///
/// @param o the outpout stream to serialize the translation_unit to.
///
/// @param annotate whether ABIXML output should be annotated.
void
dump(const translation_unit& t, std::ostream& o, const bool annotate)
{
  xml_writer::write_context ctxt(t.get_environment(), o);
  xml_writer::set_annotate(ctxt, annotate);
  write_translation_unit(ctxt, t, /*indent=*/0);
}

/// Serialize an instance of @ref translation_unit to stderr.
///
/// @param t the translation_unit to serialize.
void
dump(const translation_unit& t, const bool annotate)
{dump(t, cerr, annotate);}

/// Serialize a pointer to @ref translation_unit to an output stream.
///
/// @param t the @ref translation_unit_sptr to serialize.
///
/// @param o the output stream to serialize the translation unit to.
///
/// @param annotate whether ABIXML output should be annotated.
void
dump(const translation_unit_sptr t, std::ostream& o, const bool annotate)
{
  if (t)
    dump(*t, o, annotate);
}

/// Serialize a pointer to @ref translation_unit to stderr.
///
/// @param t the translation_unit_sptr to serialize.
///
/// @param annotate whether ABIXML output should be annotated.
void
dump(const translation_unit_sptr t, const bool annotate)
{
  if (t)
    dump(*t, annotate);
}

/// Serialize a source location to an output stream.
///
/// @param l the declaration to consider.
///
/// @param o the output stream to serialize to.
void
dump_location(const location& l, ostream& o)
{
  string path;
  unsigned line = 0, col = 0;

  l.expand(path, line, col);
  o << path << ":" << line << "," << col << "\n";
}

/// Serialize a source location for debugging purposes.
///
/// The location is serialized to the standard error output stream.
///
/// @param l the declaration to consider.
///
void
dump_location(const location& l)
{dump_location(l, cerr);}

/// Serialize the source location of a decl to an output stream for
/// debugging purposes.
///
/// @param d the declaration to consider.
///
/// @param o the output stream to serizalize the location to.
void
dump_decl_location(const decl_base& d, ostream& o)
{dump_location(d.get_location(), o);}

/// Serialize the source location of a decl to stderr for debugging
/// purposes.
///
/// @param d the declaration to consider.
void
dump_decl_location(const decl_base& d)
{dump_decl_location(d, cerr);}

/// Serialize the source location of a dcl to stderr for debugging
/// purposes.
///
/// @param d the declaration to consider.
void
dump_decl_location(const decl_base* d)
{
  if (d)
    dump_decl_location(*d);
}

/// Serialize the source location of a decl to stderr for debugging
/// purposes.
///
/// @param d the declaration to consider.
void
dump_decl_location(const decl_base_sptr d)
{dump_decl_location(d.get());}

// </Debugging routines>
} //end namespace abigail
