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

/// @file
///
/// This file contains definitions of diff objects filtering
/// facilities.

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

#include "abg-comp-filter.h"
#include "abg-tools-utils.h"

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

namespace abigail
{
namespace comparison
{
namespace filtering
{

static bool
has_offset_changes(const string_decl_base_sptr_map& f_data_members,
		   const string_decl_base_sptr_map& s_data_members);

using std::dynamic_pointer_cast;

/// Walk the diff sub-trees of a a @ref corpus_diff and apply a filter
/// to the nodes visted.  The filter categorizes each node, assigning
/// it into one or several categories.
///
/// @param filter the filter to apply to the diff nodes
///
/// @param d the corpus diff to apply the filter to.
void
apply_filter(filter_base& filter, corpus_diff_sptr d)
{
  bool s = d->context()->visiting_a_node_twice_is_forbidden();
  d->context()->forbid_visiting_a_node_twice(true);
  d->traverse(filter);
  d->context()->forbid_visiting_a_node_twice(s);
}

/// Walk a diff sub-tree and apply a filter to the nodes visted.  The
/// filter categorizes each node, assigning it into one or several
/// categories.
///
/// Note that this function makes sure to avoid visiting a node (or
/// any other node equivalent to it) more than once.  This helps avoid
/// infinite loops for diff trees that involve type changes that
/// reference themselves.
///
/// @param filter the filter to apply to the nodes of the sub-tree.
///
/// @param d the diff sub-tree to walk and apply the filter to.
void
apply_filter(filter_base& filter, diff_sptr d)
{
  bool s = d->context()->visiting_a_node_twice_is_forbidden();
  d->context()->forbid_visiting_a_node_twice(true);
  d->context()->forget_visited_diffs();
  d->traverse(filter);
  d->context()->forbid_visiting_a_node_twice(s);
}

/// Walk a diff sub-tree and apply a filter to the nodes visted.  The
/// filter categorizes each node, assigning it into one or several
/// categories.
///
/// Note that this function makes sure to avoid visiting a node (or
/// any other node equivalent to it) more than once.  This helps avoid
/// infinite loops for diff trees that involve type changes that
/// reference themselves.
///
/// @param filter the filter to apply to the nodes of the sub-tree.
///
/// @param d the diff sub-tree to walk and apply the filter to.
void
apply_filter(filter_base_sptr filter, diff_sptr d)
{apply_filter(*filter, d);}

/// Test if there is a class that is declaration-only among the two
/// classes in parameter.
///
/// @param class1 the first class to consider.
///
/// @param class2 the second class to consider.
///
/// @return true if either classes are declaration-only, false
/// otherwise.
static bool
there_is_a_decl_only_class(const class_decl_sptr& class1,
			   const class_decl_sptr& class2)
{
  if ((class1 && class1->get_is_declaration_only())
      || (class2 && class2->get_is_declaration_only()))
    return true;
  return false;
}

/// Test if there is a enum that is declaration-only among the two
/// enums in parameter.
///
/// @param enum1 the first enum to consider.
///
/// @param enum2 the second enum to consider.
///
/// @return true if either enums are declaration-only, false
/// otherwise.
static bool
there_is_a_decl_only_enum(const enum_type_decl_sptr& enum1,
			  const enum_type_decl_sptr& enum2)
{
  if ((enum1 && enum1->get_is_declaration_only())
      || (enum2 && enum2->get_is_declaration_only()))
    return true;
  return false;
}

/// Test if the diff involves a declaration-only class.
///
/// @param diff the class diff to consider.
///
/// @return true iff the diff involves a declaration-only class.
static bool
diff_involves_decl_only_class(const class_diff* diff)
{
  if (diff && there_is_a_decl_only_class(diff->first_class_decl(),
					 diff->second_class_decl()))
    return true;
  return false;
}

/// Tests if the size of a given type changed.
///
/// @param f the first version of the type to consider.
///
/// @param s the second version of the type to consider.
///
/// @return true if the type size changed, false otherwise.
static bool
type_size_changed(const type_base_sptr f, const type_base_sptr s)
{
  if (!f || !s
      || f->get_size_in_bits() == 0
      || s->get_size_in_bits() == 0
      || there_is_a_decl_only_class(is_compatible_with_class_type(f),
				    is_compatible_with_class_type(s))
      || there_is_a_decl_only_enum(is_compatible_with_enum_type(f),
				   is_compatible_with_enum_type(s)))
    return false;

  return f->get_size_in_bits() != s->get_size_in_bits();
}

/// Detect if a type has offset changes.
///
/// The type must be either a class or a union.  This function returns
/// true iff the type has a data member which has an offset change.
///
/// @param f the first version of the type to consider.
///
/// @param s the second version of the type to consider.
///
/// @return true iff the type has a data member which has an offset
/// change.
static bool
type_has_offset_changes(const type_base_sptr f, const type_base_sptr s)
{
  if (!f || !s)
    return false;

  class_or_union_sptr first = is_class_or_union_type(f);
  class_or_union_sptr second = is_class_or_union_type(s);
  if (!first || !second)
    return false;

  // collect the data members
  string_decl_base_sptr_map f_data_members, s_data_members;
  collect_non_anonymous_data_members(first, f_data_members);
  collect_non_anonymous_data_members(second, s_data_members);

    // detect offset changes
  if (has_offset_changes(f_data_members, s_data_members))
    return true;

  return false;
}

/// Detect if a type has offset changes.
///
/// The type must be either a class or a union.  This function returns
/// true iff the type has a data member which has an offset change.
///
/// @param f the first version of the type to consider.
///
/// @param s the second version of the type to consider.
///
/// @return true iff the type has a data member which has an offset
/// change.
static bool
type_has_offset_changes(const decl_base_sptr f, const decl_base_sptr s)
{return type_has_offset_changes(is_type(f), is_type(s));}

/// Tests if the size of a given type changed.
///
/// @param f the declaration of the first version of the type to
/// consider.
///
/// @param s the declaration of the second version of the type to
/// consider.
///
/// @return true if the type size changed, false otherwise.
static bool
type_size_changed(const decl_base_sptr f, const decl_base_sptr s)
{return type_size_changed(is_type(f), is_type(s));}

/// Test if a given type diff node carries a type size change.
///
/// @param diff the diff tree node to test.
///
/// @return true if @p diff carries a type size change.
static bool
has_type_size_change(const diff* diff)
{
  if (!diff)
    return false;

  if (const fn_parm_diff* fn_parm_d = is_fn_parm_diff(diff))
    diff = fn_parm_d->type_diff().get();

  type_base_sptr f = is_type(diff->first_subject()),
    s = is_type(diff->second_subject());

  if (!f || !s)
    return false;

  return type_size_changed(f, s);
}

/// Find a data member that is at a given offset.
///
/// @param data_members the set of data member to consider.
///
/// @param the offset to consider.
///
/// @return the data member found at offset @p offset of nil if none
/// was found with that offset;
static var_decl_sptr
find_data_member_at_offset(const string_decl_base_sptr_map& data_members,
			   unsigned offset)
{
  for (auto e : data_members)
    {
      var_decl_sptr dm = is_var_decl(e.second);
      ABG_ASSERT(dm);
      unsigned off = get_absolute_data_member_offset(dm);
      if (offset == off)
	return dm;
    }
  return var_decl_sptr();
}

/// Test if a set of data members contains at least one data member
/// that has an offset change.
///
/// @param f_data_members the first version of data members to
/// consider.
///
/// @param s_data_members the second version of data members to
/// consider.
///
/// @return true iff there is at least one data member which has an
/// offset change between the first version of data members and the
/// second version.
static bool
has_offset_changes(const string_decl_base_sptr_map& f_data_members,
		   const string_decl_base_sptr_map& s_data_members)
{
  // Compare the offsets of the data members
  for (auto entry : f_data_members)
    {
      var_decl_sptr f_member = is_var_decl(entry.second);
      ABG_ASSERT(f_member);
      unsigned f_offset = get_absolute_data_member_offset(f_member);
      auto i = s_data_members.find(entry.first);
      var_decl_sptr s_member;
      if (i == s_data_members.end())
	{
	  s_member = find_data_member_at_offset(s_data_members, f_offset);
	  if (!s_member)
	    // A data member was suppressed; that's bad; let's consider
	    // that as an offset change.
	    return true;
	}

      if (!s_member)
	s_member = is_var_decl(i->second);
      ABG_ASSERT(s_member);
      unsigned s_offset = get_absolute_data_member_offset(s_member);
      if (f_offset != s_offset)
	return true;
    }
  return false;
}

/// Test if a set of data members contains at least one data member
/// that has a sub-type change.
///
/// @param f_data_members the first version of data members to
/// consider.
///
/// @param s_data_members the second version of data members to
/// consider.
///
/// @return true iff there is at least one data member which has a
/// sub-type change between the first version of data members and the
/// second version.
static bool
has_subtype_changes(const string_decl_base_sptr_map& f_data_members,
		    const string_decl_base_sptr_map& s_data_members,
		    diff_context_sptr ctxt)
{
  // Now compare the offsets of the data members collected.
  for (auto entry : f_data_members)
    {
      var_decl_sptr f_member = is_var_decl(entry.second);
      ABG_ASSERT(f_member);

      var_decl_sptr s_member;
      auto i = s_data_members.find(entry.first);
      if (i == s_data_members.end())
	{
	  unsigned offset = get_data_member_offset(f_member);
	  s_member = find_data_member_at_offset(s_data_members, offset);
	  if (!s_member)
	    // A data member was suppressed; that's bad; let's consider
	    // that as a sub-type change.
	    return true;
	}

      if (!s_member)
	s_member = is_var_decl(i->second);
      ABG_ASSERT(s_member);
      diff_sptr d =compute_diff(f_member->get_type(), s_member->get_type(), ctxt);
      if (d->has_changes())
	return true;
    }
  return false;
}

/// Test if the changes of a @ref class_diff are harmless.
///
/// Potentially harmful changes are basically:
///   1/ name change (that changes the type altogether)
///   2/ size change
///   3/ offset change of any data member
///   4/ any subtype change.
///
/// Thus, this function tests that the class_diff carries none of the
/// 4 kinds of changes above.
///
/// @param d the @ref class_diff to consider.
///
/// @return true iff @p d has only harmless changes.
static bool
class_diff_has_only_harmless_changes(const class_diff* d)
{
  if (!d || !d->has_changes())
    return true;

  class_decl_sptr f = d->first_class_decl(), s = d->second_class_decl();

  if (f->get_qualified_name() != s->get_qualified_name())
    return false;

  if (f->get_size_in_bits() != s->get_size_in_bits())
    return false;

  // collect the data members
  string_decl_base_sptr_map f_data_members, s_data_members;
  collect_non_anonymous_data_members(f, f_data_members);
  collect_non_anonymous_data_members(s, s_data_members);

  // detect offset changes
  if (has_offset_changes(f_data_members, s_data_members))
    return false;

  // detect subtype changes
  if (has_subtype_changes(f_data_members, s_data_members, d->context()))
    return false;

  return true;
}

/// Test if the changes of a @ref class_diff are harmless.
///
/// Potentially harmful changes are basically:
///   1/ name change (that changes the type altogether)
///   2/ size change
///   3/ offset change of any data member
///   4/ any subtype change.
///
/// Thus, this function tests that the class_diff carries none of the
/// 4 kinds of changes above.
///
/// @param d the @ref class_diff to consider.
///
/// @return true iff @p d has only harmless changes.
static bool
class_diff_has_only_harmless_changes(diff* d)
{
  if (const class_diff* class_dif = is_class_diff(d))
    return class_diff_has_only_harmless_changes(class_dif);
  return false;
}

/// Tests if the access specifiers for a member declaration changed.
///
/// @param f the declaration for the first version of the member
/// declaration to consider.
///
/// @param s the declaration for the second version of the member
/// delcaration to consider.
///
/// @return true iff the access specifier changed.
static bool
access_changed(const decl_base_sptr& f, const decl_base_sptr& s)
{
  if (!is_member_decl(f)
      || !is_member_decl(s))
    return false;

  access_specifier fa = get_member_access_specifier(f),
    sa = get_member_access_specifier(s);

  if (sa != fa)
    return true;

  return false;
}

/// Test if there was a function or variable CRC change.
///
/// @param f the first function or variable to consider.
///
/// @param s the second function or variable to consider.
///
/// @return true if the test is positive, false otherwise.
template <typename function_or_var_decl_sptr>
static bool
crc_changed(const function_or_var_decl_sptr& f,
	    const function_or_var_decl_sptr& s)
{
  const auto& symbol_f = f->get_symbol();
  const auto& symbol_s = s->get_symbol();
  if (!symbol_f || !symbol_s)
    return false;
  return symbol_f->get_crc() != symbol_s->get_crc();
}

/// Test if the current diff tree node carries a CRC change in either a
/// function or a variable.
///
/// @param diff the diff tree node to consider.
///
/// @return true if the test is positive, false otherwise.
static bool
crc_changed(const diff* diff)
{
  if (const function_decl_diff* d =
	dynamic_cast<const function_decl_diff*>(diff))
    return crc_changed(d->first_function_decl(), d->second_function_decl());
  if (const var_diff* d = dynamic_cast<const var_diff*>(diff))
    return crc_changed(d->first_var(), d->second_var());
  return false;
}

/// Test if there was a function or variable namespace change.
///
/// @param f the first function or variable to consider.
///
/// @param s the second function or variable to consider.
///
/// @return true if the test is positive, false otherwise.
template <typename function_or_var_decl_sptr>
static bool
namespace_changed(const function_or_var_decl_sptr& f,
		  const function_or_var_decl_sptr& s)
{
  const auto& symbol_f = f->get_symbol();
  const auto& symbol_s = s->get_symbol();
  if (!symbol_f || !symbol_s)
    return false;
  return symbol_f->get_namespace() != symbol_s->get_namespace();
}

/// Test if the current diff tree node carries a namespace change in
/// either a function or a variable.
///
/// @param diff the diff tree node to consider.
///
/// @return true if the test is positive, false otherwise.
static bool
namespace_changed(const diff* diff)
{
  if (const function_decl_diff* d =
	dynamic_cast<const function_decl_diff*>(diff))
    return namespace_changed(d->first_function_decl(),
			     d->second_function_decl());
  if (const var_diff* d = dynamic_cast<const var_diff*>(diff))
    return namespace_changed(d->first_var(), d->second_var());
  return false;
}

/// Test if there was a function name change, but there there was no
/// change in name of the underlying symbol.  IOW, if the name of a
/// function changed, but the symbol of the new function is equal to
/// the symbol of the old one, or is equal to an alians of the symbol
/// of the old function.
///
/// @param f the first function to consider.
///
/// @param s the second function to consider.
///
/// @return true if the test is positive, false otherwise.
static bool
function_name_changed_but_not_symbol(const function_decl_sptr& f,
				     const function_decl_sptr& s)
{
  if (!f || !s)
    return false;
  string fn = f->get_qualified_name(),
    sn = s->get_qualified_name();

  if (fn != sn)
    {
      elf_symbol_sptr fs = f->get_symbol(), ss = s->get_symbol();
      if (fs == ss)
	return true;
      if (!!fs != !!ss)
	return false;
      for (elf_symbol_sptr s = fs->get_next_alias();
	   s && !s->is_main_symbol();
	   s = s->get_next_alias())
	if (*s == *ss)
	  return true;
    }
  return false;
}

/// Test if the current diff tree node carries a function name change,
/// in which there there was no change in the name of the underlying
/// symbol.  IOW, if the name of a function changed, but the symbol of
/// the new function is equal to the symbol of the old one, or is
/// equal to an alians of the symbol of the old function.
///
/// @param diff the diff tree node to consider.
///
/// @return true if the test is positive, false otherwise.
static bool
function_name_changed_but_not_symbol(const diff* diff)
{
  if (const function_decl_diff* d =
      dynamic_cast<const function_decl_diff*>(diff))
    return function_name_changed_but_not_symbol(d->first_function_decl(),
						d->second_function_decl());
  return false;
}

/// Tests if the offset of a given data member changed.
///
/// @param f the declaration for the first version of the data member to
/// consider.
///
/// @param s the declaration for the second version of the data member
/// to consider.
///
/// @return true iff the offset of the data member changed.
static bool
data_member_offset_changed(decl_base_sptr f, decl_base_sptr s)
{
  if (!is_member_decl(f)
      || !is_member_decl(s))
    return false;

  var_decl_sptr v0 = dynamic_pointer_cast<var_decl>(f),
    v1 = dynamic_pointer_cast<var_decl>(s);
  if (!v0 || !v1)
    return false;

  if (get_data_member_offset(v0) != get_data_member_offset(v1))
    return true;

  return false;
}

/// Test if the size of a non-static data member changed accross two
/// versions.
///
/// @param f the first version of the non-static data member.
///
/// @param s the second version of the non-static data member.
static bool
non_static_data_member_type_size_changed(const decl_base_sptr& f,
					 const decl_base_sptr& s)
{
  if (!is_member_decl(f)
      || !is_member_decl(s))
    return false;

  var_decl_sptr fv = dynamic_pointer_cast<var_decl>(f),
    sv = dynamic_pointer_cast<var_decl>(s);
  if (!fv
      || !sv
      || get_member_is_static(fv)
      || get_member_is_static(sv))
    return false;

  return type_size_changed(fv->get_type(), sv->get_type());
}

/// Test if the size of a static data member changed accross two
/// versions.
///
/// @param f the first version of the static data member.
///
/// @param s the second version of the static data member.
static bool
static_data_member_type_size_changed(const decl_base_sptr& f,
				     const decl_base_sptr& s)
{
  if (!is_member_decl(f)
      || !is_member_decl(s))
    return false;

  var_decl_sptr fv = dynamic_pointer_cast<var_decl>(f),
    sv = dynamic_pointer_cast<var_decl>(s);
  if (!fv
      || !sv
      || !get_member_is_static(fv)
      || !get_member_is_static(sv))
    return false;

  return type_size_changed(fv->get_type(), sv->get_type());
}

/// Test if two types are different but compatible.
///
/// @param d1 the declaration of the first type to consider.
///
/// @param d2 the declaration of the second type to consider.
///
/// @return true if d1 and d2 are different but compatible.
static bool
is_compatible_change(const decl_base_sptr& d1, const decl_base_sptr& d2)
{
  if ((d1 && d2)
      && (d1 != d2)
      && types_are_compatible(d1, d2))
    return true;
  return false;
}

/// Test if two decls have different names.
///
/// @param d1 the first declaration to consider.
///
/// @param d2 the second declaration to consider.
///
/// @return true if d1 and d2 have different names.
static bool
decl_name_changed(const type_or_decl_base* a1, const type_or_decl_base *a2)
{
  string d1_name, d2_name;

  const decl_base *d1 = dynamic_cast<const decl_base*>(a1);
  if (d1 == 0)
    return false;

  const decl_base *d2 = dynamic_cast<const decl_base*>(a2);
  if (d2 == 0)
    return false;

  if (d1)
    d1_name = d1->get_qualified_name();
  if (d2)
    d2_name = d2->get_qualified_name();

  return d1_name != d2_name;
}

/// Test if two decls have different names.
///
/// @param d1 the first declaration to consider.
///
/// @param d2 the second declaration to consider.
///
/// @return true if d1 and d2 have different names.
static bool
decl_name_changed(const type_or_decl_base_sptr& d1,
		  const type_or_decl_base_sptr& d2)
{return decl_name_changed(d1.get(), d2.get());}

/// Test if a diff nodes carries a changes in which two decls have
/// different names.
///
/// @param d the diff node to consider.
///
/// @return true iff d carries a changes in which two decls have
/// different names.
static bool
decl_name_changed(const diff *d)
{return decl_name_changed(d->first_subject(), d->second_subject());}

/// Test if two decls represents a harmless name change.
///
/// For now, a harmless name change is considered only for a typedef,
/// enum or a data member.
///
/// @param f the first decl to consider in the comparison.
///
/// @param s the second decl to consider in the comparison.
///
/// @return true iff decl @p s represents a harmless change over @p f.
bool
has_harmless_name_change(const decl_base_sptr& f, const decl_base_sptr& s)
{
  // So, a harmless name change is either ...
  return (decl_name_changed(f, s)
	  && (// ... an anonymous decl name changed into another
	      // anonymous decl name ...
	      (f->get_is_anonymous() && s->get_is_anonymous())
	      ||
	      // ... an anonymous decl name changed harmlessly into
	      // another anonymous decl name ...
	      ((f->get_is_anonymous_or_has_anonymous_parent()
		&& s->get_is_anonymous_or_has_anonymous_parent())
	       && tools_utils::decl_names_equal(f->get_qualified_name(),
						s->get_qualified_name()))
	      // ... a typedef name change, without having the
	      // underlying type changed ...
	      || (is_typedef(f)
		  && is_typedef(s)
		  && (is_typedef(f)->get_underlying_type()
		   == is_typedef(s)->get_underlying_type()))
	      // .. or a data member name change, without having its
	      // type changed ...
	      || (is_data_member(f)
		  && is_data_member(s)
		  && (is_var_decl(f)->get_type()
		      == is_var_decl(s)->get_type()))
	      // .. an enum name change without having any other part
	      // of the enum to change.
	      || (is_enum_type(f)
		  && is_enum_type(s)
		  && !enum_has_non_name_change(*is_enum_type(f),
					       *is_enum_type(s),
					       0))));
}

/// Test if two decls represents a harmful name change.
///
/// A harmful name change is a name change that is not harmless, so
/// this function uses the function has_harmless_name_change.
///
/// @param f the first decl to consider in the comparison.
///
/// @param s the second decl to consider in the comparison.
///
/// @return true iff decl @p s represents a harmful name change over
/// @p f.
bool
has_harmful_name_change(const decl_base_sptr& f, const decl_base_sptr& s)
{return decl_name_changed(f, s) && ! has_harmless_name_change(f, s);}

/// Test if a diff node represents a harmful name change.
///
/// A harmful name change is a name change that is not harmless, so
/// this function uses the function has_harmless_name_change.
///
/// @param f the first decl to consider in the comparison.
///
/// @param s the second decl to consider in the comparison.
///
/// @return true iff decl @p s represents a harmful name change over
/// @p f.
bool
has_harmful_name_change(const diff* dif)
{
  decl_base_sptr f = is_decl(dif->first_subject()),
    s = is_decl(dif->second_subject());

  return has_harmful_name_change(f, s);
}

/// Test if a class_diff node has non-static members added or
/// removed.
///
/// @param diff the diff node to consider.
///
/// @return true iff the class_diff node has non-static members added
/// or removed.
static bool
non_static_data_member_added_or_removed(const class_diff* diff)
{
  if (diff && !diff_involves_decl_only_class(diff))
    {
      for (string_decl_base_sptr_map::const_iterator i =
	     diff->inserted_data_members().begin();
	   i != diff->inserted_data_members().end();
	   ++i)
	if (!get_member_is_static(i->second))
	  return true;

      for (string_decl_base_sptr_map::const_iterator i =
	     diff->deleted_data_members().begin();
	   i != diff->deleted_data_members().end();
	   ++i)
	if (!get_member_is_static(i->second))
	  return true;
    }

  return false;
}

/// Test if a class_diff node has members added or removed.
///
/// @param diff the diff node to consider.
///
/// @return true iff the class_diff node has members added or removed.
static bool
non_static_data_member_added_or_removed(const diff* diff)
{
  return non_static_data_member_added_or_removed
    (dynamic_cast<const class_diff*>(diff));
}

/// Test if a @ref class_or_union_diff has a data member replaced by
/// an anonymous data member in a harmless way.  That means, the new
/// anonymous data member somehow contains the replaced data member
/// and it doesn't break the layout of the containing class.
///
/// @param diff the diff node to consider.
///
/// @return true iff the @ref class_or_union_diff has a data member
/// harmlessly replaced by an anonymous data member.
bool
has_data_member_replaced_by_anon_dm(const diff* diff)
{
  const class_or_union_diff *c = is_class_or_union_diff(diff);

  if (!c)
    return false;
  return !c->data_members_replaced_by_adms().empty();
}

/// Test if we are looking at two variables which types are both one
/// dimension array, with one of them being of unknow size and the two
/// variables having the same symbol size.
///
/// This can happen in the case of these two declarations, for instance:
///
///     unsigned int array[];
///
/// and:
///
///     unsigned int array[] ={0};
///
/// In both cases, the size of the ELF symbol of the variable 'array'
/// is 32 bits, but, at least in the first case
bool
is_var_1_dim_unknown_size_array_change(const var_decl_sptr& var1,
				       const var_decl_sptr& var2)
{
  type_base_sptr /*first type*/ft =
    peel_qualified_or_typedef_type(var1->get_type());
  type_base_sptr /*second type*/st =
    peel_qualified_or_typedef_type(var2->get_type());

  array_type_def_sptr /*first array type*/fat = is_array_type(ft);
  array_type_def_sptr /*second array type*/sat = is_array_type(st);

  // The types of the variables must be arrays.
  if (!fat || !sat)
    return false;

  // The arrays must have one dimension and at least one of them must
  // be of unknown size.
  if (fat->get_subranges().size() != 1
      || sat->get_subranges().size() != 1
      || (!fat->is_non_finite() && !sat->is_non_finite()))
    return false;

  // The variables must be equal modulo their type.
  if (!var_equals_modulo_types(*var1, *var2, nullptr))
    return false;

  // The symbols of the variables must be defined and of the same
  // non-zero size.
  if (!var1->get_symbol()
      || !var2->get_symbol()
      || var1->get_symbol()->get_size() != var2->get_symbol()->get_size())
    return false;

  return true;
}

/// Test if we are looking at a diff that carries a change of
/// variables which types are both one dimension array, with one of
/// them being of unknow size and the two variables having the same
/// symbol size.
///
/// This can happen in the case of these two declarations, for instance:
///
///     unsigned int array[];
///
/// and:
///
///     unsigned int array[] ={0};
///
/// In both cases, the size of the ELF symbol of the variable 'array'
/// is 32 bits, but, at least in the first case
bool
is_var_1_dim_unknown_size_array_change(const diff* diff)
{
  const var_diff* d = is_var_diff(diff);

  if (!d)
    return false;

  var_decl_sptr f = d->first_var(), s = d->second_var();

  return is_var_1_dim_unknown_size_array_change(f, s);
}

/// Test if a class with a fake flexible data member got changed into
/// a class with a real fexible data member.
///
/// A fake flexible array data member is a data member that is the
/// last of the class/struct which type is an array of one element.
/// This was used before C99 standardized flexible array data members.
///
/// @param first the first version of the class to consider.
///
/// @param second the second version of the class to consider.
///
/// @return true iff @p first has a fake flexible array data member
/// that got changed into @p second with a real flexible array data
/// member.
bool
has_strict_fam_conversion(const class_decl_sptr& first,
			  const class_decl_sptr& second)
{
  if (has_fake_flexible_array_data_member(first)
      && has_flexible_array_data_member(second))
    // A fake flexible array member has been changed into
    // a real flexible array ...
    return true;
  return false;
}

/// Test if a diff node carries a change from class with a fake
/// flexible data member into a class with a real fexible data member.
///
/// A fake flexible array data member is a data member that is the
/// last of the class/struct which type is an array of one element.
/// This was used before C99 standardized flexible array data members.
///
/// @param the diff node to consider.
///
/// @return true iff @p dif carries a change from class with a fake
/// flexible data member into a class with a real fexible data member.
/// member.
bool
has_strict_fam_conversion(const diff *dif)
{
  const class_diff* d = is_class_diff(dif);
  if (!d)
    return false;

  return has_strict_fam_conversion(d->first_class_decl(),
				   d->second_class_decl());
}

/// Test if a class_diff node has static members added or removed.
///
/// @param diff the diff node to consider.
///
/// @return true iff the class_diff node has static members added
/// or removed.
static bool
static_data_member_added_or_removed(const class_diff* diff)
{
  if (diff && !diff_involves_decl_only_class(diff))
    {
      for (string_decl_base_sptr_map::const_iterator i =
	     diff->inserted_data_members().begin();
	   i != diff->inserted_data_members().end();
	   ++i)
	if (get_member_is_static(i->second))
	  return true;

      for (string_decl_base_sptr_map::const_iterator i =
	     diff->deleted_data_members().begin();
	   i != diff->deleted_data_members().end();
	   ++i)
	if (get_member_is_static(i->second))
	  return true;
    }

  return false;
}

/// Test if a class_diff node has a harmless "One Definition Rule"
/// violation that will cause a diagnostic rule.
///
/// The conditions this function looks for are:
///
///  1/ The two subject of the diff must be canonically different
///
///  2/ The two subjects of the diff must be structurally equal
///
///  3/ The canonical types of the subjects of the diff must be
///  structurally different.
///
/// These conditions makes the diff node appears as it carries changes
/// (because of a ODR glitch present in the binary), but the glitch
/// has no effect on the structural equality of the subjects of the
/// diff.  If we do not detect these conditions, we'd end up with a
/// diagnostic glitch where the reporter thinks there is an ABI change
/// (because of the canonical difference), but then it fails to give
/// any detail about it, because there is no structural change.
///
/// @param diff the diff node to consider.
///
/// @return true iff the the diff node has a harmless "One Definition
/// Rule" violation that cause an empty false positive.
static bool
class_diff_has_harmless_odr_violation_change(const diff* dif)
{
  class_diff* d =  dynamic_cast<class_diff*>(const_cast<diff*>(dif));
  if (!d || !d->has_changes())
    return false;

  class_decl_sptr first = d->first_class_decl();
  class_decl_sptr second = d->second_class_decl();

  if (first->get_qualified_name() == second->get_qualified_name()
      && first != second
      && first->get_corpus() == second->get_corpus())
    return true;

  return false;
}

/// Test if a class_diff node has static members added or
/// removed.
///
/// @param diff the diff node to consider.
///
/// @return true iff the class_diff node has static members added
/// or removed.
static bool
static_data_member_added_or_removed(const diff* diff)
{
  return static_data_member_added_or_removed
    (dynamic_cast<const class_diff*>(diff));
}

/// Test if the class_diff node has a change involving virtual member
/// functions.
///
/// That means whether there is an added, removed or changed virtual
/// member function.
///
/// @param diff the class_diff node to consider.
///
/// @return true iff the class_diff node contains changes involving
/// virtual member functions.
static bool
has_virtual_mem_fn_change(const class_diff* diff)
{
  if (!diff || diff_involves_decl_only_class(diff))
    return false;

  for (string_member_function_sptr_map::const_iterator i =
	 diff->deleted_member_fns().begin();
       i != diff->deleted_member_fns().end();
       ++i)
    {
      if (get_member_function_is_virtual(i->second))
	{
	  // Do not consider a virtual function that got deleted from
	  // an offset and re-inserted at the same offset as a
	  // "virtual member function change".
	  string_member_function_sptr_map::const_iterator j =
	    diff->inserted_member_fns().find(i->first);
	  if (j != diff->inserted_member_fns().end()
	      && (get_member_function_vtable_offset(i->second)
		  == get_member_function_vtable_offset(j->second)))
	    continue;

	  return true;
	}
    }

  for (string_member_function_sptr_map::const_iterator i =
	 diff->inserted_member_fns().begin();
       i != diff->inserted_member_fns().end();
       ++i)
    {
      if (get_member_function_is_virtual(i->second))
	{
	  // Do not consider a virtual function that got deleted from
	  // an offset and re-inserted at the same offset as a
	  // "virtual member function change".
	  string_member_function_sptr_map::const_iterator j =
	    diff->deleted_member_fns().find(i->first);
	  if (j != diff->deleted_member_fns().end()
	      && (get_member_function_vtable_offset(i->second)
		  == get_member_function_vtable_offset(j->second)))
	    continue;

	  return true;
	}
    }

  for (function_decl_diff_sptrs_type::const_iterator i =
	 diff->changed_member_fns().begin();
       i != diff->changed_member_fns().end();
       ++i)
    if (get_member_function_is_virtual((*i)->first_function_decl())
	|| get_member_function_is_virtual((*i)->second_function_decl()))
      {
	if (get_member_function_vtable_offset((*i)->first_function_decl())
	    == get_member_function_vtable_offset((*i)->second_function_decl()))
	  continue;

	return true;
      }

  return false;
}

/// Test if the function_decl_diff node has a change involving virtual
/// member functions.
///
/// That means whether there is an added, removed or changed virtual
/// member function.
///
/// @param diff the function_decl_diff node to consider.
///
/// @return true iff the function_decl_diff node contains changes
/// involving virtual member functions.
bool
has_virtual_mem_fn_change(const function_decl_diff* diff)
{
  if (!diff)
    return false;

  function_decl_sptr ff = diff->first_function_decl(),
    sf = diff->second_function_decl();

  if (!is_member_function(ff)
      || !is_member_function(sf))
    return false;

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

  size_t ff_vtable_offset = get_member_function_vtable_offset(ff),
    sf_vtable_offset = get_member_function_vtable_offset(sf);

  if (ff_vtable_offset != sf_vtable_offset)
    return true;

  return false;
}

/// Test if the class_diff node has a change involving virtual member
/// functions.
///
/// That means whether there is an added, removed or changed virtual
/// member function.
///
/// @param diff the class_diff node to consider.
///
/// @return true iff the class_diff node contains changes involving
/// virtual member functions.
static bool
has_virtual_mem_fn_change(const diff* diff)
{
  return (has_virtual_mem_fn_change(dynamic_cast<const class_diff*>(diff))
	  || has_virtual_mem_fn_change(dynamic_cast<const function_decl_diff*>(diff)));
}

/// Test if the class_diff has changes to non virtual member
/// functions.
///
///@param diff the class_diff nod e to consider.
///
/// @retrurn iff the class_diff node has changes to non virtual member
/// functions.
static bool
has_non_virtual_mem_fn_change(const class_diff* diff)
{
  if (!diff || diff_involves_decl_only_class(diff))
    return false;

  for (string_member_function_sptr_map::const_iterator i =
	 diff->deleted_member_fns().begin();
       i != diff->deleted_member_fns().end();
       ++i)
    if (!get_member_function_is_virtual(i->second))
      return true;

  for (string_member_function_sptr_map::const_iterator i =
	 diff->inserted_member_fns().begin();
       i != diff->inserted_member_fns().end();
       ++i)
    if (!get_member_function_is_virtual(i->second))
      return true;

  for (function_decl_diff_sptrs_type::const_iterator i =
	 diff->changed_member_fns().begin();
       i != diff->changed_member_fns().end();
       ++i)
    if(!get_member_function_is_virtual((*i)->first_function_decl())
       && !get_member_function_is_virtual((*i)->second_function_decl()))
      return true;

  return false;
}

/// Test if the class_diff has changes to non virtual member
/// functions.
///
///@param diff the class_diff nod e to consider.
///
/// @retrurn iff the class_diff node has changes to non virtual member
/// functions.
static bool
has_non_virtual_mem_fn_change(const diff* diff)
{return has_non_virtual_mem_fn_change(dynamic_cast<const class_diff*>(diff));}

/// Test if a class_diff carries a base class removal.
///
/// @param diff the class_diff to consider.
///
/// @return true iff @p diff carries a base classe removal.
static bool
base_classes_removed(const class_diff* diff)
{
  if (!diff)
    return false;
  return diff->deleted_bases().size();
}

/// Test if a class_diff carries a base classes removal.
///
/// @param diff the class_diff to consider.
///
/// @return true iff @p diff carries a base class removal.
static bool
base_classes_removed(const diff* diff)
{return base_classes_removed(dynamic_cast<const class_diff*>(diff));}

/// Test if two classes that are decl-only (have the decl-only flag
/// and carry no data members) but are different just by their size.
///
/// In some weird DWARF representation, it happens that a decl-only
/// class (with no data member) actually carries a non-zero size.
/// That shouldn't happen, but hey, we need to deal with real life.
/// So we need to detect that case first.
///
/// @param first the first class or union to consider.
///
/// @param seconf the second class or union to consider.
///
/// @return true if the two classes are decl-only and differ in their
/// size.
bool
is_decl_only_class_with_size_change(const class_or_union& first,
				    const class_or_union& second)
{
  if (first.get_qualified_name() != second.get_qualified_name())
    return false;

  if (!first.get_is_declaration_only() || !second.get_is_declaration_only())
    return false;

  bool f_is_empty = first.get_data_members().empty();
  bool s_is_empty = second.get_data_members().empty();

  return f_is_empty && s_is_empty;
}

/// Test if two classes that are decl-only (have the decl-only flag
/// and carry no data members) but are different just by their size.
///
/// In some weird DWARF representation, it happens that a decl-only
/// class (with no data member) actually carries a non-zero size.
/// That shouldn't happen, but hey, we need to deal with real life.
/// So we need to detect that case first.
///
/// @param first the first class or union to consider.
///
/// @param seconf the second class or union to consider.
///
/// @return true if the two classes are decl-only and differ in their
/// size.
bool
is_decl_only_class_with_size_change(const class_or_union_sptr& first,
				    const class_or_union_sptr& second)
{
  if (!first || !second)
    return false;

  class_or_union_sptr f = look_through_decl_only_class(first);
  class_or_union_sptr s = look_through_decl_only_class(second);

  return is_decl_only_class_with_size_change(*f, *s);
}

/// Test if a diff node is for two classes that are decl-only (have
/// the decl-only flag and carry no data members) but are different
/// just by their size.
///
/// In some weird DWARF representation, it happens that a decl-only
/// class (with no data member) actually carries a non-zero size.
/// That shouldn't happen, but hey, we need to deal with real life.
/// So we need to detect that case first.
///
/// @param diff the diff node to consider.
///
/// @return true if the two classes are decl-only and differ in their
/// size.
bool
is_decl_only_class_with_size_change(const diff *diff)
{
  const class_or_union_diff *d = dynamic_cast<const class_or_union_diff*>(diff);
  if (!d)
    return false;

  class_or_union_sptr f =
    look_through_decl_only_class(d->first_class_or_union());
  class_or_union_sptr s =
    look_through_decl_only_class(d->second_class_or_union());

  return is_decl_only_class_with_size_change(f, s);
}

/// Test if two @ref decl_base_sptr are different just by the
/// fact that one is decl-only and the other one is defined.
///
/// @param first the first decl to consider.
///
/// @param second the second decl to consider.
///
/// @return true iff the two arguments are different just by the fact
/// that one is decl-only and the other one is defined.
bool
has_decl_only_def_change(const decl_base_sptr& first,
			 const decl_base_sptr& second)
{
  if (!first || !second)
    return false;

  decl_base_sptr f =
    look_through_decl_only(first);
  decl_base_sptr s =
    look_through_decl_only(second);

  if (f->get_qualified_name() != s->get_qualified_name())
    return false;

  return f->get_is_declaration_only() != s->get_is_declaration_only();
}

/// Test if a diff carries a change in which the two decls are
/// different by the fact that one is a decl-only and the other one is
/// defined.
///
/// @param diff the diff node to consider.
///
/// @return true if the diff carries a change in which the two decls
/// are different by the fact that one is a decl-only and the other
/// one is defined.
bool
has_decl_only_def_change(const diff *d)
{
  if (!d)
    return false;

  decl_base_sptr f =
    look_through_decl_only(is_decl(d->first_subject()));
  decl_base_sptr s =
    look_through_decl_only(is_decl(d->second_subject()));

  return has_decl_only_def_change(f, s);
}


/// Test if two @ref class_or_union_sptr are different just by the
/// fact that one is decl-only and the other one is defined.
///
/// @param first the first class or union to consider.
///
/// @param second the second class or union to consider.
///
/// @return true iff the two arguments are different just by the fact
/// that one is decl-only and the other one is defined.
bool
has_class_decl_only_def_change(const class_or_union_sptr& first,
			       const class_or_union_sptr& second)
{
  if (!first || !second)
    return false;

  class_or_union_sptr f =
    look_through_decl_only_class(first);
  class_or_union_sptr s =
    look_through_decl_only_class(second);

  if (f->get_qualified_name() != s->get_qualified_name())
    return false;

  return f->get_is_declaration_only() != s->get_is_declaration_only();
}

/// Test if two @ref enum_sptr are different just by the
/// fact that one is decl-only and the other one is defined.
///
/// @param first the first enum to consider.
///
/// @param second the second enum to consider.
///
/// @return true iff the two arguments are different just by the fact
/// that one is decl-only and the other one is defined.
bool
has_enum_decl_only_def_change(const enum_type_decl_sptr& first,
			      const enum_type_decl_sptr& second)
{
  if (!first || !second)
    return false;

  enum_type_decl_sptr f = look_through_decl_only_enum(first);
  enum_type_decl_sptr s = look_through_decl_only_enum(second);

  if (f->get_qualified_name() != s->get_qualified_name())
    return false;

  return f->get_is_declaration_only() != s->get_is_declaration_only();
}

/// Test if a class_or_union_diff carries a change in which the two
/// classes are different by the fact that one is a decl-only and the
/// other one is defined.
///
/// @param diff the diff node to consider.
///
/// @return true if the class_or_union_diff carries a change in which
/// the two classes are different by the fact that one is a decl-only
/// and the other one is defined.
bool
has_class_decl_only_def_change(const diff *diff)
{
  const class_or_union_diff *d = dynamic_cast<const class_or_union_diff*>(diff);
  if (!d)
    return false;

  class_or_union_sptr f =
    look_through_decl_only_class(d->first_class_or_union());
  class_or_union_sptr s =
    look_through_decl_only_class(d->second_class_or_union());

  return has_class_decl_only_def_change(f, s);
}

/// Test if a enum_diff carries a change in which the two enums are
/// different by the fact that one is a decl-only and the other one is
/// defined.
///
/// @param diff the diff node to consider.
///
/// @return true if the enum_diff carries a change in which the two
/// enums are different by the fact that one is a decl-only and the
/// other one is defined.
bool
has_enum_decl_only_def_change(const diff *diff)
{
  const enum_diff *d = dynamic_cast<const enum_diff*>(diff);
  if (!d)
    return false;

  enum_type_decl_sptr f = look_through_decl_only_enum(d->first_enum());
  enum_type_decl_sptr s = look_through_decl_only_enum(d->second_enum());

  return has_enum_decl_only_def_change(f, s);
}

/// Test if a diff node carries a basic type name change.
///
/// @param d the diff node to consider.
///
/// @return true iff the diff node carries a basic type name change.
bool
has_basic_type_name_change(const diff *d)
{
  if (const type_decl_diff *dif = is_diff_of_basic_type(d))
    if (decl_name_changed(dif))
      return true;

  return false;
}

/// Test if a diff node carries a class or union type name change.
///
/// @param d the diff node to consider.
///
/// @return true iff the diff node carries a class or union type name
/// change.
bool
has_class_or_union_type_name_change(const diff *d)
{
  if (const class_or_union_diff *dif = is_diff_of_class_or_union_type(d))
    if (decl_name_changed(dif))
      return true;

  return false;
}

/// Test if a diff node carries a basic or class type name change.
///
/// @param d the diff node to consider.
///
/// @return true iff the diff node carries a basic or class type name
/// change.
bool
has_basic_or_class_type_name_change(const diff *d)
{
  return (has_basic_type_name_change(d)
	  || has_class_or_union_type_name_change(d));
}

/// Test if a diff node carries a distinct type change or a
/// pointer/reference/typedef to distinct type change.
///
/// Note that a distinct type change is a change where the two
/// subjects of the change are not of the same kind, e.g, a basic type
/// that got changed into a qualified type.
///
/// @param d the diff node to consider.
///
/// @return true iff @p d is mostly a distinct diff.
bool
is_mostly_distinct_diff(const diff *d)
{
  if (is_distinct_diff(d))
    return true;

  // Let's consider that 'd' is a type diff ...
  diff * td = const_cast<type_diff_base*>(is_type_diff(d));
  if (!td)
    {
      // ... or a function parameter diff.  In which case, let's get
      // its child type diff ...
      fn_parm_diff *pd = const_cast<fn_parm_diff*>(is_fn_parm_diff(d));
      if (pd)
	{
	  td = const_cast<type_diff_base*>(is_type_diff(pd->type_diff().get()));
	  if (!td)
	    // if the diff of the fn_parm_diff is a a distinct diff
	    // then handle it.
	    td = const_cast<distinct_diff*>
	      (is_distinct_diff(pd->type_diff().get()));
	}
      else
	return false;
    }

  // At this point, if we are not looking at a type diff we must have
  // bailed out already.
  ABG_ASSERT(td);

  type_base_sptr first = is_type(td->first_subject());
  type_base_sptr second = is_type(td->second_subject());

  first = peel_typedef_pointer_or_reference_type(first);
  second = peel_typedef_pointer_or_reference_type(second);
  ABG_ASSERT(first && second);

  return distinct_diff::entities_are_of_distinct_kinds(first, second);
}

/// Test if a diff node carries a non-anonymous data member to
/// anonymous data member change, or vice-versa.
///
/// @param d the diff node to consider.
///
/// @return true iff @p d carries a non-anonymous to anonymous data
/// member change, or vice-versa.
bool
has_anonymous_data_member_change(const diff *d)
{
  if (is_anonymous_data_member(d->first_subject())
      || is_anonymous_data_member(d->second_subject()))
    return true;
  return false;
}

/// Test if a diff node carries a non-anonymous data member to
/// anonymous data member change, or vice-versa.
///
/// @param d the diff node to consider.
///
/// @return true iff @p d carries a non-anonymous to anonymous data
/// member change, or vice-versa.
bool
has_anonymous_data_member_change(const diff_sptr &d)
{return has_anonymous_data_member_change(d.get());}

/// Test if an enum_diff carries an enumerator insertion.
///
/// @param diff the enum_diff to consider.
///
/// @return true iff @p diff carries an enumerator insertion.
static bool
has_enumerator_insertion(const diff* diff)
{
  if (const enum_diff* d = dynamic_cast<const enum_diff*>(diff))
    return !d->inserted_enumerators().empty();
  return false;
}

/// Test if an enum_diff carries an enumerator removal.
///
/// @param diff the enum_diff to consider.
///
/// @return true iff @p diff carries an enumerator removal or change.
static bool
has_enumerator_removal_or_change(const diff* diff)
{
  if (const enum_diff* d = dynamic_cast<const enum_diff*>(diff))
    return (!d->deleted_enumerators().empty()
	    || !d->changed_enumerators().empty());
  return false;
}

/// Test if an enum_diff carries a harmful change.
///
/// @param diff the enum_diff to consider.
///
/// @return true iff @p diff carries a harmful change.
static bool
has_harmful_enum_change(const diff* diff)
{
  if (const enum_diff* d = dynamic_cast<const enum_diff*>(diff))
    return (has_enumerator_removal_or_change(d)
	    || has_type_size_change(d));
  return false;
}

/// Test if a diff node carries a harmless change of an enum into an
/// integer (or vice-versa).
///
/// The test takes into account the fact change we care about might be
/// wrapped into a typedef or qualified type diff.
///
/// @param diff the diff node to consider.
///
/// @return true if @p diff is a harmless enum to integer change.
static bool
has_harmless_enum_to_int_change(const diff* diff)
{
  if (!diff)
    return false;

  diff = peel_typedef_or_qualified_type_diff(diff);

  if (const distinct_diff *d = is_distinct_diff(diff))
    {
      const enum_type_decl *enum_type = 0;
      const type_base *integer_type = 0;

      type_base *first_type =
	peel_qualified_or_typedef_type(is_type(d->first().get()));
      type_base *second_type =
	peel_qualified_or_typedef_type(is_type(d->second().get()));

      if (const enum_type_decl *e = is_enum_type(first_type))
	enum_type = e;
      else if (const enum_type_decl *e = is_enum_type(second_type))
	enum_type = e;

      if (const type_base * i = is_type_decl(first_type))
	integer_type = i;
      else if (const type_base *i = is_type_decl(second_type))
	integer_type = i;

      if (enum_type
	  && integer_type
	  && enum_type->get_size_in_bits() == integer_type->get_size_in_bits())
	return true;
    }

  return false;
}

/// Test if an @ref fn_parm_diff node has a top cv qualifier change on
/// the type of the function parameter.
///
/// @param diff the diff node to consider.  It should be a @ref
/// fn_parm_diff, otherwise the function returns 'false' directly.
///
/// @return true iff @p diff is a @ref fn_parm_diff node that has a
/// top cv qualifier change on the type of the function parameter.
static bool
has_fn_parm_type_top_cv_qual_change(const diff* diff)
{
  // is diff a "function parameter diff node?
  const fn_parm_diff* parm_diff = is_fn_parm_diff(diff);

  if (!parm_diff || !parm_diff->has_changes())
    // diff either carries no change or is not a function parameter
    // diff node.  So bail out.
    return false;

  function_decl::parameter_sptr first_parm = parm_diff->first_parameter();
  function_decl::parameter_sptr second_parm = parm_diff->second_parameter();

  type_base_sptr first_parm_type = first_parm->get_type();
  type_base_sptr second_parm_type = second_parm->get_type();

  if (!is_qualified_type(first_parm_type)
      && !is_qualified_type(second_parm_type))
    // None of the parameter types is qualified.
    return false;

  qualified_type_def::CV cv_quals_1 = qualified_type_def::CV_NONE;
  qualified_type_def::CV cv_quals_2 = qualified_type_def::CV_NONE;
  type_base_sptr peeled_type_1 = first_parm_type;
  type_base_sptr peeled_type_2 = second_parm_type;

  if (qualified_type_def_sptr qtype1 = is_qualified_type(first_parm_type))
    {
      cv_quals_1 = qtype1->get_cv_quals();
      peeled_type_1 = peel_qualified_type(qtype1);
    }

  if (qualified_type_def_sptr qtype2 = is_qualified_type(second_parm_type))
    {
      cv_quals_2 = qtype2->get_cv_quals();
      peeled_type_2 = peel_qualified_type(qtype2);
    }

  if (peeled_type_1
      && peeled_type_2
      && get_type_name(peeled_type_1) == get_type_name(peeled_type_2)
      && cv_quals_1 != cv_quals_2)
    // The top-level CV qualifiers of the function type are different
    // and the un-qualified variant (peeled) of said function types
    // are equal.  This means the only change the function types have
    // are about top-level CV qualifiers.
    return true;

  return false;
}

/// Test if a type diff only carries a CV qualifier-only change.
///
/// @param type_dif the type dif to consider.
///
/// @return true iff the type_diff carries a CV qualifier only change.
static bool
type_diff_has_cv_qual_change_only(const diff *type_dif)
{
  if (!is_type_diff(type_dif))
    return false;

  if (is_pointer_diff(type_dif))
    type_dif = peel_pointer_diff(type_dif);
  else if (is_reference_diff(type_dif))
    type_dif = peel_reference_diff(type_dif);

  const type_base *f = 0;
  const type_base *s = 0;
  if (const distinct_diff *d = is_distinct_diff(type_dif))
    {
      if (is_qualified_type(d->first()) == is_qualified_type(d->second()))
	return false;
      else
	{
	  f = is_type(d->first()).get();
	  s = is_type(d->second()).get();
	}
    }
  else if (const qualified_type_diff *d = is_qualified_type_diff(type_dif))
    {
      f = is_type(d->first_qualified_type()).get();
      s = is_type(d->second_qualified_type()).get();
    }
  else
    return false;

  f = peel_qualified_type(f);
  s = peel_qualified_type(s);

  // If f and s are arrays, note that they can differ only by the cv
  // qualifier of the array element type.  That cv qualifier is not
  // removed by peel_qualified_type.  So we need to test this case
  // specifically.
  if (array_type_def *f_a = is_array_type(f))
    if (array_type_def *s_a = is_array_type(s))
      return equals_modulo_cv_qualifier(f_a, s_a);

  return *f == *s;
}

/// Test if an @ref fn_parm_diff node has a cv qualifier change on the
/// type of the function parameter. That is, we are looking for
/// changes like 'const char*' to 'char*'.
///
/// @param diff the diff node to consider.  It should be a @ref
/// fn_parm_diff, otherwise the function returns 'false' directly.
///
/// @return true iff @p diff is a @ref fn_parm_diff node that has a
/// cv qualifier change on the type of the function parameter.
static bool
has_fn_parm_type_cv_qual_change(const diff* dif)
{
  // is diff a "function parameter diff node?
  const fn_parm_diff* parm_diff = is_fn_parm_diff(dif);

  if (!parm_diff || !parm_diff->has_changes())
    // diff either carries no change or is not a function parameter
    // diff node.  So bail out.
    return false;

  const diff *type_dif = parm_diff->type_diff().get();
  return type_diff_has_cv_qual_change_only(type_dif);
}

/// Test if a function type or decl diff node carries a CV
/// qualifier-only change on its return type.
///
/// @param dif the diff node to consider.  Note that if this is
/// neither a function type nor decl diff node, the function returns
/// false.
///
/// @return true iff @p dif is a function decl or type diff node which
/// carries a CV qualifier-only change on its return type.
static bool
has_fn_return_type_cv_qual_change(const diff* dif)
{
  const function_type_diff* fn_type_diff = is_function_type_diff(dif);
  if (!fn_type_diff)
    if (const function_decl_diff* fn_decl_diff = is_function_decl_diff(dif))
      fn_type_diff = fn_decl_diff->type_diff().get();

  if (!fn_type_diff)
    return false;

  const diff* return_type_diff = fn_type_diff->return_type_diff().get();
  return type_diff_has_cv_qual_change_only(return_type_diff);
}

/// Test if a function type or decl diff node carries a function
/// parameter addition or removal.
///
/// @param dif the diff node to consider.  Note that if this is
/// neither a function type nor decl diff node, the function returns
/// false.
///
/// @return true iff @p dif is a function decl or type diff node which
/// carries a function parameter addition or removal.
static bool
has_added_or_removed_function_parameters(const diff *dif)
{
  const function_type_diff *fn_type_diff = is_function_type_diff(dif);
    if (!fn_type_diff)
    if (const function_decl_diff* fn_decl_diff = is_function_decl_diff(dif))
      fn_type_diff = fn_decl_diff->type_diff().get();

  if (!fn_type_diff)
    return false;

  if (!(fn_type_diff->sorted_deleted_parms().empty()
	&& fn_type_diff->sorted_added_parms().empty()))
    return true;

  return false;
}

/// Test if a variable diff node carries a CV qualifier change on its type.
///
/// @param dif the diff node to consider.  Note that if it's not of
/// var_diff type, the function returns false.
///
/// @return true iff the @p dif carries a CV qualifier change on its
/// type.
static bool
has_var_type_cv_qual_change(const diff* dif)
{
  const var_diff *var_dif = is_var_diff(dif);
  if (!var_dif)
    return false;

  diff *type_dif = var_dif->type_diff().get();
  if (!type_dif)
    return false;

  return type_diff_has_cv_qual_change_only(type_dif);
}

/// Test if a diff node carries a void* to pointer type change.
///
/// Note that this function looks through typedef and qualifier types
/// to find the void pointer.
///
/// @param dif the diff node to consider.
///
/// @return true iff @p dif carries a void* to pointer type change.
static bool
has_void_ptr_to_ptr_change(const diff* dif)
{
  dif = peel_typedef_diff(dif);

  if (const distinct_diff *d = is_distinct_diff(dif))
    {
      const type_base *f = is_type(d->first().get());
      const type_base *s = is_type(d->second().get());

      f = peel_qualified_or_typedef_type(f);
      s = peel_qualified_or_typedef_type(s);

      if (is_void_pointer_type_equivalent(f)
	  && is_pointer_type(s)
	  && !is_void_pointer_type_equivalent(s)
	  && f->get_size_in_bits() == s->get_size_in_bits())
	return true;
    }
  else if (const pointer_diff *d = is_pointer_diff(dif))
    {
      const type_base *f = is_type(d->first_pointer()).get();
      const type_base *s = is_type(d->second_pointer()).get();

      f = peel_qualified_or_typedef_type(f);
      s = peel_qualified_or_typedef_type(s);

      if (is_void_pointer_type_equivalent(f)
	  && is_pointer_type(s)
	  && !is_void_pointer_type_equivalent(s)
	  && f->get_size_in_bits() == s->get_size_in_bits())
	return true;
    }
  else if (const qualified_type_diff *d = is_qualified_type_diff(dif))
    {
      const type_base *f = is_type(d->first_qualified_type()).get();
      const type_base *s = is_type(d->second_qualified_type()).get();

      f = peel_qualified_or_typedef_type(f);
      s = peel_qualified_or_typedef_type(s);

      if (is_void_pointer_type_equivalent(f)
	  && is_pointer_type(s)
	  && !is_void_pointer_type_equivalent(s)
	  && f->get_size_in_bits() == s->get_size_in_bits())
	return true;
    }

  return false;
}

/// Test if a diff node carries a benign change to the size of a
/// variable of type array.
///
/// A benign size change is a change in size (from or to infinite) of
/// the array as expressed by the debug info, but when the *ELF* size
/// (what really matters) of the variable object hasn't changed.  This
/// happens when the debug info emitter did have trouble figuring out
/// the actual size of the array.
///
/// @param dif the diff node to consider.
///
/// @return true iff @p dif contains the benign array type size change.
static bool
has_benign_array_of_unknown_size_change(const diff* dif)
{
  return is_var_1_dim_unknown_size_array_change(dif);
}

/// Test if a union diff node does have changes that don't impact its
/// size.
///
/// @param d the union diff node to consider.
///
/// @return true iff @p d is a diff node which has changes that don't
/// impact its size.
bool
union_diff_has_harmless_changes(const diff *d)
{
  if (is_union_diff(d)
      && d->has_changes()
      && !has_type_size_change(d))
    return true;

  return false;
}

/// Detect if the changes carried by a given diff node are deemed
/// harmless and do categorize the diff node accordingly.
///
/// @param d the diff node being visited.
///
/// @param pre this is true iff the node is being visited *before* the
/// children nodes of @p d.
///
/// @return true iff the traversal shall keep going after the
/// completion of this function.
static bool
categorize_harmless_diff_node(diff *d, bool pre)
{
  if (!d->has_changes())
    return true;

  if (pre)
    {
      diff_category category = NO_CHANGE_CATEGORY;

      decl_base_sptr f = is_decl(d->first_subject()),
	s = is_decl(d->second_subject());

      if (has_class_decl_only_def_change(d)
	  || has_enum_decl_only_def_change(d))
	category |= TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY;

      if (access_changed(f, s))
	category |= ACCESS_CHANGE_CATEGORY;

      if (is_compatible_change(f, s))
	category |= COMPATIBLE_TYPE_CHANGE_CATEGORY;

      if (has_harmless_name_change(f, s)
	  || class_diff_has_harmless_odr_violation_change(d))
	category |= HARMLESS_DECL_NAME_CHANGE_CATEGORY;

      if (union_diff_has_harmless_changes(d)
	  || class_diff_has_only_harmless_changes(d))
	category |= HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY;

      if (has_non_virtual_mem_fn_change(d))
	category |= NON_VIRT_MEM_FUN_CHANGE_CATEGORY;

      if (static_data_member_added_or_removed(d)
	  || static_data_member_type_size_changed(f, s))
	category |= STATIC_DATA_MEMBER_CHANGE_CATEGORY;

      if (has_data_member_replaced_by_anon_dm(d))
	category |= HARMLESS_DATA_MEMBER_CHANGE_CATEGORY;

      if ((has_enumerator_insertion(d)
	   && !has_harmful_enum_change(d))
	  || has_harmless_enum_to_int_change(d))
	category |= HARMLESS_ENUM_CHANGE_CATEGORY;

      if (function_name_changed_but_not_symbol(d))
	category |= HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY;

      if (has_fn_parm_type_top_cv_qual_change(d))
	category |= FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY;

      if (has_fn_parm_type_cv_qual_change(d))
	category |= FN_PARM_TYPE_CV_CHANGE_CATEGORY;

      if (has_fn_return_type_cv_qual_change(d))
	category |= FN_RETURN_TYPE_CV_CHANGE_CATEGORY;

      if (has_var_type_cv_qual_change(d))
	category |= VAR_TYPE_CV_CHANGE_CATEGORY;

      if (has_void_ptr_to_ptr_change(d))
	category |= VOID_PTR_TO_PTR_CHANGE_CATEGORY;

      if (has_benign_array_of_unknown_size_change(d))
	category |= BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY;

      if (category)
	{
	  d->add_to_local_and_inherited_categories(category);
	  // Also update the category of the canonical node.
	  if (diff * canonical = d->get_canonical_diff())
	    canonical->add_to_local_and_inherited_categories(category);
	}
    }

  return true;
}

/// Detect if the changes carried by a given diff node are deemed
/// harmful and do categorize the diff node accordingly.
///
/// @param d the diff node being visited.
///
/// @param pre this is true iff the node is being visited *before* the
/// children nodes of @p d.
///
/// @return true iff the traversal shall keep going after the
/// completion of this function.
static bool
categorize_harmful_diff_node(diff *d, bool pre)
{
  if (!d->has_changes())
    return true;

  if (pre)
    {
      diff_category category = NO_CHANGE_CATEGORY;
      decl_base_sptr f = is_decl(d->first_subject()),
	s = is_decl(d->second_subject());

      // Detect size or offset changes as well as data member addition
      // or removal.
      //
      // TODO: be more specific -- not all size changes are harmful.
      if (!has_class_decl_only_def_change(d)
	  && !has_enum_decl_only_def_change(d)
	  && (type_size_changed(f, s)
	      || type_has_offset_changes(f, s)
	      || data_member_offset_changed(f, s)
	      || non_static_data_member_type_size_changed(f, s)
	      || non_static_data_member_added_or_removed(d)
	      || base_classes_removed(d)
	      || has_harmful_enum_change(d)
	      || crc_changed(d)
	      || namespace_changed(d)))
	category |= SIZE_OR_OFFSET_CHANGE_CATEGORY;

      if (has_virtual_mem_fn_change(d))
	category |= VIRTUAL_MEMBER_CHANGE_CATEGORY;

      if (has_added_or_removed_function_parameters(d))
	category |= FN_PARM_ADD_REMOVE_CHANGE_CATEGORY;

      if (category)
	{
	  d->add_to_local_and_inherited_categories(category);
	  // Update the category of the canonical diff node too.
	  if (diff * canonical = d->get_canonical_diff())
	    canonical->add_to_local_and_inherited_categories(category);
	}
    }

  return true;
}

/// The visiting code of the harmless_harmful_filter.
///
/// @param d the diff node being visited.
///
/// @param pre this is true iff the node is being visited *before* the
/// children nodes of @p d.
///
/// @return true iff the traversal shall keep going after the
/// completion of this function.
bool
harmless_harmful_filter::visit(diff* d, bool pre)
{
  return (categorize_harmless_diff_node(d, pre)
	  && categorize_harmful_diff_node(d, pre));
}

/// Part of the visiting code of the harmless_harmful_filter.
///
/// This function is called after the visiting of a given diff node.
/// Note that when this function is called, the visiting might not
/// have taken place *if* the node (or an equivalent node) has already
/// been visited.
///
/// @param d the diff node that has either been visited or skipped
/// (because it has already been visited during this traversing).
void
harmless_harmful_filter::visit_end(diff* d)
{
  if (d->context()->diff_has_been_visited(d))
    {
      // This node or one of its equivalent node has already been
      // visited.  That means at this moment,
      // harmless_harmful_filter::visit() has *not* been called prior
      // to this harmless_harmful_filter::visit_end() is called.  In
      // other words, only harmless_harmful_filter::visit_begin() and
      // harmless_harmful_filter::visit_end() are called.
      //
      // So let's update the category of this diff node from its
      // canonical node.
      if (diff* c = d->get_canonical_diff())
	d->add_to_local_and_inherited_categories(c->get_local_category());
    }
}
} // end namespace filtering
} // end namespace comparison
} // end namespace abigail
