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


/// @file
///
/// This is the implementation of the
/// abigail::comparison::default_reporter type.

#include "abg-comparison-priv.h"
#include "abg-reporter.h"
#include "abg-reporter-priv.h"

namespace abigail
{
namespace comparison
{

/// Test if a given instance of @ref corpus_diff carries changes whose
/// reports are not suppressed by any suppression specification.  In
/// effect, these are deemed incompatible ABI changes.
///
/// @param d the @ref corpus_diff to consider
///
/// @return true iff @p d carries subtype changes that are deemed
/// incompatible ABI changes.
bool
default_reporter::diff_has_net_changes(const corpus_diff *d) const
{
  if (!d)
    return false;

  const corpus_diff::diff_stats& stats = const_cast<corpus_diff*>(d)->
    apply_filters_and_suppressions_before_reporting();

  // Logic here should match emit_diff_stats.
  return (d->architecture_changed()
	  || d->soname_changed()
	  || stats.net_num_func_removed()
	  || stats.net_num_func_changed()
	  || stats.net_num_func_added()
	  || stats.net_num_vars_removed()
	  || stats.net_num_vars_changed()
	  || stats.net_num_vars_added()
	  || stats.net_num_removed_unreachable_types()
	  || stats.net_num_changed_unreachable_types()
	  || stats.net_num_added_unreachable_types()
	  || stats.net_num_removed_func_syms()
	  || stats.net_num_added_func_syms()
	  || stats.net_num_removed_var_syms()
	  || stats.net_num_added_var_syms());
}

/// Ouputs a report of the differences between of the two type_decl
/// involved in the @ref type_decl_diff.
///
/// @param d the @ref type_decl_diff to consider.
///
/// @param out the output stream to emit the report to.
///
/// @param indent the string to use for indentatino indent.
void
default_reporter::report(const type_decl_diff& d,
			 ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  type_decl_sptr f = d.first_type_decl(), s = d.second_type_decl();

  string name = f->get_pretty_representation();

  report_name_size_and_alignment_changes(f, s, d.context(),
					 out, indent);

  if (f->get_visibility() != s->get_visibility())
    {
      out << indent
	  << "visibility changed from '"
	  << f->get_visibility() << "' to '" << s->get_visibility()
	  << "\n";
    }

  if (f->get_linkage_name() != s->get_linkage_name())
    {
      out << indent
	  << "mangled name changed from '"
	  << f->get_linkage_name() << "' to "
	  << s->get_linkage_name()
	  << "\n";
    }
}

/// Report the differences between the two enums.
///
/// @param d the enum diff to consider.
///
/// @param out the output stream to send the report to.
///
/// @param indent the string to use for indentation.
void
default_reporter::report(const enum_diff& d, ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER3(d.first_subject(),
						   d.second_subject(),
						   "enum type");

  string name = d.first_enum()->get_pretty_representation();

  enum_type_decl_sptr first = d.first_enum(), second = d.second_enum();

  const diff_context_sptr& ctxt = d.context();

  // Report enum decl-only <-> definition changes.
  if (ctxt->get_allowed_category() & TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY)
    if (filtering::has_enum_decl_only_def_change(first, second))
      {
	string was =
	  first->get_is_declaration_only()
	  ? " was a declaration-only enum type"
	  : " was a defined enum type";

	string is_now =
	  second->get_is_declaration_only()
	  ? " and is now a declaration-only enum type"
	  : " and is now a defined enum type";

	out << indent << "enum type " << name << was << is_now << "\n";
	return;
      }

  report_name_size_and_alignment_changes(first, second, ctxt,
					 out, indent);
  maybe_report_diff_for_member(first, second, ctxt, out, indent);

  //underlying type
  d.underlying_type_diff()->report(out, indent);

  //report deletions/insertions/change of enumerators
  unsigned numdels = d.deleted_enumerators().size();
  unsigned numins = d.inserted_enumerators().size();
  unsigned numchanges = d.changed_enumerators().size();

  if (numdels)
    {
      report_mem_header(out, numdels, 0, del_kind, "enumerator", indent);
      enum_type_decl::enumerators sorted_deleted_enumerators;
      sort_enumerators(d.deleted_enumerators(), sorted_deleted_enumerators);
      for (enum_type_decl::enumerators::const_iterator i =
	     sorted_deleted_enumerators.begin();
	   i != sorted_deleted_enumerators.end();
	   ++i)
	{
	  out << indent
	      << "  '"
	      << (first->get_is_anonymous()
		  ? i->get_name()
		  : i->get_qualified_name())
	      << "' value '"
	      << i->get_value()
	      << "'";
	  out << "\n";
	}
    }
  if (numins)
    {
      report_mem_header(out, numins, 0, ins_kind, "enumerator", indent);
      enum_type_decl::enumerators sorted_inserted_enumerators;
      sort_enumerators(d.inserted_enumerators(), sorted_inserted_enumerators);
      for (enum_type_decl::enumerators::const_iterator i =
	     sorted_inserted_enumerators.begin();
	   i != sorted_inserted_enumerators.end();
	   ++i)
	{
	  out << indent
	      << "  '"
	      << (second->get_is_anonymous()
		  ? i->get_name()
		  :i->get_qualified_name())
	      << "' value '"
	      << i->get_value()
	      << "'";
	  out << "\n";
	}
    }
  if (numchanges)
    {
      report_mem_header(out, numchanges, 0, change_kind, "enumerator", indent);
      changed_enumerators_type sorted_changed_enumerators;
      sort_changed_enumerators(d.changed_enumerators(),
			       sorted_changed_enumerators);
      for (changed_enumerators_type::const_iterator i =
	     sorted_changed_enumerators.begin();
	   i != sorted_changed_enumerators.end();
	   ++i)
	{
	  out << indent
	      << "  '"
	      << (first->get_is_anonymous()
		  ? i->first.get_name()
		  : i->first.get_qualified_name())
	      << "' from value '"
	      << i->first.get_value() << "' to '"
	      << i->second.get_value() << "'";
	  report_loc_info(second, *ctxt, out);
	  out << "\n";
	}
    }

  if (ctxt->show_leaf_changes_only())
    maybe_report_interfaces_impacted_by_diff(&d, out, indent);

  d.reported_once(true);
}

/// For a @ref typedef_diff node, report the local changes to the
/// typedef rather the changes to its underlying type.
///
/// Note that changes to the underlying type are also considered
/// local.
///
/// @param d the @ref typedef_diff node to consider.
///
/// @param out the output stream to report to.
///
/// @param indent the white space string to use for indentation.
void
default_reporter::report_non_type_typedef_changes(const typedef_diff &d,
						  ostream& out,
						  const string& indent) const
{
  if (!d.to_be_reported())
    return;

  typedef_decl_sptr f = d.first_typedef_decl(), s = d.second_typedef_decl();

  maybe_report_diff_for_member(f, s, d.context(), out, indent);

  if ((filtering::has_harmless_name_change(f, s)
       && ((d.context()->get_allowed_category()
	    & HARMLESS_DECL_NAME_CHANGE_CATEGORY)
	   || d.context()->show_leaf_changes_only()))
      || f->get_qualified_name() != s->get_qualified_name())
    {
      out << indent << "typedef name changed from "
	  << f->get_qualified_name()
	  << " to "
	  << s->get_qualified_name();
      report_loc_info(s, *d.context(), out);
      out << "\n";
    }
}

/// Reports the difference between the two subjects of the diff in a
/// serialized form.
///
/// @param d @ref typedef_diff node to consider.
///
/// @param out the output stream to emit the report to.
///
/// @param indent the indentation string to use.
void
default_reporter::report(const typedef_diff& d,
			 ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  typedef_decl_sptr f = d.first_typedef_decl(), s = d.second_typedef_decl();

  if (!d.is_filtered_out_without_looking_at_allowed_changes())
    report_non_type_typedef_changes(d, out, indent);

  diff_sptr dif = d.underlying_type_diff();
  if (dif && dif->has_changes())
    {
      if (dif->to_be_reported())
	{
	  RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2(dif,
							    "underlying type");
	  out << indent
	      << "underlying type '"
	      << dif->first_subject()->get_pretty_representation() << "'";
	  report_loc_info(dif->first_subject(), *d.context(), out);
	  out << " changed:\n";
	  dif->report(out, indent + "  ");
	}
      else
	{
	  // The typedef change is to be reported, so we'll report its
	  // underlying type change too (even if its redundant),
	  // unless it's suppressed.  It makes sense in this
	  // particular case to emit the underlying type change
	  // because of the informative value underneath.  We don't
	  // want to just know about the local changes of the typedef,
	  // but also about the changes on the underlying type.
	  diff_category c = dif->get_category();
	  if (!(c & (SUPPRESSED_CATEGORY | PRIVATE_TYPE_CATEGORY)))
	    {
	      out << indent
		  << "underlying type '"
		  << dif->first_subject()->get_pretty_representation() << "'";
	      report_loc_info(dif->first_subject(), *d.context(), out);
	      out << " changed:\n";
	      if (c & REDUNDANT_CATEGORY)
		dif->set_category(c & ~REDUNDANT_CATEGORY);
	      dif->report(out, indent + "  ");
	      if (c & REDUNDANT_CATEGORY)
		dif->set_category(c | REDUNDANT_CATEGORY);
	    }
	}
    }

  d.reported_once(true);
}

/// For a @ref qualified_type_diff node, report the changes that are
/// local.
///
/// @param d the @ref qualified_type_diff node to consider.
///
/// @param out the output stream to emit the report to.
///
/// @param indent the white string to use for indentation.
///
/// @return true iff a local change has been emitted.  In this case,
/// the local change is a name change.
bool
default_reporter::report_local_qualified_type_changes(const qualified_type_diff& d,
						      ostream& out,
						      const string& indent) const
{
  if (!d.to_be_reported())
    return false;

  string fname = d.first_qualified_type()->get_pretty_representation(),
    sname = d.second_qualified_type()->get_pretty_representation();

  if (fname != sname)
    {
      out << indent << "'" << fname << "' changed to '" << sname << "'\n";
      return true;
    }
  return false;
}

/// For a @ref qualified_type_diff node, report the changes of its
/// underlying type.
///
/// @param d the @ref qualified_type_diff node to consider.
///
/// @param out the output stream to emit the report to.
///
/// @param indent the white string to use for indentation.
///
/// @return true iff a local change has been emitted.  In this case,
/// the local change is a name change.
void
default_reporter::report_underlying_changes_of_qualified_type
(const qualified_type_diff& d, ostream& out, const string& indent) const
{
  if (!d.to_be_reported())
    return;

  diff_sptr dif = d.leaf_underlying_type_diff();
  ABG_ASSERT(dif);
  ABG_ASSERT(dif->to_be_reported());
  RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2(dif,
						    "unqualified "
						    "underlying type");

  string fltname = dif->first_subject()->get_pretty_representation();
  out << indent << "in unqualified underlying type '" << fltname << "'";
  report_loc_info(dif->second_subject(), *d.context(), out);
  out << ":\n";
  dif->report(out, indent + "  ");
}

/// Report a @ref qualified_type_diff in a serialized form.
///
/// @param d the @ref qualified_type_diff node to consider.
///
/// @param out the output stream to serialize to.
///
/// @param indent the string to use to indent the lines of the report.
void
default_reporter::report(const qualified_type_diff& d, ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER(d.first_qualified_type(),
						   d.second_qualified_type());

  if (!d.is_filtered_out_without_looking_at_allowed_changes())
    if (report_local_qualified_type_changes(d, out, indent))
      // The local change was emitted and it's a name change.  If the
      // type name changed, the it means the type changed altogether.
      // It makes a little sense to detail the changes in extenso here.
      return;

  report_underlying_changes_of_qualified_type(d, out, indent);
}

/// Report the @ref pointer_diff in a serialized form.
///
/// @param d the @ref pointer_diff node to consider.
///
/// @param out the stream to serialize the diff to.
///
/// @param indent the prefix to use for the indentation of this
/// serialization.
void
default_reporter::report(const pointer_diff& d, ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  if (diff_sptr dif = d.underlying_type_diff())
    {
      RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2(dif, "pointed to type");
      string repr = dif->first_subject()
	? dif->first_subject()->get_pretty_representation()
	: string("void");

      out << indent
	  << "in pointed to type '" << repr << "'";
      report_loc_info(dif->second_subject(), *d.context(), out);
      out << ":\n";
      dif->report(out, indent + "  ");
    }
}

/// For a @reference_diff node, report the local changes carried by
/// the diff node.
///
/// @param d the @reference_diff node to consider.
///
/// @param out the output stream to report to.
///
/// @param indent the white space indentation to use in the report.
void
default_reporter::report_local_reference_type_changes(const reference_diff& d,
						      ostream& out,
						      const string& indent) const
{
  if (!d.to_be_reported())
    return;

  reference_type_def_sptr f = d.first_reference(), s = d.second_reference();
  ABG_ASSERT(f && s);

  string f_repr = f->get_pretty_representation(),
    s_repr = s->get_pretty_representation();

  if (f->is_lvalue() != s->is_lvalue())
    {
      out << indent;
      if (f->is_lvalue())
	out << "lvalue reference type '" << f_repr
	    << " became an rvalue reference type: '"
	    << s_repr
	    << "'\n";
      else
	out << "rvalue reference type '" << f_repr
	    << " became an lvalue reference type: '"
	    << s_repr
	    << "'\n";
    }
  else if (!types_have_similar_structure(f->get_pointed_to_type().get(),
					 s->get_pointed_to_type().get()))
    out << indent
	<< "reference type changed from: '"
	<< f_repr << "' to: '" << s_repr << "'\n";
}

/// Report a @ref reference_diff in a serialized form.
///
/// @param d the @ref reference_diff node to consider.
///
/// @param out the output stream to serialize the dif to.
///
/// @param indent the string to use for indenting the report.
void
default_reporter::report(const reference_diff& d, ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  enum change_kind k = ir::NO_CHANGE_KIND;
  equals(*d.first_reference(), *d.second_reference(), &k);

  if (!d.is_filtered_out_without_looking_at_allowed_changes())
    if ((k & ALL_LOCAL_CHANGES_MASK) && !(k & SUBTYPE_CHANGE_KIND))
      report_local_reference_type_changes(d, out, indent);

  if (k & SUBTYPE_CHANGE_KIND)
    if (diff_sptr dif = d.underlying_type_diff())
      {
	RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2(dif,
							  "referenced type");

	out << indent
	    << "in referenced type '"
	    << dif->first_subject()->get_pretty_representation() << "'";
	report_loc_info(dif->second_subject(), *d.context(), out);
	out << ":\n";
	dif->report(out, indent + "  ");
      }
}

/// Report the local changes carried by a @ref ptr_to_mbr_diff diff
/// node.
///
/// This is a subroutine of the method default_reporter::report() that
/// emits change report for @ref ptr_to_mbr_diff node.
///
/// @param d the diff node to consider
///
/// @param out the output stream to emit the report to.
///
/// @param indent the indentation string (spaces) to use in the
/// report.
///
/// @return truf iff a report was emitted to the output stream.
bool
default_reporter::report_local_ptr_to_mbr_type_changes(const ptr_to_mbr_diff& d,
						       std::ostream& out,
						       const std::string& indent) const
{
  if (!d.to_be_reported())
    return false;

  ptr_to_mbr_type_sptr f = d.first_ptr_to_mbr_type(),
    s = d.second_ptr_to_mbr_type();

  enum change_kind k = ir::NO_CHANGE_KIND;
  equals(*d.first_ptr_to_mbr_type(), *d.second_ptr_to_mbr_type(), &k);

  if (k & ALL_LOCAL_CHANGES_MASK)
    {
      string f_repr = f->get_pretty_representation(),
	s_repr = s->get_pretty_representation();

      out << indent;
      out << "pointer-to-member type changed from: '"
	  << f_repr << " to: '"<< s_repr << "'\n";
      return true;
    }
  return false;
}


/// Emit a textual report about the changes carried by a @ref
/// ptr_to_mbr_diff diff node.
///
/// @param out the output stream to emit the report to.
///
/// @param indent the indentation string to use for the report.
void
default_reporter::report(const ptr_to_mbr_diff& d,
			 std::ostream& out,
			 const std::string& indent) const
{
  if (!d.to_be_reported())
    return;

  report_local_ptr_to_mbr_type_changes(d, out, indent);

  if (diff_sptr dif = d.member_type_diff())
    {
      RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2
	(dif,"data member type of pointer-to-member");
      if (dif->to_be_reported())
	{
	  out << indent
	      << "in data member type '"
	      << dif->first_subject()->get_pretty_representation()
	      << "' of pointed-to-member type '"
	      << d.first_ptr_to_mbr_type()->get_pretty_representation()
	      << "'";
	  report_loc_info(dif->second_subject(), *d.context(), out);
	  out << ":\n";
	  dif->report(out, indent + "  ");
	}
    }
  if (diff_sptr dif = d.containing_type_diff())
    {
      RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2
	(dif,"containing type of pointer-to-member");
      if (dif->to_be_reported())
	{
	  out << indent
	      << "in containing type '"
	      << dif->first_subject()->get_pretty_representation()
	      << "' of pointed-to-member type '"
	      << d.first_ptr_to_mbr_type()->get_pretty_representation()
	      << "'";
	  report_loc_info(dif->second_subject(), *d.context(), out);
	  out << ":\n";
	  dif->report(out, indent + "  ");
	}
    }
}

/// Emit a textual report about the a @ref fn_parm_diff instance.
///
/// @param d the @ref fn_parm_diff to consider.
///
/// @param out the output stream to emit the textual report to.
///
/// @param indent the indentation string to use in the report.
void
default_reporter::report(const fn_parm_diff& d, ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  function_decl::parameter_sptr f = d.first_parameter(),
    s = d.second_parameter();

  // either the parameter has a sub-type change (if its type name
  // hasn't changed) or it has a "grey" change (that is, a change that
  // changes his type name w/o changing the signature of the
  // function).
  bool has_sub_type_change =
    type_has_sub_type_changes(d.first_parameter()->get_type(),
			      d.second_parameter()->get_type());

  diff_sptr type_diff = d.type_diff();
  ABG_ASSERT(type_diff->has_changes());

  out << indent;
  if (f->get_is_artificial())
    out << "implicit ";
  out << "parameter " << f->get_index();
  report_loc_info(f, *d.context(), out);
  out << " of type '"
      << f->get_type_pretty_representation();

  if (has_sub_type_change)
    out << "' has sub-type changes:\n";
  else
    out << "' changed:\n";

  type_diff->report(out, indent + "  ");
}

/// For a @ref function_type_diff node, report the local changes
/// carried by the diff node.
///
/// @param d the @ref function_type_diff node to consider.
///
/// @param out the output stream to report to.
///
/// @param indent the white space indentation string to use.
void
default_reporter::report_local_function_type_changes(const function_type_diff& d,
						     ostream& out,
						     const string& indent) const

{
  if (!d.to_be_reported())
    return;

  function_type_sptr fft = d.first_function_type();
  function_type_sptr sft = d.second_function_type();

  diff_context_sptr ctxt = d.context();

  // Report about the size of the function address
  if (fft->get_size_in_bits() != sft->get_size_in_bits())
    {
      out << indent << "address size of function changed from "
	  << fft->get_size_in_bits()
	  << " bits to "
	  << sft->get_size_in_bits()
	  << " bits\n";
    }

  // Report about the alignment of the function address
  if (fft->get_alignment_in_bits()
      != sft->get_alignment_in_bits())
    {
      out << indent << "address alignment of function changed from "
	  << fft->get_alignment_in_bits()
	  << " bits to "
	  << sft->get_alignment_in_bits()
	  << " bits\n";
    }

  // Hmmh, the above was quick.  Now report about function parameters;
  // this shouldn't be as straightforward.

  // Report about the parameters that got removed.
  for (vector<function_decl::parameter_sptr>::const_iterator i =
	 d.priv_->sorted_deleted_parms_.begin();
       i != d.priv_->sorted_deleted_parms_.end();
       ++i)
    {
      out << indent << "parameter " << (*i)->get_index()
	  << " of type '" << (*i)->get_type_pretty_representation()
	  << "' was removed\n";
    }

  // Report about the parameters that got added
  for (vector<function_decl::parameter_sptr>::const_iterator i =
	 d.priv_->sorted_added_parms_.begin();
       i != d.priv_->sorted_added_parms_.end();
       ++i)
    {
      out << indent << "parameter " << (*i)->get_index()
	  << " of type '" << (*i)->get_type_pretty_representation()
	  << "' was added\n";
    }
}

/// Build and emit a textual report about a @ref function_type_diff.
///
/// @param d the @ref function_type_diff to consider.
///
/// @param out the output stream.
///
/// @param indent the indentation string to use.
void
default_reporter::report(const function_type_diff& d, ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  function_type_sptr fft = d.first_function_type();
  function_type_sptr sft = d.second_function_type();

  diff_context_sptr ctxt = d.context();
  corpus_sptr fc = ctxt->get_first_corpus();
  corpus_sptr sc = ctxt->get_second_corpus();

  // Report about return type differences.
  if (d.priv_->return_type_diff_
      && d.priv_->return_type_diff_->to_be_reported())
    {
      out << indent << "return type changed:\n";
      d.priv_->return_type_diff_->report(out, indent + "  ");
    }

  // Report about the parameter types that have changed sub-types.
  for (vector<fn_parm_diff_sptr>::const_iterator i =
	 d.priv_->sorted_subtype_changed_parms_.begin();
       i != d.priv_->sorted_subtype_changed_parms_.end();
       ++i)
    {
      diff_sptr dif = *i;
      if (dif && dif->to_be_reported())
	dif->report(out, indent);
    }

  if (!d.is_filtered_out_without_looking_at_allowed_changes())
    report_local_function_type_changes(d, out, indent);
}

/// Report about the change carried by a @ref subrange_diff diff node
/// in a serialized form.
///
/// @param d the diff node to consider.
///
/// @param out the output stream to report to.
///
/// @param indent the indentation string to use in the report.
void
default_reporter::report(const subrange_diff& d, std::ostream& out,
			 const std::string& indent) const
{
  if (!diff_to_be_reported(&d))
    return;

  RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER3(d.first_subrange(),
						    d.second_subrange(),
						    "range type");

  represent(d, d.context(), out,indent, /*local_only=*/false);
}

/// Report a @ref array_diff in a serialized form.
///
/// @param d the @ref array_diff to consider.
///
/// @param out the output stream to serialize the dif to.
///
/// @param indent the string to use for indenting the report.
void
default_reporter::report(const array_diff& d, ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  string name = d.first_array()->get_pretty_representation();
  RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER3(d.first_array(),
						    d.second_array(),
						    "array type");

  diff_sptr dif = d.element_type_diff();
  if (dif->to_be_reported())
    {
      string fn = ir::get_pretty_representation(is_type(dif->first_subject()));
      // report array element type changes
      out << indent << "array element type '"
	  << fn << "' changed:\n";
      dif->report(out, indent + "  ");
    }

  if (!d.is_filtered_out_without_looking_at_allowed_changes())
    report_name_size_and_alignment_changes(d.first_array(),
					   d.second_array(),
					   d.context(),
					   out, indent);
}

/// Generates a report for an intance of @ref base_diff.
///
/// @param d the @ref base_diff to consider.
///
/// @param out the output stream to send the report to.
///
/// @param indent the string to use for indentation.
void
default_reporter::report(const base_diff& d, ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  class_decl::base_spec_sptr f = d.first_base(), s = d.second_base();
  string repr = f->get_base_class()->get_pretty_representation();
  bool emitted = false;

  if (!d.is_filtered_out_without_looking_at_allowed_changes())
    {
      if (f->get_is_static() != s->get_is_static())
	{
	  if (f->get_is_static())
	    out << indent << "is no more static";
	  else
	    out << indent << "now becomes static";
	  emitted = true;
	}

      if ((d.context()->get_allowed_category() & ACCESS_CHANGE_CATEGORY)
	  && (f->get_access_specifier() != s->get_access_specifier()))
	{
	  if (emitted)
	    out << ", ";

	  out << "has access changed from '"
	      << f->get_access_specifier()
	      << "' to '"
	      << s->get_access_specifier()
	      << "'";

	  emitted = true;
	}
    }
  if (class_diff_sptr dif = d.get_underlying_class_diff())
    {
      if (dif->to_be_reported())
	{
	  if (emitted)
	    out << "\n";
	  dif->report(out, indent);
	}
    }
}

/// Report the changes carried by a @ref scope_diff.
///
/// @param d the @ref scope_diff to consider.
///
/// @param out the out stream to report the changes to.
///
/// @param indent the string to use for indentation.
void
default_reporter::report(const scope_diff& d, ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  // Report changed types.
  unsigned num_changed_types = d.changed_types().size();
  if (num_changed_types == 0)
    ;
  else if (num_changed_types == 1)
    out << indent << "1 changed type:\n";
  else
    out << indent << num_changed_types << " changed types:\n";

  for (diff_sptrs_type::const_iterator dif = d.changed_types().begin();
       dif != d.changed_types().end();
       ++dif)
    {
      if (!*dif)
	continue;

      out << indent << "  '"
	  << (*dif)->first_subject()->get_pretty_representation()
	  << "' changed:\n";
      (*dif)->report(out, indent + "    ");
    }

  // Report changed decls
  unsigned num_changed_decls = d.changed_decls().size();
  if (num_changed_decls == 0)
    ;
  else if (num_changed_decls == 1)
    out << indent << "1 changed declaration:\n";
  else
    out << indent << num_changed_decls << " changed declarations:\n";

  for (diff_sptrs_type::const_iterator dif= d.changed_decls().begin();
       dif != d.changed_decls().end ();
       ++dif)
    {
      if (!*dif)
	continue;

      out << indent << "  '"
	  << (*dif)->first_subject()->get_pretty_representation()
	  << "' was changed to '"
	  << (*dif)->second_subject()->get_pretty_representation() << "'";
      report_loc_info((*dif)->second_subject(), *d.context(), out);
      out << ":\n";

      (*dif)->report(out, indent + "    ");
    }

  // Report removed types/decls
  for (string_decl_base_sptr_map::const_iterator i =
	 d.priv_->deleted_types_.begin();
       i != d.priv_->deleted_types_.end();
       ++i)
    out << indent
	<< "  '"
	<< i->second->get_pretty_representation()
	<< "' was removed\n";

  if (d.priv_->deleted_types_.size())
    out << "\n";

  for (string_decl_base_sptr_map::const_iterator i =
	 d.priv_->deleted_decls_.begin();
       i != d.priv_->deleted_decls_.end();
       ++i)
    out << indent
	<< "  '"
	<< i->second->get_pretty_representation()
	<< "' was removed\n";

  if (d.priv_->deleted_decls_.size())
    out << "\n";

  // Report added types/decls
  bool emitted = false;
  for (string_decl_base_sptr_map::const_iterator i =
	 d.priv_->inserted_types_.begin();
       i != d.priv_->inserted_types_.end();
       ++i)
    {
      // Do not report about type_decl as these are usually built-in
      // types.
      if (dynamic_pointer_cast<type_decl>(i->second))
	continue;
      out << indent
	  << "  '"
	  << i->second->get_pretty_representation()
	  << "' was added\n";
      emitted = true;
    }

  if (emitted)
    out << "\n";

  emitted = false;
  for (string_decl_base_sptr_map::const_iterator i =
	 d.priv_->inserted_decls_.begin();
       i != d.priv_->inserted_decls_.end();
       ++i)
    {
      // Do not report about type_decl as these are usually built-in
      // types.
      if (dynamic_pointer_cast<type_decl>(i->second))
	continue;
      out << indent
	  << "  '"
	  << i->second->get_pretty_representation()
	  << "' was added\n";
      emitted = true;
    }

  if (emitted)
    out << "\n";
}

/// Report the changes carried by a @ref class_or_union_diff node in a
/// textual format.
///
/// @param d the @ref class_or_union_diff node to consider.
///
/// @param out the output stream to write the textual report to.
///
/// @param indent the number of white space to use as indentation.
void
default_reporter::report(const class_or_union_diff& d,
			 ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  class_or_union_sptr first = d.first_class_or_union(),
    second = d.second_class_or_union();

  const diff_context_sptr& ctxt = d.context();

  // Report class decl-only <-> definition change.
  if (ctxt->get_allowed_category() & TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY)
    if (filtering::has_class_decl_only_def_change(first, second))
      {
	string was =
	  first->get_is_declaration_only()
	  ? " was a declaration-only type"
	  : " was a defined type";

	string is_now =
	  second->get_is_declaration_only()
	  ? " and is now a declaration-only type"
	  : " and is now a defined type";

	out << indent << "type " << first->get_pretty_representation()
	    << was << is_now << "\n";
	return;
      }

  // member functions
  if (d.member_fns_changes())
    {
      // report deletions
      int numdels = d.get_priv()->deleted_member_functions_.size();
      size_t num_filtered =
	d.get_priv()->count_filtered_deleted_mem_fns(ctxt);
      if (numdels)
	report_mem_header(out, numdels, num_filtered, del_kind,
			  "member function", indent);
      for (class_or_union::member_functions::const_iterator i =
	     d.get_priv()->sorted_deleted_member_functions_.begin();
	   i != d.get_priv()->sorted_deleted_member_functions_.end();
	   ++i)
	{
	  if (!(ctxt->get_allowed_category()
		& NON_VIRT_MEM_FUN_CHANGE_CATEGORY)
	      && !get_member_function_is_virtual(*i))
	    continue;

	  method_decl_sptr mem_fun = *i;
	  out << indent << "  ";
	  represent(*ctxt, mem_fun, out);
	}

      // report insertions;
      int numins = d.get_priv()->inserted_member_functions_.size();
      num_filtered = d.get_priv()->count_filtered_inserted_mem_fns(ctxt);
      if (numins)
	report_mem_header(out, numins, num_filtered, ins_kind,
			  "member function", indent);
      for (class_or_union::member_functions::const_iterator i =
	     d.get_priv()->sorted_inserted_member_functions_.begin();
	   i != d.get_priv()->sorted_inserted_member_functions_.end();
	   ++i)
	{
	  if (!(ctxt->get_allowed_category()
		& NON_VIRT_MEM_FUN_CHANGE_CATEGORY)
	      && !get_member_function_is_virtual(*i))
	    continue;

	  method_decl_sptr mem_fun = *i;
	  out << indent << "  ";
	  represent(*ctxt, mem_fun, out);
	}

      // report member function with sub-types changes
      int numchanges = d.get_priv()->sorted_changed_member_functions_.size();
      num_filtered = d.get_priv()->count_filtered_changed_mem_fns(ctxt);
      if (numchanges)
	report_mem_header(out, numchanges, num_filtered, change_kind,
			  "member function", indent);
      for (function_decl_diff_sptrs_type::const_iterator i =
	     d.get_priv()->sorted_changed_member_functions_.begin();
	   i != d.get_priv()->sorted_changed_member_functions_.end();
	   ++i)
	{
	  if (!(ctxt->get_allowed_category()
		& NON_VIRT_MEM_FUN_CHANGE_CATEGORY)
	      && !(get_member_function_is_virtual
		   ((*i)->first_function_decl()))
	      && !(get_member_function_is_virtual
		   ((*i)->second_function_decl())))
	    continue;

	  diff_sptr diff = *i;
	  if (!diff || !diff->to_be_reported())
	    continue;

	  string repr =
	    (*i)->first_function_decl()->get_pretty_representation();
	  out << indent << "  '" << repr << "' has some sub-type changes:\n";
	  diff->report(out, indent + "    ");
	}
    }

  // data members
  if (d.data_members_changes())
    {
      // report deletions
      int numdels = d.class_or_union_diff::get_priv()->
	get_deleted_non_static_data_members_number();
      if (numdels)
	{
	  report_mem_header(out, numdels, 0, del_kind,
			    "data member", indent);
	  vector<decl_base_sptr> sorted_dms;
	  sort_data_members
	    (d.class_or_union_diff::get_priv()->deleted_data_members_,
	     sorted_dms);
	  for (vector<decl_base_sptr>::const_iterator i = sorted_dms.begin();
	       i != sorted_dms.end();
	       ++i)
	    {
	      var_decl_sptr data_mem =
		dynamic_pointer_cast<var_decl>(*i);
	      ABG_ASSERT(data_mem);
	      if (get_member_is_static(data_mem))
		continue;
	      represent_data_member(data_mem, ctxt, out, indent + "  ");
	    }
	}

      //report insertions
      int numins =
	d.class_or_union_diff::get_priv()->inserted_data_members_.size();
      if (numins)
	{
	  report_mem_header(out, numins, 0, ins_kind,
			    "data member", indent);
	  vector<decl_base_sptr> sorted_dms;
	  sort_data_members
	    (d.class_or_union_diff::get_priv()->inserted_data_members_,
	     sorted_dms);
	  for (vector<decl_base_sptr>::const_iterator i = sorted_dms.begin();
	       i != sorted_dms.end();
	       ++i)
	    {
	      var_decl_sptr data_mem =
		dynamic_pointer_cast<var_decl>(*i);
	      ABG_ASSERT(data_mem);
	      represent_data_member(data_mem, ctxt, out, indent + "  ");
	    }
	}

      // report change
      size_t num_changes =
	(d.sorted_subtype_changed_data_members().size()
	 + d.sorted_changed_data_members().size());

      size_t num_changes_filtered =
	(d.count_filtered_subtype_changed_data_members()
	 + d.count_filtered_changed_data_members());

      if (num_changes)
	{
	  report_mem_header(out, num_changes, num_changes_filtered,
			    change_kind, "data member", indent);

	  for (var_diff_sptrs_type::const_iterator it =
		 d.sorted_changed_data_members().begin();
	       it != d.sorted_changed_data_members().end();
	       ++it)
	    if ((*it)->to_be_reported())
	      represent(*it, ctxt, out, indent + "  ");

	  for (var_diff_sptrs_type::const_iterator it =
		 d.sorted_subtype_changed_data_members().begin();
	       it != d.sorted_subtype_changed_data_members().end();
	       ++it)
	    if ((*it)->to_be_reported())
	      represent(*it, ctxt, out, indent + "  ");
	}

      // Report about data members replaced by an anonymous union data
      // member.
      maybe_report_data_members_replaced_by_anon_dm(d, out, indent);
    }

  // member types
  if (const edit_script& e = d.member_types_changes())
    {
      int numchanges =
	d.class_or_union_diff::get_priv()->sorted_changed_member_types_.size();
      int numdels =
	d.class_or_union_diff::get_priv()->deleted_member_types_.size();

      // report deletions
      if (numdels)
	{
	  report_mem_header(out, numdels, 0, del_kind,
			    "member type", indent);

	  for (string_decl_base_sptr_map::const_iterator i =
		 d.class_or_union_diff::get_priv()->deleted_member_types_.begin();
	       i != d.class_or_union_diff::get_priv()->deleted_member_types_.end();
	       ++i)
	    {
	      decl_base_sptr mem_type = i->second;
	      out << indent << "  '"
		  << mem_type->get_pretty_representation()
		  << "'\n";
	    }
	  out << "\n";
	}
      // report changes
      if (numchanges)
	{
	  report_mem_header(out, numchanges, 0, change_kind,
			    "member type", indent);

	  for (diff_sptrs_type::const_iterator it =
		 d.class_or_union_diff::get_priv()->sorted_changed_member_types_.begin();
	       it != d.class_or_union_diff::get_priv()->sorted_changed_member_types_.end();
	       ++it)
	    {
	      if (!(*it)->to_be_reported())
		continue;

	      type_or_decl_base_sptr o = (*it)->first_subject();
	      type_or_decl_base_sptr n = (*it)->second_subject();
	      out << indent << "  '"
		  << o->get_pretty_representation()
		  << "' changed ";
	      report_loc_info(n, *ctxt, out);
	      out << ":\n";
	      (*it)->report(out, indent + "    ");
	    }
	  out << "\n";
	}

      // report insertions
      int numins = e.num_insertions();
      ABG_ASSERT(numchanges <= numins);
      numins -= numchanges;

      if (numins)
	{
	  report_mem_header(out, numins, 0, ins_kind,
			    "member type", indent);

	  for (vector<insertion>::const_iterator i = e.insertions().begin();
	       i != e.insertions().end();
	       ++i)
	    {
	      type_base_sptr mem_type;
	      for (vector<unsigned>::const_iterator j =
		     i->inserted_indexes().begin();
		   j != i->inserted_indexes().end();
		   ++j)
		{
		  mem_type = second->get_member_types()[*j];
		  if (!d.class_or_union_diff::get_priv()->
		      member_type_has_changed(get_type_declaration(mem_type)))
		    {
		      out << indent << "  '"
			  << get_type_declaration(mem_type)->
			get_pretty_representation()
			  << "'\n";
		    }
		}
	    }
	  out << "\n";
	}
    }

  // member function templates
  if (const edit_script& e = d.member_fn_tmpls_changes())
    {
      // report deletions
      int numdels = e.num_deletions();
      if (numdels)
	report_mem_header(out, numdels, 0, del_kind,
			  "member function template", indent);
      for (vector<deletion>::const_iterator i = e.deletions().begin();
	   i != e.deletions().end();
	   ++i)
	{
	  member_function_template_sptr mem_fn_tmpl =
	    first->get_member_function_templates()[i->index()];
	  out << indent << "  '"
	      << mem_fn_tmpl->as_function_tdecl()->get_pretty_representation()
	      << "'\n";
	}

      // report insertions
      int numins = e.num_insertions();
      if (numins)
	report_mem_header(out, numins, 0, ins_kind,
			  "member function template", indent);
      for (vector<insertion>::const_iterator i = e.insertions().begin();
	   i != e.insertions().end();
	   ++i)
	{
	  member_function_template_sptr mem_fn_tmpl;
	  for (vector<unsigned>::const_iterator j =
		 i->inserted_indexes().begin();
	       j != i->inserted_indexes().end();
	       ++j)
	    {
	      mem_fn_tmpl = second->get_member_function_templates()[*j];
	      out << indent << "  '"
		  << mem_fn_tmpl->as_function_tdecl()->
		get_pretty_representation()
		  << "'\n";
	    }
	}
    }

  // member class templates.
  if (const edit_script& e = d.member_class_tmpls_changes())
    {
      // report deletions
      int numdels = e.num_deletions();
      if (numdels)
	report_mem_header(out, numdels, 0, del_kind,
			  "member class template", indent);
      for (vector<deletion>::const_iterator i = e.deletions().begin();
	   i != e.deletions().end();
	   ++i)
	{
	  member_class_template_sptr mem_cls_tmpl =
	    first->get_member_class_templates()[i->index()];
	  out << indent << "  '"
	      << mem_cls_tmpl->as_class_tdecl()->get_pretty_representation()
	      << "'\n";
	}

      // report insertions
      int numins = e.num_insertions();
      if (numins)
	report_mem_header(out, numins, 0, ins_kind,
			  "member class template", indent);
      for (vector<insertion>::const_iterator i = e.insertions().begin();
	   i != e.insertions().end();
	   ++i)
	{
	  member_class_template_sptr mem_cls_tmpl;
	  for (vector<unsigned>::const_iterator j =
		 i->inserted_indexes().begin();
	       j != i->inserted_indexes().end();
	       ++j)
	    {
	      mem_cls_tmpl = second->get_member_class_templates()[*j];
	      out << indent << "  '"
		  << mem_cls_tmpl->as_class_tdecl()
		->get_pretty_representation()
		  << "'\n";
	    }
	}
    }
}

/// Produce a basic report about the changes carried by a @ref
/// class_diff node.
///
/// @param d the @ref class_diff node to consider.
///
/// @param out the output stream to report the changes to.
///
/// @param indent the string to use as an indentation prefix in the
/// report.
void
default_reporter::report(const class_diff& d, ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  string name = d.first_subject()->get_pretty_representation();

  RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER(d.first_subject(),
						   d.second_subject());

  d.currently_reporting(true);

  // Now report the changes about the differents parts of the type.
  class_decl_sptr first = d.first_class_decl(),
    second = d.second_class_decl();

  report_name_size_and_alignment_changes(first, second, d.context(),
					 out, indent);

  const diff_context_sptr& ctxt = d.context();
  maybe_report_diff_for_member(first, second, ctxt, out, indent);

  // bases classes
  if (d.base_changes())
    {
      // Report deletions.
      int numdels = d.get_priv()->deleted_bases_.size();
      size_t numchanges = d.get_priv()->sorted_changed_bases_.size();

      if (numdels)
	{
	  report_mem_header(out, numdels, 0, del_kind,
			    "base class", indent);

	  for (class_decl::base_specs::const_iterator i
		 = d.get_priv()->sorted_deleted_bases_.begin();
	       i != d.get_priv()->sorted_deleted_bases_.end();
	       ++i)
	    {
	      if (i != d.get_priv()->sorted_deleted_bases_.begin())
		out << "\n";

	      class_decl::base_spec_sptr base = *i;

	      if (d.get_priv()->base_has_changed(base))
		continue;
	      out << indent << "  "
		  << base->get_base_class()->get_pretty_representation();
	      report_loc_info(base->get_base_class(), *d.context(), out);
	    }
	  out << "\n";
	}

      // Report changes.
      size_t num_filtered = d.get_priv()->count_filtered_bases();
      if (numchanges)
	{
	  report_mem_header(out, numchanges, num_filtered, change_kind,
			    "base class", indent);
	  for (base_diff_sptrs_type::const_iterator it =
		 d.get_priv()->sorted_changed_bases_.begin();
	       it != d.get_priv()->sorted_changed_bases_.end();
	       ++it)
	    {
	      base_diff_sptr diff = *it;
	      if (!diff || !diff->to_be_reported())
		continue;

	      class_decl::base_spec_sptr o = diff->first_base();
	      out << indent << "  '"
		  << o->get_base_class()->get_pretty_representation() << "'";
	      report_loc_info(o->get_base_class(), *d.context(), out);
	      out << " changed:\n";
	      diff->report(out, indent + "    ");
	    }
	}

      //Report insertions.
      int numins = d.get_priv()->inserted_bases_.size();
      if (numins)
	{
	  report_mem_header(out, numins, 0, ins_kind,
			    "base class", indent);

	  for (class_decl::base_specs::const_iterator i =
		 d.get_priv()->sorted_inserted_bases_.begin();
	       i != d.get_priv()->sorted_inserted_bases_.end();
	       ++i)
	    {
	      class_decl_sptr b = (*i)->get_base_class();
	      out << indent << "  " << b->get_pretty_representation();
	      report_loc_info(b, *ctxt, out);
	      out << "\n";
	    }
	}

      // Report base classes re-organisation
      maybe_report_base_class_reordering(d, out, indent);
    }

  d.class_or_union_diff::report(out, indent);

  d.currently_reporting(false);

  d.reported_once(true);
}

/// Produce a basic report about the changes carried by a @ref
/// union_diff node.
///
/// @param d the @ref union_diff node to consider.
///
/// @param out the output stream to report the changes to.
///
/// @param indent the string to use as an indentation prefix in the
/// report.
void
default_reporter::report(const union_diff& d, ostream& out,
			 const string& indent) const
{
  RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER(d.first_subject(),
						   d.second_subject());

  d.currently_reporting(true);

  // Now report the changes about the differents parts of the type.
  union_decl_sptr first = d.first_union_decl(), second = d.second_union_decl();

  report_name_size_and_alignment_changes(first, second, d.context(),
					 out, indent);

  maybe_report_diff_for_member(first, second,d. context(), out, indent);

  d.class_or_union_diff::report(out, indent);

  if (d.context()->get_allowed_category() & HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY
      && filtering::union_diff_has_harmless_changes(&d))
    {
      // The user wants to see harmless changes and the union diff we
      // are looking at does carry some harmless changes.  Let's show
      // the "before" and "after" carried by the diff node.
      out << indent << "type changed from:\n"
	  << get_class_or_union_flat_representation(first, indent + "  ",
						    /*one_line=*/true,
						    /*internal=*/false,
						    /*qualified_names=*/false)
	  << "\n"
	  << indent << "to:\n"
	  << get_class_or_union_flat_representation(second, indent + "  ",
						    /*one_line=*/true,
						    /*internal=*/false,
						    /*qualified_names=*/false)
	  << "\n";
    }

  d.currently_reporting(false);

  d.reported_once(true);
}

/// Emit a report about the changes carried by a @ref distinct_diff
/// node.
///
/// @param d the @ref distinct_diff node to consider.
///
/// @param out the output stream to send the diff report to.
///
/// @param indent the indentation string to use in the report.
void
default_reporter::report(const distinct_diff& d, ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  type_or_decl_base_sptr f = d.first(), s = d.second();

  string f_repr = f ? f->get_pretty_representation() : "'void'";
  string s_repr = s ? s->get_pretty_representation() : "'void'";

  diff_sptr diff = d.compatible_child_diff();

  string compatible = diff ? " to compatible type '": " to '";

  out << indent << "entity changed from '" << f_repr << "'"
      << compatible << s_repr << "'";
  report_loc_info(s, *d.context(), out);
  out << "\n";

  type_base_sptr fs = strip_typedef(is_type(f)),
    ss = strip_typedef(is_type(s));

  if (diff)
    diff->report(out, indent + "  ");
  else
    report_size_and_alignment_changes(f, s, d.context(), out, indent);
}

/// Serialize a report of the changes encapsulated in the current
/// instance of @ref function_decl_diff over to an output stream.
///
/// @param d the @ref function_decl_diff node to consider.
///
/// @param out the output stream to serialize the report to.
///
/// @param indent the string to use an an indentation prefix.
void
default_reporter::report(const function_decl_diff& d, ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  maybe_report_diff_for_member(d.first_function_decl(),
			       d.second_function_decl(),
			       d.context(), out, indent);

  function_decl_sptr ff = d.first_function_decl();
  function_decl_sptr sf = d.second_function_decl();

  diff_context_sptr ctxt = d.context();
  corpus_sptr fc = ctxt->get_first_corpus();
  corpus_sptr sc = ctxt->get_second_corpus();


  string qn1 = ff->get_qualified_name(), qn2 = sf->get_qualified_name(),
    linkage_names1, linkage_names2;
  elf_symbol_sptr s1 = ff->get_symbol(), s2 = sf->get_symbol();

  if (s1)
    linkage_names1 = s1->get_id_string();
  if (s2)
    linkage_names2 = s2->get_id_string();

  // If the symbols for ff and sf have aliases, get all the names of
  // the aliases;
  if (fc && s1)
    linkage_names1 =
      s1->get_aliases_id_string(fc->get_fun_symbol_map());
  if (sc && s2)
    linkage_names2 =
      s2->get_aliases_id_string(sc->get_fun_symbol_map());

  if (!d.is_filtered_out_without_looking_at_allowed_changes())
    {
      /// If the set of linkage names of the function have changed, report
      /// it.
      if (linkage_names1 != linkage_names2)
	{
	  if (linkage_names1.empty())
	    {
	      out << indent << ff->get_pretty_representation()
		  << " didn't have any linkage name, and it now has: '"
		  << linkage_names2 << "'\n";
	    }
	  else if (linkage_names2.empty())
	    {
	      out << indent << ff->get_pretty_representation()
		  << " did have linkage names '" << linkage_names1
		  << "'\n"
		  << indent << "but it doesn't have any linkage name anymore\n";
	    }
	  else
	    out << indent << "linkage names of "
		<< ff->get_pretty_representation()
		<< "\n" << indent << "changed from '"
		<< linkage_names1 << "' to '" << linkage_names2 << "'\n";
	}

      if (qn1 != qn2
	  && d.type_diff()
	  && d.type_diff()->to_be_reported())
	{
	  // So the function has sub-type changes that are to be
	  // reported.  Let's see if the function name changed too; if it
	  // did, then we'd report that change right before reporting the
	  // sub-type changes.
	  string frep1 = d.first_function_decl()->get_pretty_representation(),
	    frep2 = d.second_function_decl()->get_pretty_representation();
	  out << indent << "'" << frep1 << " {" << linkage_names1<< "}"
	      << "' now becomes '"
	      << frep2 << " {" << linkage_names2 << "}" << "'\n";
	}

      maybe_report_diff_for_symbol(ff->get_symbol(),
				   sf->get_symbol(),
				   d.context(), out, indent);

      // Now report about inline-ness changes
      if (ff->is_declared_inline() != sf->is_declared_inline())
	{
	  out << indent;
	  if (ff->is_declared_inline())
	    out << sf->get_pretty_representation()
		<< " is not declared inline anymore\n";
	  else
	    out << sf->get_pretty_representation()
		<< " is now declared inline\n";
	}

      // Report about vtable offset changes.
      if (is_member_function(ff) && is_member_function(sf))
	{
	  bool ff_is_virtual = get_member_function_is_virtual(ff),
	    sf_is_virtual = get_member_function_is_virtual(sf);
	  if (ff_is_virtual != sf_is_virtual)
	    {
	      out << indent;
	      if (ff_is_virtual)
		out << ff->get_pretty_representation()
		    << " is no more declared virtual\n";
	      else
		out << ff->get_pretty_representation()
		    << " is now declared virtual\n";
	    }

	  size_t ff_vtable_offset = get_member_function_vtable_offset(ff),
	    sf_vtable_offset = get_member_function_vtable_offset(sf);
	  if (ff_is_virtual && sf_is_virtual
	      && (ff_vtable_offset != sf_vtable_offset))
	    {
	      out << indent
		  << "the vtable offset of "  << ff->get_pretty_representation()
		  << " changed from " << ff_vtable_offset
		  << " to " << sf_vtable_offset << "\n";
	    }

	  // the parent types (classe or union) of the two member
	  // functions.
	  class_or_union_sptr f =
	    is_class_or_union_type(is_method_type(ff->get_type())->get_class_type());
	  class_or_union_sptr s =
	    is_class_or_union_type(is_method_type(sf->get_type())->get_class_type());

	  class_decl_sptr fc = is_class_type(f);
	  class_decl_sptr sc = is_class_type(s);

	  // Detect if the virtual member function changes above
	  // introduced a vtable change or not.
	  bool vtable_added = false, vtable_removed = false;
	  if (!f->get_is_declaration_only() && !s->get_is_declaration_only())
	    {
	      if (fc && sc)
		{
		  vtable_added = !fc->has_vtable() && sc->has_vtable();
		  vtable_removed = fc->has_vtable() && !sc->has_vtable();
		}
	    }
	  bool vtable_changed = ((ff_is_virtual != sf_is_virtual)
				 || (ff_vtable_offset != sf_vtable_offset));
	  bool incompatible_change = (ff_vtable_offset != sf_vtable_offset);

	  if (vtable_added)
	    out << indent
		<< "  note that a vtable was added to "
		<< fc->get_pretty_representation()
		<< "\n";
	  else if (vtable_removed)
	    out << indent
		<< "  note that the vtable was removed from "
		<< fc->get_pretty_representation()
		<< "\n";
	  else if (vtable_changed)
	    {
	      out << indent;
	      if (incompatible_change)
		out << "  note that this is an ABI incompatible "
		  "change to the vtable of ";
	      else
		out << "  note that this induces a change to the vtable of ";
	      out << fc->get_pretty_representation()
		  << "\n";
	    }

	}
    }

  // Report about function type differences.
  if (d.type_diff() && d.type_diff()->to_be_reported())
    d.type_diff()->report(out, indent);
}

/// Report the changes carried by a @ref var_diff node in a serialized
/// form.
///
/// @param d the @ref var_diff node to consider.
///
/// @param out the stream to serialize the diff to.
///
/// @param indent the prefix to use for the indentation of this
/// serialization.
void
default_reporter::report(const var_diff& d, ostream& out,
			 const string& indent) const
{
  if (!d.to_be_reported())
    return;

  decl_base_sptr first = d.first_var(), second = d.second_var();
  string n = first->get_pretty_representation();

  if (!d.is_filtered_out_without_looking_at_allowed_changes())
    {
      report_name_size_and_alignment_changes(first, second,
					     d.context(),
					     out, indent);

      maybe_report_diff_for_symbol(d.first_var()->get_symbol(),
				   d.second_var()->get_symbol(),
				   d.context(), out, indent);

      maybe_report_diff_for_member(first, second, d.context(), out, indent);

      maybe_report_diff_for_variable(first, second, d.context(), out, indent);
    }

  if (diff_sptr dif = d.type_diff())
    {
      if (dif->to_be_reported())
	{
	  RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2(dif, "type");
	  out << indent << "type of variable changed:\n";
	  dif->report(out, indent + "  ");
	}
    }
}

/// Report the changes carried by a @ref translation_unit_diff node in
/// a serialized form.
///
/// @param d the @ref translation_unit_diff node to consider.
///
/// @param out the output stream to serialize the report to.
///
/// @param indent the prefix to use as indentation for the report.
void
default_reporter::report(const translation_unit_diff& d,
			 ostream& out,
			 const string& indent) const
{
  static_cast<const scope_diff&>(d).report(out, indent);
}

/// Report the changes carried by a @ref corpus_diff node in a
/// serialized form.
///
/// @param d the @ref corpus_diff node to consider.
///
/// @param out the output stream to serialize the report to.
///
/// @param indent the prefix to use as indentation for the report.
void
default_reporter::report(const corpus_diff& d, ostream& out,
			 const string& indent) const
{
  const corpus_diff::diff_stats &s =
    const_cast<corpus_diff&>(d).
    apply_filters_and_suppressions_before_reporting();

  const diff_context_sptr& ctxt = d.context();

  d.priv_->emit_diff_stats(s, out, indent);
  if (ctxt->show_stats_only())
    return;
  out << "\n";

  if (ctxt->show_soname_change()
      && !d.priv_->sonames_equal_)
    out << indent << "SONAME changed from '"
	<< d.first_corpus()->get_soname() << "' to '"
	<< d.second_corpus()->get_soname() << "'\n\n";

  if (ctxt->show_architecture_change()
      && !d.priv_->architectures_equal_)
    out << indent << "architecture changed from '"
	<< d.first_corpus()->get_architecture_name() << "' to '"
	<< d.second_corpus()->get_architecture_name() << "'\n\n";

  /// Report removed/added/changed functions.
  if (ctxt->show_deleted_fns())
    {
      if (s.net_num_func_removed() == 1)
	out << indent << "1 Removed function:\n\n";
      else if (s.net_num_func_removed() > 1)
	out << indent << s.net_num_func_removed() << " Removed functions:\n\n";

      bool emitted = false;
      corpus::functions sorted_deleted_fns;
      sort_string_function_ptr_map(d.priv_->deleted_fns_, sorted_deleted_fns);
      for (auto f : sorted_deleted_fns)
	{
	  if (d.priv_->deleted_function_is_suppressed(f))
	    continue;

	  out << indent
	      << "  ";
	  out << "[D] ";
	  out << "'" << (f)->get_pretty_representation() << "'";
	  if (ctxt->show_linkage_names())
	    {
	      out << "    {";
	      show_linkage_name_and_aliases(out, "", *(f)->get_symbol(),
					    d.first_corpus()->get_fun_symbol_map());
	      out << "}";
	    }
	  out << "\n";
	  if (is_member_function(f) && get_member_function_is_virtual(f))
	    {
	      class_decl_sptr c =
		is_class_type(is_method_type(f->get_type())->get_class_type());
	      out << indent
		  << "    "
		  << "note that this removes an entry from the vtable of "
		  << c->get_pretty_representation()
		  << "\n";
	    }
	  emitted = true;
	}
      if (emitted)
	out << "\n";
    }

  if (ctxt->show_added_fns())
    {
      if (s.net_num_func_added() == 1)
	out << indent << "1 Added function:\n\n";
      else if (s.net_num_func_added() > 1)
	out << indent << s.net_num_func_added()
	    << " Added functions:\n\n";
      bool emitted = false;
      corpus::functions sorted_added_fns;
      sort_string_function_ptr_map(d.priv_->added_fns_, sorted_added_fns);
      for (auto f : sorted_added_fns)
	{
	  if (d.priv_->added_function_is_suppressed(f))
	    continue;

	  out
	    << indent
	    << "  ";
	  out << "[A] ";
	  out << "'"
	      << f->get_pretty_representation()
	      << "'";
	  if (ctxt->show_linkage_names())
	    {
	      out << "    {";
	      show_linkage_name_and_aliases
		(out, "", *f->get_symbol(),
		 d.second_corpus()->get_fun_symbol_map());
	      out << "}";
	    }
	  out << "\n";
	  if (is_member_function(f) && get_member_function_is_virtual(f))
	    {
	      class_decl_sptr c =
		is_class_type(is_method_type(f->get_type())->get_class_type());
	      out << indent
		  << "    "
		  << "note that this adds a new entry to the vtable of "
		  << c->get_pretty_representation()
		  << "\n";
	    }
	  emitted = true;
	}
      if (emitted)
	out << "\n";
    }

  if (ctxt->show_changed_fns())
    {
      size_t num_changed = s.num_func_changed() - s.num_changed_func_filtered_out();
      if (num_changed == 1)
	out << indent << "1 function with some indirect sub-type change:\n\n";
      else if (num_changed > 1)
	out << indent << num_changed
	    << " functions with some indirect sub-type change:\n\n";

      vector<function_decl_diff_sptr> sorted_changed_fns;
      sort_string_function_decl_diff_sptr_map(d.priv_->changed_fns_map_,
					      sorted_changed_fns);
      for (vector<function_decl_diff_sptr>::const_iterator i =
	     sorted_changed_fns.begin();
	   i != sorted_changed_fns.end();
	   ++i)
	{
	  diff_sptr diff = *i;
	  if (!diff)
	    continue;

	  if (diff->to_be_reported())
	    {
	      function_decl_sptr fn = (*i)->first_function_decl();
	      out << indent << "  [C] '"
		  << fn->get_pretty_representation() << "'";
	      report_loc_info((*i)->first_function_decl(), *ctxt, out);
	      out << " has some indirect sub-type changes:\n";
	      if (// The symbol of the function has aliases and the
		  // function is not a cdtor (yeah because c++ cdtors
		  // usually have several aliases).
		  (fn->get_symbol()->has_aliases()
		   && !(is_member_function(fn)
			&& get_member_function_is_ctor(fn))
		   && !(is_member_function(fn)
			&& get_member_function_is_dtor(fn)))
		  || // We are in C and the name of the function is
		     // different from the symbol name -- without
		     // taking the possible symbol version into
		     // account (this usually means the programmers
		     // was playing tricks with symbol names and
		     // versions).
		  (is_c_language(get_translation_unit(fn)->get_language())
		   && fn->get_name() != fn->get_symbol()->get_name()))
		{
		  // As the name of the symbol of the function doesn't
		  // seem to be obvious here, make sure to tell the
		  // user about the name of the (function) symbol she
		  // is looking at here.
		  int number_of_aliases =
		    fn->get_symbol()->get_number_of_aliases();
		  if (number_of_aliases == 0)
		    {
		      out << indent << "    "
			  << "Please note that the exported symbol of "
			"this function is "
			  << fn->get_symbol()->get_id_string()
			  << "\n";
		    }
		  else
		    {
		      out << indent << "    "
			  << "Please note that the symbol of this function is "
			  << fn->get_symbol()->get_id_string()
			  << "\n     and it aliases symbol";
		      if (number_of_aliases > 1)
			out << "s";
		      out << ": "
			  << fn->get_symbol()->get_aliases_id_string(false)
			  << "\n";
		    }
		}
	      diff->report(out, indent + "    ");
	      // Extra spacing.
	      out << "\n";
	    }
	}
      // Changed functions have extra spacing already. No new line here.
    }

  // Report removed/added/changed variables.
  if (ctxt->show_deleted_vars())
    {
      if (s.net_num_vars_removed() == 1)
	out << indent << "1 Removed variable:\n\n";
      else if (s.net_num_vars_removed() > 1)
	out << indent << s.net_num_vars_removed()
	    << " Removed variables:\n\n";
      string n;
      bool emitted = false;
      corpus::variables sorted_deleted_vars;
      sort_string_var_ptr_map(d.priv_->deleted_vars_, sorted_deleted_vars);
      for (auto v : sorted_deleted_vars)
	{
	  if (d.priv_->deleted_variable_is_suppressed(v))
	    continue;

	  n = v->get_pretty_representation();

	  out << indent
	      << "  ";
	  out << "[D] ";
	  out << "'"
	      << n
	      << "'";
	  if (ctxt->show_linkage_names())
	    {
	      out << "    {";
	      show_linkage_name_and_aliases(out, "", *v->get_symbol(),
					    d.first_corpus()->get_var_symbol_map());
	      out << "}";
	    }
	  out << "\n";
	  emitted = true;
	}
      if (emitted)
	out << "\n";
    }

  if (ctxt->show_added_vars())
    {
      if (s.net_num_vars_added() == 1)
	out << indent << "1 Added variable:\n\n";
      else if (s.net_num_vars_added() > 1)
	out << indent << s.net_num_vars_added()
	    << " Added variables:\n\n";
      string n;
      bool emitted = false;
      corpus::variables sorted_added_vars;
      sort_string_var_ptr_map(d.priv_->added_vars_, sorted_added_vars);
      for (auto v : sorted_added_vars)
	{
	  if (d.priv_->added_variable_is_suppressed(v))
	    continue;

	  n = v->get_pretty_representation();

	  out << indent
	      << "  ";
	  out << "[A] ";
	  out << "'" << n << "'";
	  if (ctxt->show_linkage_names())
	    {
	      out << "    {";
	      show_linkage_name_and_aliases(out, "", *v->get_symbol(),
					    d.second_corpus()->get_var_symbol_map());
	      out << "}";
	    }
	  out << "\n";
	  emitted = true;
	}
      if (emitted)
	out << "\n";
    }

  if (ctxt->show_changed_vars())
    {
      size_t num_changed =
	s.num_vars_changed() - s.num_changed_vars_filtered_out();
      if (num_changed == 1)
	out << indent << "1 Changed variable:\n\n";
      else if (num_changed > 1)
	out << indent << num_changed
	    << " Changed variables:\n\n";
      string n1, n2;

      for (var_diff_sptrs_type::const_iterator i =
	     d.priv_->sorted_changed_vars_.begin();
	   i != d.priv_->sorted_changed_vars_.end();
	   ++i)
	{
	  diff_sptr diff = *i;

	  if (!diff)
	    continue;

	  if (!diff->to_be_reported())
	    continue;

	  n1 = diff->first_subject()->get_pretty_representation();
	  n2 = diff->second_subject()->get_pretty_representation();

	  out << indent << "  [C] '" << n1 << "' was changed";
	  if (n1 != n2)
	    out << " to '" << n2 << "'";
	  report_loc_info(diff->second_subject(), *ctxt, out);
	  out << ":\n";
	  diff->report(out, indent + "    ");
	  // Extra spacing.
	  out << "\n";
	}
      // Changed variables have extra spacing already. No new line here.
    }

  // Report removed function symbols not referenced by any debug info.
  if (ctxt->show_symbols_unreferenced_by_debug_info()
      && d.priv_->deleted_unrefed_fn_syms_.size())
    {
      if (s.net_num_removed_func_syms() == 1)
	out << indent
	    << "1 Removed function symbol not referenced by debug info:\n\n";
      else if (s.net_num_removed_func_syms() > 0)
	out << indent
	    << s.net_num_removed_func_syms()
	    << " Removed function symbols not referenced by debug info:\n\n";

      bool emitted = false;
      vector<elf_symbol_sptr> sorted_deleted_unrefed_fn_syms;
      sort_string_elf_symbol_map(d.priv_->deleted_unrefed_fn_syms_,
				 sorted_deleted_unrefed_fn_syms);
      for (vector<elf_symbol_sptr>::const_iterator i =
	     sorted_deleted_unrefed_fn_syms.begin();
	   i != sorted_deleted_unrefed_fn_syms.end();
	   ++i)
	{
	  if (d.priv_->deleted_unrefed_fn_sym_is_suppressed((*i).get()))
	    continue;

	  out << indent << "  ";
	  out << "[D] ";

	  show_linkage_name_and_aliases(out, "", **i,
					d.first_corpus()->get_fun_symbol_map());
	  out << "\n";
	  emitted = true;
	}
      if (emitted)
	out << "\n";
    }

  // Report added function symbols not referenced by any debug info.
  if (ctxt->show_symbols_unreferenced_by_debug_info()
      && ctxt->show_added_symbols_unreferenced_by_debug_info()
      && d.priv_->added_unrefed_fn_syms_.size())
    {
      if (s.net_num_added_func_syms() == 1)
	out << indent
	    << "1 Added function symbol not referenced by debug info:\n\n";
      else if (s.net_num_added_func_syms() > 0)
	out << indent
	    << s.net_num_added_func_syms()
	    << " Added function symbols not referenced by debug info:\n\n";

      bool emitted = false;
      vector<elf_symbol_sptr> sorted_added_unrefed_fn_syms;
      sort_string_elf_symbol_map(d.priv_->added_unrefed_fn_syms_,
				 sorted_added_unrefed_fn_syms);
      for (vector<elf_symbol_sptr>::const_iterator i =
	     sorted_added_unrefed_fn_syms.begin();
	   i != sorted_added_unrefed_fn_syms.end();
	   ++i)
	{
	  if (d.priv_->added_unrefed_fn_sym_is_suppressed((*i).get()))
	    continue;

	  out << indent << "  ";
	  out << "[A] ";
	  show_linkage_name_and_aliases(out, "",
					**i,
					d.second_corpus()->get_fun_symbol_map());
	  out << "\n";
	  emitted = true;
	}
      if (emitted)
	out << "\n";
    }

  // Report removed variable symbols not referenced by any debug info.
  if (ctxt->show_symbols_unreferenced_by_debug_info()
      && d.priv_->deleted_unrefed_var_syms_.size())
    {
      if (s.net_num_removed_var_syms() == 1)
	out << indent
	    << "1 Removed variable symbol not referenced by debug info:\n\n";
      else if (s.net_num_removed_var_syms() > 0)
	out << indent
	    << s.net_num_removed_var_syms()
	    << " Removed variable symbols not referenced by debug info:\n\n";

      bool emitted = false;
      vector<elf_symbol_sptr> sorted_deleted_unrefed_var_syms;
      sort_string_elf_symbol_map(d.priv_->deleted_unrefed_var_syms_,
				 sorted_deleted_unrefed_var_syms);
      for (vector<elf_symbol_sptr>::const_iterator i =
	     sorted_deleted_unrefed_var_syms.begin();
	   i != sorted_deleted_unrefed_var_syms.end();
	   ++i)
	{
	  if (d.priv_->deleted_unrefed_var_sym_is_suppressed((*i).get()))
	    continue;

	  out << indent << "  ";
	  out << "[D] ";

	  show_linkage_name_and_aliases
	    (out, "", **i,
	     d.first_corpus()->get_fun_symbol_map());

	  out << "\n";
	  emitted = true;
	}
      if (emitted)
	out << "\n";
    }

  // Report added variable symbols not referenced by any debug info.
  if (ctxt->show_symbols_unreferenced_by_debug_info()
      && ctxt->show_added_symbols_unreferenced_by_debug_info()
      && d.priv_->added_unrefed_var_syms_.size())
    {
      if (s.net_num_added_var_syms() == 1)
	out << indent
	    << "1 Added variable symbol not referenced by debug info:\n\n";
      else if (s.net_num_added_var_syms() > 0)
	out << indent
	    << s.net_num_added_var_syms()
	    << " Added variable symbols not referenced by debug info:\n\n";

      bool emitted = false;
      vector<elf_symbol_sptr> sorted_added_unrefed_var_syms;
      sort_string_elf_symbol_map(d.priv_->added_unrefed_var_syms_,
				 sorted_added_unrefed_var_syms);
      for (vector<elf_symbol_sptr>::const_iterator i =
	     sorted_added_unrefed_var_syms.begin();
	   i != sorted_added_unrefed_var_syms.end();
	   ++i)
	{
	  if (d.priv_->added_unrefed_var_sym_is_suppressed((*i).get()))
	    continue;

	  out << indent << "  ";
	  out << "[A] ";
	  show_linkage_name_and_aliases(out, "", **i,
					d.second_corpus()->get_fun_symbol_map());
	  out << "\n";
	  emitted = true;
	}
      if (emitted)
	out << "\n";
    }

  // Report added/removed/changed types not reacheable from public
  // interfaces.
  maybe_report_unreachable_type_changes(d, s, indent, out);

  d.priv_->maybe_dump_diff_tree();
}

} // end namespace comparison
}// end namespace libabigail
