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

/// @file
///
/// This contains the implementation of the suppression engine of
/// libabigail.

#include <algorithm>

#include "abg-internal.h"
#include <memory>
#include <limits>

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

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

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

#include "abg-suppression-priv.h"

namespace abigail
{

namespace suppr
{

using std::dynamic_pointer_cast;
using regex::regex_t_sptr;

// <parsing stuff>

// section parsing

/// Check if a section has at least one of the given properties.
///
/// @param names pointer to the start of an array of names.
///
/// @param count number of names in the array.
///
/// @return whether at least of one the properties was found.
bool
check_sufficient_props(const char *const * names, size_t count,
		       const ini::config::section& section)
{
  for (const char *const * name = names; name < names + count; ++name)
    if (section.find_property(*name))
      return true;
  // TODO: Possibly give reason for failure in a message here.
  return false;
}

// </parsing stuff>

// <suppression_base stuff>

/// Constructor for @ref suppression_base
///
/// @param a label for the suppression.  This represents just a
/// comment.
suppression_base::suppression_base(const string& label)
  : priv_(new priv(label))
{}

/// Constructor for @ref suppression_base
///
/// @param a label for the suppression.  This represents just a
/// comment.
///
/// @param file_name_regex_str the regular expression that denotes the
/// file name to match.
///
/// @param file_name_not_regex_str the regular expression that denotes
/// the file name to *NOT* match.
suppression_base::suppression_base(const string& label,
				   const string& file_name_regex_str,
				   const string& file_name_not_regex_str)
  : priv_(new priv(label,
		   file_name_regex_str,
		   file_name_not_regex_str))
{
}

/// Tests if the current suppression specification is to avoid adding
/// the matched ABI artifact to the internal representation or not.
///
/// @return true iff the current suppression specification is to avoid
/// adding the matched ABI artifact to the internal representation.
bool
suppression_base::get_drops_artifact_from_ir() const
{return priv_->drops_artifact_;}

/// Set the flag that says whether the current suppression
/// specification is to avoid adding the matched ABI artifact to the
/// internal representation or not.
///
/// @param f the flag to set to true iff the current suppression
/// specification is to avoid adding the matched ABI artifact to the
/// internal representation.
void
suppression_base::set_drops_artifact_from_ir(bool f)
{priv_->drops_artifact_ = f;}

/// Test is the suppression specification is artificial.
///
/// Artificial means that the suppression was automatically generated
/// by libabigail, rather than being constructed from a suppression
/// file provided by the user.
///
/// @return TRUE iff the suppression specification is artificial.
bool
suppression_base::get_is_artificial() const
{return priv_->is_artificial_;}

/// Set a flag saying if the suppression specification is artificial
/// or not.
///
/// Artificial means that the suppression was automatically generated
/// by libabigail, rather than being constructed from a suppression
/// file provided by the user.
void
suppression_base::set_is_artificial(bool f)
{priv_->is_artificial_ = f;}

/// Getter for the label associated to this suppression specification.
///
/// @return the label.
const string
suppression_base::get_label() const
{return priv_->label_;}

/// Setter for the label associated to this suppression specification.
///
/// @param label the new label.
void
suppression_base::set_label(const string& label)
{priv_->label_ = label;}

/// Setter for the "file_name_regex" property of the current instance
/// of @ref suppression_base.
///
/// The "file_name_regex" property is a regular expression string that
/// designates the file name that contains the ABI artifact this
/// suppression should apply to.
///
/// @param regexp the new regular expression string.
void
suppression_base::set_file_name_regex_str(const string& regexp)
{priv_->file_name_regex_str_ = regexp;}

/// Getter for the "file_name_regex" property of the current instance
/// of @ref suppression_base.
///
/// The "file_name_regex" property is a regular expression string that
/// designates the file name that contains the ABI artifacts this
/// suppression should apply to.
///
/// @return the regular expression string.
const string&
suppression_base::get_file_name_regex_str() const
{return priv_->file_name_regex_str_;}

/// Setter for the "file_name_not_regex" property of the current
/// instance of @ref suppression_base.
///
/// The current suppression specification should apply to ABI
/// artifacts of a file which name does *NOT* match the regular
/// expression string designated by the "file_name_not_regex"
/// property.
///
/// @param regexp the new regular expression string.
void
suppression_base::set_file_name_not_regex_str(const string& regexp)
{priv_->file_name_not_regex_str_ = regexp;}

/// Getter for the "file_name_not_regex" property of the current
/// instance of @ref suppression_base.
///
/// The current suppression specification should apply to ABI
/// artifacts of a file which name does *NOT* match the regular
/// expression string designated by the "file_name_not_regex"
/// property.
///
/// @return the regular expression string.
const string&
suppression_base::get_file_name_not_regex_str() const
{return priv_->file_name_not_regex_str_;}

/// Test if the current suppression has a property related to file
/// name.
///
/// @return true iff the current suppression has either a
/// file_name_regex or a file_name_not_regex property.
bool
suppression_base::has_file_name_related_property() const
{
  return (!(get_file_name_regex_str().empty()
	    && get_file_name_not_regex_str().empty()));
}

/// Setter of the "soname_regex_str property of the current instance
/// of @ref suppression_base.
///
/// The "soname_regex_str" is a regular expression string that
/// designates the soname of the shared library that contains the ABI
/// artifacts this suppression should apply to.
///
/// @param regexp the new regular expression string.
void
suppression_base::set_soname_regex_str(const string& regexp)
{priv_->soname_regex_str_ = regexp;}

/// Getter of the "soname_regex_str property of the current instance
/// of @ref suppression_base.
///
/// The "soname_regex_str" is a regular expression string that
/// designates the soname of the shared library that contains the ABI
/// artifacts this suppression should apply to.
///
/// @return the regular expression string.
const string&
suppression_base::get_soname_regex_str() const
{return priv_->soname_regex_str_;}

/// Setter of the "soname_not_regex_str property of the current
/// instance of @ref suppression_base.
///
/// The current suppression specification should apply to ABI
/// artifacts of a shared library which SONAME does *NOT* match the
/// regular expression string designated by the "soname_not_regex"
/// property.
///
/// @param regexp the new regular expression string.
void
suppression_base::set_soname_not_regex_str(const string& regexp)
{priv_->soname_not_regex_str_ = regexp;}

/// Getter of the "soname_not_regex_str property of the current
/// instance of @ref suppression_base.
///
/// The current suppression specification should apply to ABI
/// artifacts of a shared library which SONAME does *NOT* match the
/// regular expression string designated by the "soname_not_regex"
/// property.
///
/// @return the regular expression string.
const string&
suppression_base::get_soname_not_regex_str() const
{return priv_->soname_not_regex_str_;}

/// Test if the current suppression has a property related to SONAMEs.
///
/// @return true iff the current suppression has either a soname_regex
/// or a soname_not_regex property.
bool
suppression_base::has_soname_related_property() const
{
  return (!(get_soname_regex_str().empty()
	    && get_soname_not_regex_str().empty()));
}

/// Check if the SONAMEs of the two binaries being compared match the
/// content of the properties "soname_regexp" and "soname_not_regexp"
/// of the current suppression specification.
///
/// @param suppr the suppression specification
///
/// @param ctxt the context of the comparison.
///
/// @return false if the regular expression contained in the property
/// soname_regexp or in the property "soname_not_regexp" does *NOT*
/// match at least one of the SONAMEs of the two binaries being
/// compared.  Return true otherwise.
static bool
sonames_of_binaries_match(const suppression_base& suppr,
			  const diff_context& ctxt)
{
  // Check if the sonames of the binaries match
  string first_soname = ctxt.get_corpus_diff()->first_corpus()->get_soname(),
    second_soname = ctxt.get_corpus_diff()->second_corpus()->get_soname();

  if (!suppr.has_soname_related_property())
    return false;

  if (!suppr.priv_->matches_soname(first_soname)
      && !suppr.priv_->matches_soname(second_soname))
    return false;

  return true;
}

/// Check if the names of the two binaries being compared match the
/// content of the properties "file_name_regexp" and
/// "file_name_not_regexp".
///
/// @param suppr the current suppression specification.
///
/// @param ctxt the context of the comparison.
///
/// @return false if the regular expression contained in the property
/// file_name_regexp or in the property "file_name_not_regexp" does
/// *NOT* match at least one of the names of the two binaries being
/// compared.  Return true otherwise.
static bool
names_of_binaries_match(const suppression_base& suppr,
			const diff_context &ctxt)
{
   // Check if the file names of the binaries match
  string first_binary_path = ctxt.get_corpus_diff()->first_corpus()->get_path(),
    second_binary_path = ctxt.get_corpus_diff()->second_corpus()->get_path();

  if (!suppr.has_file_name_related_property())
    return false;

  if (!suppr.priv_->matches_binary_name(first_binary_path)
      && !suppr.priv_->matches_binary_name(second_binary_path))
    return false;

  return true;
}

suppression_base::~suppression_base()
{}

static type_suppression_sptr
read_type_suppression(const ini::config::section& section);

static function_suppression_sptr
read_function_suppression(const ini::config::section& section);

static variable_suppression_sptr
read_variable_suppression(const ini::config::section& section);

static file_suppression_sptr
read_file_suppression(const ini::config::section& section);

/// Read a vector of suppression specifications from the sections of
/// an ini::config.
///
/// Note that this function needs to be updated each time a new kind
/// of suppression specification is added.
///
/// @param config the config to read from.
///
/// @param suppressions out parameter.  The vector of suppressions to
/// append the newly read suppressions to.
static void
read_suppressions(const ini::config& config,
		  suppressions_type& suppressions)
{
  suppression_sptr s;
  for (ini::config::sections_type::const_iterator i =
	 config.get_sections().begin();
       i != config.get_sections().end();
       ++i)
    if ((s = read_type_suppression(**i))
	|| (s = read_function_suppression(**i))
	|| (s = read_variable_suppression(**i))
	|| (s = read_file_suppression(**i)))
      suppressions.push_back(s);

}

/// Read suppressions specifications from an input stream.
///
/// @param input the input stream to read from.
///
/// @param suppressions the vector of suppressions to append the newly
/// read suppressions to.
void
read_suppressions(std::istream& input,
		  suppressions_type& suppressions)
{
    if (ini::config_sptr config = ini::read_config(input))
    read_suppressions(*config, suppressions);
}

/// Read suppressions specifications from an input file on disk.
///
/// @param input the path to the input file to read from.
///
/// @param suppressions the vector of suppressions to append the newly
/// read suppressions to.
void
read_suppressions(const string& file_path,
		  suppressions_type& suppressions)
{
  if (ini::config_sptr config = ini::read_config(file_path))
    read_suppressions(*config, suppressions);
}
// </suppression_base stuff>

// <type_suppression stuff>

/// Constructor for @ref type_suppression.
///
/// @param label the label of the suppression.  This is just a free
/// form comment explaining what the suppression is about.
///
/// @param type_name_regexp the regular expression describing the
/// types about which diff reports should be suppressed.  If it's an
/// empty string, the parameter is ignored.
///
/// @param type_name the name of the type about which diff reports
/// should be suppressed.  If it's an empty string, the parameter is
/// ignored.
///
/// Note that parameter @p type_name_regexp and @p type_name_regexp
/// should not necessarily be populated.  It usually is either one or
/// the other that the user wants.
type_suppression::type_suppression(const string& label,
				   const string& type_name_regexp,
				   const string& type_name)
  : suppression_base(label),
    priv_(new priv(type_name_regexp,
		   type_name,
		   /*consider_type_kind=*/false,
		   /*type_kind=*/CLASS_TYPE_KIND,
		   /*consider_reach_kind=*/false,
		   /*reach_kind=*/DIRECT_REACH_KIND))
{}

type_suppression::~type_suppression()
{}

/// Setter for the "type_name_regex" property of the type suppression
/// specification.
///
/// This sets a regular expression that specifies the family of types
/// about which diff reports should be suppressed.
///
/// @param name_regex_str the new regular expression to set.
void
type_suppression::set_type_name_regex_str(const string& name_regex_str)
{priv_->type_name_regex_str_ = name_regex_str;}

/// Getter for the "type_name_regex" property of the type suppression
/// specification.
///
/// This returns a regular expression string that specifies the family
/// of types about which diff reports should be suppressed.
///
/// @return the regular expression string.
const string&
type_suppression::get_type_name_regex_str() const
{return priv_->type_name_regex_str_;}

/// Setter for the "type_name_not_regex_str" property of the type
/// suppression specification.
///
/// This returns a regular expression string that specifies the family
/// of types that should be kept after suppression.
///
/// @param r the new regexp string.
void
type_suppression::set_type_name_not_regex_str(const string& r)
{priv_->set_type_name_not_regex_str(r);}

/// Getter for the "type_name_not_regex_str" property of the type
/// suppression specification.
///
/// This returns a regular expression string that specifies the family
/// of types that should be kept after suppression.
///
/// @return the new regexp string.
const string&
type_suppression::get_type_name_not_regex_str() const
{return priv_->get_type_name_not_regex_str();}

/// Setter for the name of the type about which diff reports should be
/// suppressed.
///
/// @param name the new type name.
void
type_suppression::set_type_name(const string& name)
{priv_->type_name_ = name;}

/// Getter for the name of the type about which diff reports should be
/// suppressed.
///
/// @param return the type name.
const string&
type_suppression::get_type_name() const
{return priv_->type_name_;}

/// Getter of the property that says whether to consider the kind of
/// type this suppression is about.
///
/// @return the boolean value of the property.
bool
type_suppression::get_consider_type_kind() const
{return priv_->consider_type_kind_;}

/// Setter of the property that says whether to consider the kind of
/// type this suppression is about.
///
/// @param f the new boolean value of the property.
void
type_suppression::set_consider_type_kind(bool f)
{priv_->consider_type_kind_ = f;}

/// Setter of the kind of type this suppression is about.
///
/// Note that this will be considered during evaluation of the
/// suppression only if type_suppression::get_consider_type_kind()
/// returns true.
///
/// @param k the new kind of type this suppression is about.
void
type_suppression::set_type_kind(type_kind k)
{priv_->type_kind_ = k;}

/// Getter of the kind of type this suppression is about.
///
/// Note that this will be considered during evaluation of the
/// suppression only if type_suppression::get_consider_type_kind()
/// returns true.
///
/// @return the kind of type this suppression is about.
type_suppression::type_kind
type_suppression::get_type_kind() const
{return priv_->type_kind_;}

/// Test if the current type suppression specification
/// suggests to consider how the matching diff node is reached.
///
/// @return true if the current type suppression specification
/// suggests to consider how the matching diff node is reached.
bool
type_suppression::get_consider_reach_kind() const
{return priv_->consider_reach_kind_;}

/// Set a flag saying if the current type suppression specification
/// suggests to consider how the matching diff node is reached.
///
/// @param f the new value of the flag.  It's true iff the current
/// type suppression specification suggests to consider how the
/// matching diff node is reached.
void
type_suppression::set_consider_reach_kind(bool f)
{priv_->consider_reach_kind_ = f;}

/// Getter of the way the diff node matching the current suppression
/// specification is to be reached.
///
/// @return the way the diff node matching the current suppression
/// specification is to be reached.
type_suppression::reach_kind
type_suppression::get_reach_kind() const
{return priv_->reach_kind_;}

/// Setter of the way the diff node matching the current suppression
/// specification is to be reached.
///
/// @param p the way the diff node matching the current suppression
/// specification is to be reached.
void
type_suppression::set_reach_kind(reach_kind k)
{priv_->reach_kind_ = k;}

/// Setter for the vector of data member insertion ranges that
/// specifies where a data member is inserted as far as this
/// suppression specification is concerned.
///
/// @param r the new insertion range vector.
void
type_suppression::set_data_member_insertion_ranges(const insertion_ranges& r)
{priv_->insertion_ranges_ = r;}

/// Getter for the vector of data member insertion range that
/// specifiers where a data member is inserted as far as this
/// suppression specification is concerned.
///
/// @return the vector of insertion ranges.
const type_suppression::insertion_ranges&
type_suppression::get_data_member_insertion_ranges() const
{return priv_->insertion_ranges_;}

/// Getter for the vector of data member insertion range that
/// specifiers where a data member is inserted as far as this
/// suppression specification is concerned.
///
/// @return the vector of insertion ranges.
type_suppression::insertion_ranges&
type_suppression::get_data_member_insertion_ranges()
{return priv_->insertion_ranges_;}

/// Getter for the array of source location paths of types that should
/// *NOT* be suppressed.
///
/// @return the set of source locations of types that should *NOT* be
/// supressed.
const unordered_set<string>&
type_suppression::get_source_locations_to_keep() const
{return priv_->source_locations_to_keep_;}

/// Getter for the array of source location paths of types that should
/// *NOT* be suppressed.
///
/// @return the array of source locations of types that should *NOT*
/// be supressed.
unordered_set<string>&
type_suppression::get_source_locations_to_keep()
{return priv_->source_locations_to_keep_;}

/// Setter for the array of source location paths of types that should
/// *NOT* be suppressed.
///
/// @param l the new array.
void
type_suppression::set_source_locations_to_keep
(const unordered_set<string>& l)
{priv_->source_locations_to_keep_ = l;}

/// Getter of the regular expression string that designates the source
/// location paths of types that should not be suppressed.
///
/// @return the regular expression string.
const string&
type_suppression::get_source_location_to_keep_regex_str() const
{return priv_->source_location_to_keep_regex_str_;}

/// Setter of the regular expression string that designates the source
/// location paths of types that should not be suppressed.
///
/// @param r the new regular expression.
void
type_suppression::set_source_location_to_keep_regex_str(const string& r)
{priv_->source_location_to_keep_regex_str_ = r;}

/// Getter of the vector of the changed enumerators that are supposed
/// to be suppressed.  Note that this will be "valid" only if the type
/// suppression has the 'type_kind = enum' property.
///
/// @return the vector of the changed enumerators that are supposed to
/// be suppressed.
const vector<string>&
type_suppression::get_changed_enumerator_names() const
{return priv_->changed_enumerator_names_;}

/// Setter of the vector of changed enumerators that are supposed to
/// be suppressed.  Note that this will be "valid" only if the type
/// suppression has the 'type_kind = enum' property.
///
/// @param n the vector of the changed enumerators that are supposed
/// to be suppressed.
void
type_suppression::set_changed_enumerator_names(const vector<string>& n)
{priv_->changed_enumerator_names_ = n;}

/// Evaluate this suppression specification on a given diff node and
/// say if the diff node should be suppressed or not.
///
/// @param diff the diff node to evaluate this suppression
/// specification against.
///
/// @return true if @p diff should be suppressed.
bool
type_suppression::suppresses_diff(const diff* diff) const
{
  const type_diff_base* d = is_type_diff(diff);
  if (!d)
    {
      // So the diff we are looking at is not a type diff.  However,
      // there are cases where a type suppression can suppress changes
      // on functions.

      // Typically, if a virtual member function's virtual index (its
      // index in the vtable of a class) changes and if the current
      // type suppression is meant to suppress change reports about
      // the enclosing class of the virtual member function, then this
      // type suppression should suppress reports about that function
      // change.
      const function_decl_diff* d = is_function_decl_diff(diff);
      if (d)
	{
	  // Let's see if 'd' carries a virtual member function
	  // change.
	  if (comparison::filtering::has_virtual_mem_fn_change(d))
	    {
	      function_decl_sptr f = d->first_function_decl();
	      class_decl_sptr fc =
		is_class_type(is_method_type(f->get_type())->get_class_type());
	      ABG_ASSERT(fc);
	      if (suppresses_type(fc, diff->context()))
		return true;
	    }
	}
      return false;
    }

  // If the suppression should consider the way the diff node has been
  // reached, then do it now.
  if (get_consider_reach_kind())
    {
      if (get_reach_kind() == POINTER_REACH_KIND)
	{
	  if (const pointer_diff* ptr_diff = is_pointer_diff(diff))
	    {
	      d = is_type_diff(ptr_diff->underlying_type_diff().get());
	      if (!d)
		// This might be of, e.g, distinct_diff type.
		return false;
	      d = is_type_diff(peel_qualified_diff(d));
	    }
	  else
	    return false;
	}
      else if (get_reach_kind() == REFERENCE_REACH_KIND)
	{
	  if (const reference_diff* ref_diff = is_reference_diff(diff))
	    {
	      d = is_type_diff(ref_diff->underlying_type_diff().get());
	      if (!d)
		// This might be of, e.g, distinct_diff type.
		return false;
	      d = is_type_diff(peel_qualified_diff(d));
	    }
	  else
	    return false;
	}
      else if (get_reach_kind() == REFERENCE_OR_POINTER_REACH_KIND)
	{
	  if (const pointer_diff* ptr_diff = is_pointer_diff(diff))
	    {
	      d = is_type_diff(ptr_diff->underlying_type_diff().get());
	      ABG_ASSERT(d);
	      d = is_type_diff(peel_qualified_diff(d));
	    }
	  else if (const reference_diff* ref_diff = is_reference_diff(diff))
	    {
	      d = is_type_diff(ref_diff->underlying_type_diff().get());
	      ABG_ASSERT(d);
	      d = is_type_diff(peel_qualified_diff(d));
	    }
	  else
	    return false;
	}
    }

  type_base_sptr ft, st;
  ft = is_type(d->first_subject());
  st = is_type(d->second_subject());
  ABG_ASSERT(ft && st);

  if (!suppresses_type(ft, d->context())
      && !suppresses_type(st, d->context()))
    {
      // A private type suppression specification considers that a
      // type can be private and yet some typedefs of that type can be
      // public -- depending on, e.g, if the typedef is defined in a
      // public header or not.  So if we are in the context of a
      // private type suppression let's *NOT* peel typedefs away.
      if (!is_private_type_suppr_spec(*this))
	{
	  ft = peel_typedef_type(ft);
	  st = peel_typedef_type(st);
	}

      if (!suppresses_type(ft, d->context())
	  && !suppresses_type(st, d->context()))
	return false;

      d = is_type_diff(get_typedef_diff_underlying_type_diff(d));
    }

  // Now let's consider class diffs in the context of a suppr spec
  // that contains properties like "has_data_member_inserted_*".

  const class_diff* klass_diff = dynamic_cast<const class_diff*>(d);
  if (klass_diff)
    {
      // We are looking at a class diff ...
      if (!get_data_member_insertion_ranges().empty())
	{
	  // ... and the suppr spec contains a
	  // "has_data_member_inserted_*" clause ...
	  if (klass_diff->deleted_data_members().empty()
	      && (klass_diff->first_class_decl()->get_size_in_bits()
		  <= klass_diff->second_class_decl()->get_size_in_bits()))
	    {
	      // That "has_data_member_inserted_*" clause doesn't hold
	      // if the class has deleted data members or shrunk.

	      const class_decl_sptr& first_type_decl =
		klass_diff->first_class_decl();

	      for (string_decl_base_sptr_map::const_iterator m =
		     klass_diff->inserted_data_members().begin();
		   m != klass_diff->inserted_data_members().end();
		   ++m)
		{
		  decl_base_sptr member = m->second;
		  size_t dm_offset = get_data_member_offset(member);
		  bool matched = false;

		  for (insertion_ranges::const_iterator i =
			 get_data_member_insertion_ranges().begin();
		       i != get_data_member_insertion_ranges().end();
		       ++i)
		    {
		      type_suppression::insertion_range_sptr range = *i;
		      uint64_t range_begin_val = 0, range_end_val = 0;
		      if (!type_suppression::insertion_range::eval_boundary
			  (range->begin(), first_type_decl, range_begin_val))
			break;
		      if (!type_suppression::insertion_range::eval_boundary
			  (range->end(), first_type_decl, range_end_val))
			break;

		      uint64_t range_begin = range_begin_val;
		      uint64_t range_end = range_end_val;

		      if (insertion_range::boundary_value_is_end(range_begin)
			  && insertion_range::boundary_value_is_end(range_end))
			{
			  // This idiom represents the predicate
			  // "has_data_member_inserted_at = end"
			  if (dm_offset >
			      get_data_member_offset(get_last_data_member
						     (first_type_decl)))
			    {
			      // So the data member was added after
			      // last data member of the klass.  That
			      // matches the suppr spec
			      // "has_data_member_inserted_at = end".
			      matched = true;
			      continue;
			    }
			}

			if (range_begin > range_end)
			  // Wrong suppr spec.  Ignore it.
			  continue;

		      if (dm_offset < range_begin || dm_offset > range_end)
			// The offset of the added data member doesn't
			// match the insertion range specified.  So
			// the diff object won't be suppressed.
			continue;

		      // If we reached this point, then all the
		      // insertion range constraints have been
		      // satisfied.  So
		      matched = true;
		    }
		  if (!matched)
		    return false;
		}
	    }
	  else
	    return false;
	}
    }

  const enum_diff* enum_dif = dynamic_cast<const enum_diff*>(d);
  if (// We are looking at an enum diff node which ...
      enum_dif
      //... carries no deleted enumerator ... "
      && enum_dif->deleted_enumerators().empty()
      // ... carries no size change ...
      && (enum_dif->first_enum()->get_size_in_bits()
	  == enum_dif->second_enum()->get_size_in_bits())
      // ... and yet carries some changed enumerators!
      && !enum_dif->changed_enumerators().empty())
    {
      // Make sure that all changed enumerators are listed in the
      // vector of enumerator names returned by the
      // get_changed_enumerator_names() member function.
      bool matched = true;
      for (string_changed_enumerator_map::const_iterator i =
	     enum_dif->changed_enumerators().begin();
	   i != enum_dif->changed_enumerators().end();
	   ++i)
	{
	  matched &= true;
	  if (std::find(get_changed_enumerator_names().begin(),
			get_changed_enumerator_names().end(),
			i->first) == get_changed_enumerator_names().end())
	    {
	      matched &= false;
	      break;
	    }
	}
      if (!matched)
	return false;
    }

  return true;
}

/// Test if the current instance of @ref type_suppression suppresses a
/// change reports about a given type.
///
/// @param type the type to consider.
///
/// @param ctxt the context of comparison we are involved with.
///
/// @return true iff the suppression specification suppresses type @p
/// type.
bool
type_suppression::suppresses_type(const type_base_sptr& type,
				  const diff_context_sptr& ctxt) const
{
  if (ctxt)
    {
      // Check if the names of the binaries match the suppression
      if (!names_of_binaries_match(*this, *ctxt))
	if (has_file_name_related_property())
	  return false;

      // Check if the sonames of the binaries match the suppression
      if (!sonames_of_binaries_match(*this, *ctxt))
	if (has_soname_related_property())
	  return false;
    }

  return suppresses_type(type);
}

/// Test if an instance of @ref type_suppression matches a given type.
///
/// This function does not take the name of the type into account
/// while testing if the type matches the type_suppression.
///
/// @param s the suppression to evaluate.
///
/// @param type the type to consider.
///
/// @return true iff the suppression specification matches type @p
/// type without taking its name into account.
static bool
suppression_matches_type_no_name(const type_suppression&	 s,
				 const type_base_sptr		&type)
{
  // If the suppression should consider type kind then, well, check
  // for that.
  if (s.get_consider_type_kind())
    {
      type_suppression::type_kind tk = s.get_type_kind();
      bool matches = true;
      switch (tk)
	{
	case type_suppression::UNKNOWN_TYPE_KIND:
	case type_suppression::CLASS_TYPE_KIND:
	  if (!is_class_type(type))
	    matches = false;
	  break;
	case type_suppression::STRUCT_TYPE_KIND:
	  {
	    class_decl_sptr klass = is_class_type(type);
	    if (!klass || !klass->is_struct())
	      matches = false;
	  }
	  break;
	case type_suppression::UNION_TYPE_KIND:
	  if (!is_union_type(type))
	    matches = false;
	  break;
	case type_suppression::ENUM_TYPE_KIND:
	  if (!is_enum_type(type))
	    matches = false;
	  break;
	case type_suppression::ARRAY_TYPE_KIND:
	  if (!is_array_type(type))
	    matches = false;
	  break;
	case type_suppression::TYPEDEF_TYPE_KIND:
	  if (!is_typedef(type))
	    matches = false;
	  break;
	case type_suppression::BUILTIN_TYPE_KIND:
	  if (!is_type_decl(type))
	    matches = false;
	  break;
	}

      if (!matches)
	return false;
    }

  // Check if there is a source location related match.
  if (!suppression_matches_type_location(s, type))
    return false;

  return true;
}

/// Test if a type suppression specification matches a type name.
///
/// @param s the type suppression to consider.
///
/// @param type_name the type name to consider.
///
/// @return true iff the type designated by its name @p type_name is
/// matched by the type suppression specification @p s.
bool
suppression_matches_type_name(const type_suppression&	s,
			      const string&		type_name)
{
  if (!s.get_type_name().empty()
      || s.priv_->get_type_name_regex()
      || s.priv_->get_type_name_not_regex())
    {
      // Check if there is an exact type name match.
      if (!s.get_type_name().empty())
	{
	  if (s.get_type_name() != type_name)
	    return false;
	}
      else
	{
	  // Now check if there is a regular expression match.
	  //
	  // If the qualified name of the considered type doesn't match
	  // the regular expression of the type name, then this
	  // suppression doesn't apply.
	  if (const regex_t_sptr& type_name_regex =
	      s.priv_->get_type_name_regex())
	    {
	      if (!regex::match(type_name_regex, type_name))
		return false;
	    }

	  if (const regex_t_sptr type_name_not_regex =
	      s.priv_->get_type_name_not_regex())
	    {
	      if (regex::match(type_name_not_regex, type_name))
		return false;
	    }
	}
    }

  return true;
}

/// Test if a type suppression matches a type in a particular scope.
///
/// @param s the type suppression to consider.
///
/// @param type_scope the scope of the type to consider.
///
/// @param type the type to consider.
///
/// @return true iff the supression @p s matches type @p type in scope
/// @p type_scope.
bool
suppression_matches_type_name(const suppr::type_suppression&	s,
			      const scope_decl*		type_scope,
			      const type_base_sptr&		type)
{
  string type_name = build_qualified_name(type_scope, type);
  return suppression_matches_type_name(s, type_name);
}

/// Test if a type suppression matches a source location.
///
/// @param s the type suppression to consider.
///
/// @param loc the location to consider.
///
/// @return true iff the suppression @p s matches location @p loc.
bool
suppression_matches_type_location(const type_suppression&	s,
				  const location&		loc)
{
  if (loc)
    {
      // Check if there is a source location related match.
      string loc_path, loc_path_base;
      unsigned loc_line = 0, loc_column = 0;
      loc.expand(loc_path, loc_line, loc_column);

      if (regex_t_sptr regexp = s.priv_->get_source_location_to_keep_regex())
	if (regex::match(regexp, loc_path))
	  return false;

      tools_utils::base_name(loc_path, loc_path_base);
      if (s.get_source_locations_to_keep().find(loc_path_base)
	  != s.get_source_locations_to_keep().end())
	return false;
      if (s.get_source_locations_to_keep().find(loc_path)
	  != s.get_source_locations_to_keep().end())
	return false;
    }
  else
    {
      if (!s.get_source_locations_to_keep().empty()
	  || s.priv_->get_source_location_to_keep_regex())
	// The user provided a "source_location_not_regexp" or
	// a "source_location_not_in" property that was not
	// triggered.  This means the current type suppression
	// doesn't suppress the type given.
	return false;
    }

  return true;
}

/// Test if a type suppression matches a type.
///
/// @param s the type suppression to consider.
///
/// @param type the type to consider.
///
/// @return true iff the suppression @p s matches type @p type.
bool
suppression_matches_type_location(const type_suppression&	s,
				  const type_base_sptr&	type)
{
  location loc = get_location(type);
  if (loc)
    return suppression_matches_type_location(s, loc);
  else
    {
      // The type had no source location.
      //
      // In the case where this type suppression was automatically
      // generated to suppress types not defined in public
      // headers, then this might mean that the type is not
      // defined in the public headers.  Otherwise, why does it
      // not have a source location?
      if (s.get_is_artificial())
	{
	  if (class_decl_sptr cl = is_class_type(type))
	    {
	      if (cl->get_is_declaration_only())
		// We tried hard above to get the definition of
		// the declaration.  If we reach this place, it
		// means the class has no definition at this point.
		ABG_ASSERT(!cl->get_definition_of_declaration());
	      if (s.get_label() == get_private_types_suppr_spec_label())
		// So this looks like what really amounts to an
		// opaque type.  So it's not defined in the public
		// headers.  So we want to filter it out.
		return true;
	    }
	}
      if (!s.get_source_locations_to_keep().empty()
	  || s.priv_->get_source_location_to_keep_regex())
	// The user provided a "source_location_not_regexp" or
	// a "source_location_not_in" property that was not
	// triggered.  This means the current type suppression
	// doesn't suppress the type given.
	return false;
    }

  return true;
}

/// Test if a type suppression matches a type name and location.
///
/// @param s the type suppression to consider.
///
/// @param type_name the name of the type to consider.
///
/// @param type_location the location of the type to consider.
///
/// @return true iff suppression @p s matches a type named @p
/// type_name with a location @p type_location.
bool
suppression_matches_type_name_or_location(const type_suppression& s,
					  const string& type_name,
					  const location& type_location)
{
  if (!suppression_matches_type_name(s, type_name))
    return false;
  if (!suppression_matches_type_location(s, type_location))
    return false;
  return true;
}

/// Test if the current instance of @ref type_suppression matches a
/// given type.
///
/// @param type the type to consider.
///
/// @return true iff the suppression specification suppresses type @p
/// type.
bool
type_suppression::suppresses_type(const type_base_sptr& type) const
{
  if (!suppression_matches_type_no_name(*this, type))
    return false;

  if (!suppression_matches_type_name(*this, get_name(type)))
    return false;

  return true;
}

/// Test if the current instance of @ref type_suppression matches a
/// given type in a given scope.
///
/// @param type the type to consider.
///
/// @param type_scope the scope of type @p type.
///
/// @return true iff the suppression specification suppresses type @p
/// type from scope @p type_scope.
bool
type_suppression::suppresses_type(const type_base_sptr& type,
				  const scope_decl* type_scope) const
{
  if (!suppression_matches_type_no_name(*this, type))
    return false;

  if (!suppression_matches_type_name(*this, type_scope, type))
    return false;

  return true;
}

/// The private data of type_suppression::insertion_range
struct type_suppression::insertion_range::priv
{
  boundary_sptr begin_;
  boundary_sptr end_;

  priv()
  {}

  priv(boundary_sptr begin, boundary_sptr end)
    : begin_(begin), end_(end)
  {}
}; // end struct type_suppression::insertion_range::priv

/// Default Constructor of @ref type_suppression::insertion_range.
type_suppression::insertion_range::insertion_range()
  : priv_(new priv)
{}

/// Constructor of @ref type_suppression::insertion_range.
///
/// @param begin the start of the range.  A range boundary that is an
/// instance of @ref interger_boundary with a negative value means the
/// maximum possible value.
///
/// @param end the end of the range.  A range boundary that is an
/// instance of @ref interger_boundary with a negative value means the
/// maximum possible value.
type_suppression::insertion_range::insertion_range(boundary_sptr begin,
						   boundary_sptr end)
  : priv_(new priv(begin, end))
{}

/// Getter for the beginning of the range.
///
/// @return the beginning of the range.  A range boundary that is an
/// instance of @ref interger_boundary with a negative value means the
/// maximum possible value.
type_suppression::insertion_range::boundary_sptr
type_suppression::insertion_range::begin() const
{return priv_->begin_;}

/// Getter for the end of the range.
///
/// @return the end of the range.  A range boundary that is an
/// instance of @ref interger_boundary with a negative value means the
/// maximum possible value.
type_suppression::insertion_range::boundary_sptr
type_suppression::insertion_range::end() const
{return priv_->end_;}

/// Create an integer boundary.
///
/// The return value of this function is to be used as a boundary for
/// an instance of @ref type_suppression::insertion_range.  That
/// boundary evaluates to an integer value.
///
/// @param value the value of the integer boundary.
///
/// @return the resulting integer boundary.
type_suppression::insertion_range::integer_boundary_sptr
type_suppression::insertion_range::create_integer_boundary(int value)
{return integer_boundary_sptr(new integer_boundary(value));}

/// Create a function call expression boundary.
///
/// The return value of this function is to be used as a boundary for
/// an instance of @ref type_suppression::insertion_range.  The value
/// of that boundary is actually a function call expression that
/// itself evalutates to an integer value, in the context of a @ref
/// class_decl.
///
/// @param expr the function call expression to create the boundary from.
///
/// @return the resulting function call expression boundary.
type_suppression::insertion_range::fn_call_expr_boundary_sptr
type_suppression::insertion_range::create_fn_call_expr_boundary(ini::function_call_expr_sptr expr)
{return fn_call_expr_boundary_sptr(new fn_call_expr_boundary(expr));}

/// Create a function call expression boundary.
///
/// The return value of this function is to be used as a boundary for
/// an instance of @ref type_suppression::insertion_range.  The value
/// of that boundary is actually a function call expression that
/// itself evalutates to an integer value, in the context of a @ref
/// class_decl.
///
/// @param s a string representing the expression the function call
/// expression to create the boundary from.
///
/// @return the resulting function call expression boundary.
type_suppression::insertion_range::fn_call_expr_boundary_sptr
type_suppression::insertion_range::create_fn_call_expr_boundary(const string& s)
{
  fn_call_expr_boundary_sptr result, nil;
  ini::function_call_expr_sptr expr;
  if (ini::read_function_call_expr(s, expr) && expr)
    result.reset(new fn_call_expr_boundary(expr));
  return result;
}

/// Evaluate an insertion range boundary to get a resulting integer
/// value.
///
/// @param boundary the boundary to evaluate.
///
/// @param context the context of evualuation.  It's a @ref class_decl
/// to take into account during the evaluation, if there is a need for
/// it.
///
/// @return true iff the evaluation was successful and @p value
/// contains the resulting value.
bool
type_suppression::insertion_range::eval_boundary(boundary_sptr	 boundary,
						 class_decl_sptr context,
						 uint64_t&	 value)
{
  if (integer_boundary_sptr b = is_integer_boundary(boundary))
    {
      value = b->as_integer();
      return true;
    }
  else if (fn_call_expr_boundary_sptr b = is_fn_call_expr_boundary(boundary))
    {
      ini::function_call_expr_sptr fn_call = b->as_function_call_expr();
      if ((fn_call->get_name() == "offset_of"
	   || fn_call->get_name() == "offset_after")
	  && fn_call->get_arguments().size() == 1)
	{
	  string member_name = fn_call->get_arguments()[0];
	  for (class_decl::data_members::const_iterator it =
		 context->get_data_members().begin();
	       it != context->get_data_members().end();
	       ++it)
	    {
	      if (!get_data_member_is_laid_out(**it))
		continue;
	      if ((*it)->get_name() == member_name)
		{
		  if (fn_call->get_name() == "offset_of")
		    value = get_data_member_offset(*it);
		  else if (fn_call->get_name() == "offset_after")
		    {
		      if (!get_next_data_member_offset(context, *it, value))
			{
			  value = get_data_member_offset(*it) +
			    (*it)->get_type()->get_size_in_bits();
			}
		    }
		  else
		    // We should not reach this point.
		    abort();
		  return true;
		}
	    }
	}
    }
  return false;
}

/// Test if a given value supposed to be inside an insertion range
/// represents the end of the range.
///
/// @param value the value to test for.
///
/// @return true iff @p value represents the end of the insertion
/// range.
bool
type_suppression::insertion_range::boundary_value_is_end(uint64_t value)
{
  return value == std::numeric_limits<uint64_t>::max();
}

/// Tests if a given instance of @ref
/// type_suppression::insertion_range::boundary is actually an integer boundary.
///
/// @param b the boundary to test.
///
/// @return a pointer to the instance of
/// type_suppression::insertion_range::integer_boundary if @p b is
/// actually an integer boundary.  Otherwise, return a null pointer.
type_suppression::insertion_range::integer_boundary_sptr
is_integer_boundary(type_suppression::insertion_range::boundary_sptr b)
{return dynamic_pointer_cast<type_suppression::insertion_range::integer_boundary>(b);}

/// Tests if a given instance of @ref
/// type_suppression::insertion_range::boundary is actually an function call expression boundary.
///
/// @param b the boundary to test.
///
/// @return a pointer to the instance of
/// type_suppression::insertion_range::fn_call_expr_boundary if @p b
/// is actually an function call expression boundary.  Otherwise,
/// return a null pointer.
type_suppression::insertion_range::fn_call_expr_boundary_sptr
is_fn_call_expr_boundary(type_suppression::insertion_range::boundary_sptr b)
{return dynamic_pointer_cast<type_suppression::insertion_range::fn_call_expr_boundary>(b);}

/// The private data type of @ref
/// type_suppression::insertion_range::boundary.
struct type_suppression::insertion_range::boundary::priv
{
  priv()
  {}
}; // end struct type_suppression::insertion_range::boundary::priv

/// Default constructor of @ref
/// type_suppression::insertion_range::boundary
type_suppression::insertion_range::boundary::boundary()
  : priv_(new priv())
{}

/// Destructor of @ref type_suppression::insertion_range::boundary.
type_suppression::insertion_range::boundary::~boundary()
{}

/// Private data type for @ref
/// type_suppression::insertion_range::integer_boundary.
struct type_suppression::insertion_range::integer_boundary::priv
{
  uint64_t value_;

  priv()
    : value_()
  {}

  priv(uint64_t value)
    : value_(value)
  {}
}; // end type_suppression::insertion_range::integer_boundary::priv

/// Converting constructor of
/// type_suppression::insertion_range::integer_boundary.
///
/// @param value the integer value of the newly created integer boundary.
type_suppression::insertion_range::integer_boundary::integer_boundary(uint64_t value)
  : priv_(new priv(value))
{}

/// Return the integer value of the current instance of @ref
/// type_suppression::insertion_range::integer_boundary.
///
/// @return the integer value of the current boundary.
uint64_t
type_suppression::insertion_range::integer_boundary::as_integer() const
{return priv_->value_;}

/// Converts the current boundary into an integer value.
///
/// @return the integer value of the current boundary.
type_suppression::insertion_range::integer_boundary::operator uint64_t() const
{return as_integer();}

/// Destructor of @ref type_suppression::insertion_range::integer_boundary.
type_suppression::insertion_range::integer_boundary::~integer_boundary()
{}

/// Private data type of type @ref
/// type_suppression::insertion_range::fn_call_expr_boundary.
struct type_suppression::insertion_range::fn_call_expr_boundary::priv
{
  ini::function_call_expr_sptr expr_;

  priv()
  {}

  priv(ini::function_call_expr_sptr expr)
    : expr_(expr)
  {}
}; // end struct type_suppression::insertion_range::fn_call_expr_boundary::priv

/// Converting constructor for @ref
/// type_suppression::insertion_range::fn_call_expr_boundary.
///
/// @param expr the function call expression to build this boundary
/// from.
type_suppression::insertion_range::fn_call_expr_boundary::
fn_call_expr_boundary(ini::function_call_expr_sptr expr)
  : priv_(new priv(expr))
{}

/// Returns the function call expression value of the current boundary.
///
/// @return the function call expression value of the current boundary;
ini::function_call_expr_sptr
type_suppression::insertion_range::fn_call_expr_boundary::as_function_call_expr() const
{return priv_->expr_;}

/// Converts the current boundary to its function call expression value.
///
/// @return the function call expression value of the current boundary.
type_suppression::insertion_range::fn_call_expr_boundary::operator ini::function_call_expr_sptr () const
{return as_function_call_expr();}

/// Destructor of @ref
/// type_suppression::insertion_range::fn_call_expr_boundary.
type_suppression::insertion_range::fn_call_expr_boundary::~fn_call_expr_boundary()
{}

/// Test if an instance of @ref suppression is an instance of @ref
/// type_suppression.
///
/// @param suppr the instance of @ref suppression to test for.
///
/// @return if @p suppr is an instance of @ref type_suppression, then
/// return the sub-object of the @p suppr of type @ref
/// type_suppression, otherwise return a nil pointer.
type_suppression_sptr
is_type_suppression(suppression_sptr suppr)
{return dynamic_pointer_cast<type_suppression>(suppr);}

// </type_suppression stuff>

/// Parse the value of the "type_kind" property in the "suppress_type"
/// section.
///
/// @param input the input string representing the value of the
/// "type_kind" property.
///
/// @return the @ref type_kind enumerator parsed.
static type_suppression::type_kind
read_type_kind_string(const string& input)
{
  if (input == "class")
    return type_suppression::CLASS_TYPE_KIND;
  else if (input == "struct")
    return type_suppression::STRUCT_TYPE_KIND;
  else if (input == "union")
    return type_suppression::UNION_TYPE_KIND;
  else if (input == "enum")
    return type_suppression::ENUM_TYPE_KIND;
  else if (input == "array")
    return type_suppression::ARRAY_TYPE_KIND;
  else if (input == "typedef")
    return type_suppression::TYPEDEF_TYPE_KIND;
  else if (input == "builtin")
    return type_suppression::BUILTIN_TYPE_KIND;
  else
    return type_suppression::UNKNOWN_TYPE_KIND;
}

/// Parse the value of the "accessed_through" property in the
/// "suppress_type" section.
///
/// @param input the input string representing the value of the
/// "accessed_through" property.
///
/// @return the @ref type_suppression::reach_kind enumerator parsed.
static type_suppression::reach_kind
read_suppression_reach_kind(const string& input)
{
  if (input == "direct")
    return type_suppression::DIRECT_REACH_KIND;
  else if (input == "pointer")
    return type_suppression::POINTER_REACH_KIND;
  else if (input == "reference")
    return type_suppression::REFERENCE_REACH_KIND;
  else if (input == "reference-or-pointer")
    return type_suppression::REFERENCE_OR_POINTER_REACH_KIND;
  else
    return type_suppression::DIRECT_REACH_KIND;
}

/// Read a type suppression from an instance of ini::config::section
/// and build a @ref type_suppression as a result.
///
/// @param section the section of the ini config to read.
///
/// @return the resulting @ref type_suppression upon successful
/// parsing, or nil.
static type_suppression_sptr
read_type_suppression(const ini::config::section& section)
{
  type_suppression_sptr result;

  if (section.get_name() != "suppress_type")
    return result;

  static const char *const sufficient_props[] = {
    "file_name_regexp",
    "file_name_not_regexp",
    "soname_regexp",
    "soname_not_regexp",
    "name",
    "name_regexp",
    "name_not_regexp",
    "type_kind",
    "source_location_not_in",
    "source_location_not_regexp",
  };
  if (!check_sufficient_props(sufficient_props,
			      sizeof(sufficient_props)/sizeof(char*),
			      section))
    return result;

  ini::simple_property_sptr drop_artifact =
    is_simple_property(section.find_property("drop_artifact"));
  if (!drop_artifact)
    drop_artifact = is_simple_property(section.find_property("drop"));

  string drop_artifact_str = drop_artifact
    ? drop_artifact->get_value()->as_string()
    : "";

  ini::simple_property_sptr label =
    is_simple_property(section.find_property("label"));
  string label_str = label ? label->get_value()->as_string() : "";

  ini::simple_property_sptr file_name_regex_prop =
    is_simple_property(section.find_property("file_name_regexp"));
  string file_name_regex_str =
    file_name_regex_prop ? file_name_regex_prop->get_value()->as_string() : "";

  ini::simple_property_sptr file_name_not_regex_prop =
    is_simple_property(section.find_property("file_name_not_regexp"));
  string file_name_not_regex_str =
    file_name_not_regex_prop
    ? file_name_not_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr soname_regex_prop =
    is_simple_property(section.find_property("soname_regexp"));
  string soname_regex_str =
    soname_regex_prop ? soname_regex_prop->get_value()->as_string() : "";

  ini::simple_property_sptr soname_not_regex_prop =
    is_simple_property(section.find_property("soname_not_regexp"));
  string soname_not_regex_str =
    soname_not_regex_prop
    ? soname_not_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr name_regex_prop =
    is_simple_property(section.find_property("name_regexp"));
  string name_regex_str = name_regex_prop
    ? name_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr name_not_regex_prop =
    is_simple_property(section.find_property("name_not_regexp"));
  string name_not_regex_str = name_not_regex_prop
    ? name_not_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr name_prop =
    is_simple_property(section.find_property("name"));
  string name_str = name_prop
    ? name_prop->get_value()->as_string()
    : "";

  ini::property_sptr srcloc_not_in_prop =
    section.find_property("source_location_not_in");
  unordered_set<string> srcloc_not_in;
  if (srcloc_not_in_prop)
    {
      if (ini::simple_property_sptr p = is_simple_property(srcloc_not_in_prop))
	srcloc_not_in.insert(p->get_value()->as_string());
      else
	{
	  ini::list_property_sptr list_property =
	    is_list_property(srcloc_not_in_prop);
	  if (list_property)
	    {
	      vector<string>::const_iterator i;
	      for (i = list_property->get_value()->get_content().begin();
		   i != list_property->get_value()->get_content().end();
		   ++i)
		srcloc_not_in.insert(*i);
	    }
	}
    }

  ini::simple_property_sptr srcloc_not_regexp_prop =
    is_simple_property(section.find_property("source_location_not_regexp"));
  string srcloc_not_regexp_str;
  if (srcloc_not_regexp_prop)
    srcloc_not_regexp_str = srcloc_not_regexp_prop->get_value()->as_string();

  bool consider_type_kind = false;
  type_suppression::type_kind type_kind = type_suppression::UNKNOWN_TYPE_KIND;
  if (ini::simple_property_sptr type_kind_prop =
      is_simple_property(section.find_property("type_kind")))
    {
      consider_type_kind = true;
      type_kind =
	read_type_kind_string(type_kind_prop->get_value()->as_string());
    }

  bool consider_reach_kind = false;
  type_suppression::reach_kind reach_kind = type_suppression::DIRECT_REACH_KIND;
  if (ini::simple_property_sptr reach_kind_prop =
      is_simple_property(section.find_property("accessed_through")))
    {
      consider_reach_kind = true;
      reach_kind =
	read_suppression_reach_kind(reach_kind_prop->get_value()->as_string());
    }

  // Support has_data_member_inserted_at
  vector<type_suppression::insertion_range_sptr> insert_ranges;
  bool consider_data_member_insertion = false;
  if (ini::simple_property_sptr prop =
      is_simple_property(section.find_property("has_data_member_inserted_at")))
    {
      // So this property has the form:
      //   has_data_member_inserted_at = <one-string-property-value>
      string ins_point = prop->get_value()->as_string();
      type_suppression::insertion_range::boundary_sptr begin, end;
      if (ins_point == "end")
	begin = type_suppression::insertion_range::create_integer_boundary(-1);
      else if (isdigit(ins_point[0]))
	begin = type_suppression::insertion_range::create_integer_boundary
	  (atoi(ins_point.c_str()));
      else if (type_suppression::insertion_range::fn_call_expr_boundary_sptr expr =
	       type_suppression::insertion_range::create_fn_call_expr_boundary(ini::read_function_call_expr(ins_point)))
	begin = expr;
      else
	return result;

      end = type_suppression::insertion_range::create_integer_boundary(-1);
      type_suppression::insertion_range_sptr insert_range
	(new type_suppression::insertion_range(begin, end));
	  insert_ranges.push_back(insert_range);
	  consider_data_member_insertion = true;
    }

  // Support has_data_member_inserted_between
  if (ini::tuple_property_sptr prop =
      is_tuple_property(section.find_property
			("has_data_member_inserted_between")))
    {
      // ensures that this has the form:
      //  has_data_member_inserted_between = {0 , end};
      // and not (for instance):
      //  has_data_member_inserted_between = {{0 , end}, {1, foo}}
      //
      //  This means that the tuple_property_value contains just one
      //  value, which is a list_property that itself contains 2
      //  values.
      type_suppression::insertion_range::boundary_sptr begin, end;
      ini::tuple_property_value_sptr v = prop->get_value();
      if (v
	  && v->get_value_items().size() == 1
	  && is_list_property_value(v->get_value_items()[0])
	  && is_list_property_value(v->get_value_items()[0])->get_content().size() == 2)
	{
	  ini::list_property_value_sptr val =
	    is_list_property_value(v->get_value_items()[0]);
	  ABG_ASSERT(val);
	  string str = val->get_content()[0];
	  if (str == "end")
	    begin =
	      type_suppression::insertion_range::create_integer_boundary(-1);
	  else if (isdigit(str[0]))
	    begin = type_suppression::insertion_range::create_integer_boundary
	      (atoi(str.c_str()));
	  else if (type_suppression::insertion_range::fn_call_expr_boundary_sptr expr =
		   type_suppression::insertion_range::create_fn_call_expr_boundary(ini::read_function_call_expr(str)))
	    begin = expr;
	  else
	    return result;

	  str = val->get_content()[1];
	  if (str == "end")
	    end =
	      type_suppression::insertion_range::create_integer_boundary(-1);
	  else if (isdigit(str[0]))
	    end = type_suppression::insertion_range::create_integer_boundary
	      (atoi(str.c_str()));
	  else if (type_suppression::insertion_range::fn_call_expr_boundary_sptr expr =
		   type_suppression::insertion_range::create_fn_call_expr_boundary(ini::read_function_call_expr(str)))
	    end = expr;
	  else
	    return result;

	  type_suppression::insertion_range_sptr insert_range
	    (new type_suppression::insertion_range(begin, end));
	  insert_ranges.push_back(insert_range);
	  consider_data_member_insertion = true;
	}
      else
	// the 'has_data_member_inserted_between' property has a wrong
	// value type, so let's discard the endire [suppress_type]
	// section.
	return result;
    }

  // Support has_data_members_inserted_between
  // The syntax looks like:
  //
  //    has_data_members_inserted_between = {{8, 24}, {32, 64}, {128, end}}
  //
  // So we expect a tuple property, with potentially several pairs (as
  // part of the value); each pair designating a range.  Note that
  // each pair (range) is a list property value.
  if (ini::tuple_property_sptr prop =
      is_tuple_property(section.find_property
			("has_data_members_inserted_between")))
    {
      bool is_well_formed = true;
      for (vector<ini::property_value_sptr>::const_iterator i =
	     prop->get_value()->get_value_items().begin();
	   is_well_formed && i != prop->get_value()->get_value_items().end();
	   ++i)
	{
	  ini::tuple_property_value_sptr tuple_value =
	    is_tuple_property_value(*i);
	  if (!tuple_value
	      || tuple_value->get_value_items().size() != 1
	      || !is_list_property_value(tuple_value->get_value_items()[0]))
	    {
	      is_well_formed = false;
	      break;
	    }
	  ini::list_property_value_sptr list_value =
	    is_list_property_value(tuple_value->get_value_items()[0]);
	  if (list_value->get_content().size() != 2)
	    {
	      is_well_formed = false;
	      break;
	    }

	  type_suppression::insertion_range::boundary_sptr begin, end;
	  string str = list_value->get_content()[0];
	  if (str == "end")
	    begin =
	      type_suppression::insertion_range::create_integer_boundary(-1);
	  else if (isdigit(str[0]))
	    begin =
	      type_suppression::insertion_range::create_integer_boundary
	      (atoi(str.c_str()));
	  else if (type_suppression::insertion_range::fn_call_expr_boundary_sptr expr =
		   type_suppression::insertion_range::create_fn_call_expr_boundary(ini::read_function_call_expr(str)))
	    begin = expr;
	  else
	    return result;

	  str = list_value->get_content()[1];
	  if (str == "end")
	    end =
	      type_suppression::insertion_range::create_integer_boundary(-1);
	  else if (isdigit(str[0]))
	    end = type_suppression::insertion_range::create_integer_boundary
	      (atoi(str.c_str()));
	  else if (type_suppression::insertion_range::fn_call_expr_boundary_sptr expr =
		   type_suppression::insertion_range::create_fn_call_expr_boundary(ini::read_function_call_expr(str)))
	    end = expr;
	  else
	    return result;

	  type_suppression::insertion_range_sptr insert_range
	    (new type_suppression::insertion_range(begin, end));
	  insert_ranges.push_back(insert_range);
	  consider_data_member_insertion = true;
	}
      if (!is_well_formed)
	return result;
    }

  /// Support 'changed_enumerators = foo, bar, baz'
  ///
  /// Note that this constraint is valid only if we have:
  ///   'type_kind = enum'.
  ///
  /// If the current type is an enum and if it carries changed
  /// enumerators listed in the changed_enumerators property value
  /// then it should be suppressed.

  ini::property_sptr changed_enumerators_prop =
    section.find_property("changed_enumerators");

  vector<string> changed_enumerator_names;
  if (changed_enumerators_prop)
    {
      if (ini::list_property_sptr p =
	  is_list_property(changed_enumerators_prop))
	changed_enumerator_names =
	  p->get_value()->get_content();
      else if (ini::simple_property_sptr p =
	       is_simple_property(changed_enumerators_prop))
	changed_enumerator_names.push_back(p->get_value()->as_string());
    }

  result.reset(new type_suppression(label_str, name_regex_str, name_str));

  if (consider_type_kind)
    {
      result->set_consider_type_kind(true);
      result->set_type_kind(type_kind);
    }

  if (consider_reach_kind)
    {
      result->set_consider_reach_kind(true);
      result->set_reach_kind(reach_kind);
    }

  if (consider_data_member_insertion)
    result->set_data_member_insertion_ranges(insert_ranges);

  if (!name_not_regex_str.empty())
    result->set_type_name_not_regex_str(name_not_regex_str);

  if (!file_name_regex_str.empty())
    result->set_file_name_regex_str(file_name_regex_str);

  if (!file_name_not_regex_str.empty())
    result->set_file_name_not_regex_str(file_name_not_regex_str);

  if (!soname_regex_str.empty())
    result->set_soname_regex_str(soname_regex_str);

  if (!soname_not_regex_str.empty())
    result->set_soname_not_regex_str(soname_not_regex_str);

  if (!srcloc_not_in.empty())
    result->set_source_locations_to_keep(srcloc_not_in);

  if (!srcloc_not_regexp_str.empty())
    result->set_source_location_to_keep_regex_str(srcloc_not_regexp_str);

  if ((drop_artifact_str == "yes" || drop_artifact_str == "true")
      && ((!name_regex_str.empty()
	   || !name_str.empty()
	   || !srcloc_not_regexp_str.empty()
	   || !srcloc_not_in.empty())))
    result->set_drops_artifact_from_ir(true);

  if (result->get_type_kind() == type_suppression::ENUM_TYPE_KIND
      && !changed_enumerator_names.empty())
    result->set_changed_enumerator_names(changed_enumerator_names);

  return result;
}

// <function_suppression stuff>

/// Constructor for the @ref the function_suppression::parameter_spec
/// type.
///
/// @param i the index of the parameter designated by this specification.
///
/// @param tn the type name of the parameter designated by this specification.
///
/// @param tn_regex a regular expression that defines a set of type
/// names for the parameter designated by this specification.  Note
/// that at evaluation time, this regular expression is taken in
/// account only if the parameter @p tn is empty.
function_suppression::parameter_spec::parameter_spec(size_t i,
						     const string& tn,
						     const string& tn_regex)
  : priv_(new priv(i, tn, tn_regex))
{}

/// Getter for the index of the parameter designated by this
/// specification.
///
/// @return the index of the parameter designated by this
/// specification.
size_t
function_suppression::parameter_spec::get_index() const
{return priv_->index_;}

/// Setter for the index of the parameter designated by this
/// specification.
///
/// @param i the new index to set.
void
function_suppression::parameter_spec::set_index(size_t i)
{priv_->index_ = i;}

/// Getter for the type name of the parameter designated by this specification.
///
/// @return the type name of the parameter.
const string&
function_suppression::parameter_spec::get_parameter_type_name() const
{return priv_->type_name_;}

/// Setter for the type name of the parameter designated by this
/// specification.
///
/// @param tn new parameter type name to set.
void
function_suppression::parameter_spec::set_parameter_type_name(const string& tn)
{priv_->type_name_ = tn;}

/// Getter for the regular expression that defines a set of type names
/// for the parameter designated by this specification.
///
/// Note that at evaluation time, this regular expression is taken in
/// account only if the name of the parameter as returned by
/// function_suppression::parameter_spec::get_parameter_type_name() is
/// empty.
///
/// @return the regular expression or the parameter type name.
const string&
function_suppression::parameter_spec::get_parameter_type_name_regex_str() const
{return priv_->type_name_regex_str_;}

/// Setter for the regular expression that defines a set of type names
/// for the parameter designated by this specification.
///
/// Note that at evaluation time, this regular expression is taken in
/// account only if the name of the parameter as returned by
/// function_suppression::parameter_spec::get_parameter_type_name() is
/// empty.
///
/// @param type_name_regex_str the new type name regular expression to
/// set.
void
function_suppression::parameter_spec::set_parameter_type_name_regex_str
(const string& type_name_regex_str)
{priv_->type_name_regex_str_ = type_name_regex_str;}

/// Default constructor for the @ref function_suppression type.
///
/// It defines no suppression for now.  Suppressions have to be
/// specified by using the various accessors of the @ref
/// function_suppression type.
function_suppression::function_suppression()
  :  suppression_base(/*label=*/""), priv_(new priv)
{}

/// Constructor for the @ref function_suppression type.
///
/// @param label an informative text string that the evalution code
/// might use to designate this function suppression specification in
/// error messages.  This parameter might be empty, in which case it's
/// ignored at evaluation time.
///
/// @param the name of the function the user wants the current
/// specification to designate.  This parameter might be empty, in
/// which case it's ignored at evaluation time.
///
/// @param nr if @p name is empty this parameter is a regular
/// expression for a family of names of functions the user wants the
/// current specification to designate.  If @p name is not empty, this
/// parameter is ignored at specification evaluation time.  This
/// parameter might be empty, in which case it's ignored at evaluation
/// time.
///
/// @param ret_tn the name of the return type of the function the user
/// wants this specification to designate.  This parameter might be
/// empty, in which case it's ignored at evaluation time.
///
/// @param ret_tr if @p ret_tn is empty, then this is a regular
/// expression for a family of return type names for functions the
/// user wants the current specification to designate.  If @p ret_tn
/// is not empty, then this parameter is ignored at specification
/// evaluation time.  This parameter might be empty, in which case
/// it's ignored at evaluation time.
///
/// @param ps a vector of parameter specifications to specify
/// properties of the parameters of the functions the user wants this
/// specification to designate.  This parameter might be empty, in
/// which case it's ignored at evaluation time.
///
/// @param sym_n the name of symbol of the function the user wants
/// this specification to designate.  This parameter might be empty,
/// in which case it's ignored at evaluation time.
///
/// @param sym_nr if the parameter @p sym_n is empty, then this
/// parameter is a regular expression for a family of names of symbols
/// of functions the user wants this specification to designate.  If
/// the parameter @p sym_n is not empty, then this parameter is
/// ignored at specification evaluation time.  This parameter might be
/// empty, in which case it's ignored at evaluation time.
///
/// @param sym_v the name of the version of the symbol of the function
/// the user wants this specification to designate.  This parameter
/// might be empty, in which case it's ignored at evaluation time.
///
/// @param sym_vr if the parameter @p sym_v is empty, then this
/// parameter is a regular expression for a family of versions of
/// symbols of functions the user wants the current specification to
/// designate.  If the parameter @p sym_v is non empty, then this
/// parameter is ignored.  This parameter might be empty, in which
/// case it's ignored at evaluation time.
function_suppression::function_suppression(const string&		label,
					   const string&		name,
					   const string&		nr,
					   const string&		ret_tn,
					   const string&		ret_tr,
					   parameter_specs_type&	ps,
					   const string&		sym_n,
					   const string&		sym_nr,
					   const string&		sym_v,
					   const string&		sym_vr)
  : suppression_base(label),
    priv_(new priv(name, nr, ret_tn, ret_tr, ps,
		   sym_n, sym_nr, sym_v, sym_vr))
{}

function_suppression::~function_suppression()
{}

/// Parses a string containing the content of the "change-kind"
/// property and returns the an instance of @ref
/// function_suppression::change_kind as a result.
///
/// @param s the string to parse.
///
/// @return the resulting @ref function_suppression::change_kind.
function_suppression::change_kind
function_suppression::parse_change_kind(const string& s)
{
  if (s == "function-subtype-change")
    return FUNCTION_SUBTYPE_CHANGE_KIND;
  else if (s == "added-function")
    return ADDED_FUNCTION_CHANGE_KIND;
  else if (s == "deleted-function")
    return DELETED_FUNCTION_CHANGE_KIND;
  else if (s == "all")
    return ALL_CHANGE_KIND;
  else
    return UNDEFINED_CHANGE_KIND;
}

/// Getter of the "change-kind" property.
///
/// @param returnthe "change-kind" property.
function_suppression::change_kind
function_suppression::get_change_kind() const
{return priv_->change_kind_;}

/// Setter of the "change-kind" property.
///
/// @param k the new value of the change_kind property.
void
function_suppression::set_change_kind(change_kind k)
{priv_->change_kind_ = k;}

/// Getter for the name of the function the user wants the current
/// specification to designate.  This might be empty, in which case
/// it's ignored at evaluation time.
///
/// @return the name of the function.
const string&
function_suppression::get_name() const
{return priv_->name_;}

/// Setter for the name of the function the user wants the current
/// specification to designate.  This might be empty, in which case
/// it's ignored at evaluation time.
///
/// @param n the new function name to set.
void
function_suppression::set_name(const string& n)
{priv_->name_ = n;}

/// Getter for a regular expression for a family of names of functions
/// the user wants the current specification to designate.
///
/// @return the regular expression for the possible names of the
/// function(s).
const string&
function_suppression::get_name_regex_str() const
{return priv_->name_regex_str_;}

/// Setter for a regular expression for a family of names of functions
/// the user wants the current specification to designate.
///
/// @param r the new the regular expression for the possible names of
/// the function(s).
void
function_suppression::set_name_regex_str(const string& r)
{priv_->name_regex_str_ = r;}

/// Getter for a regular expression of a family of names of functions
/// the user wants the current specification to designate the negation
/// of.
///
/// @return the regular expression for the possible names of the
/// function(s).
const string&
function_suppression::get_name_not_regex_str() const
{return priv_->name_not_regex_str_;}

/// Setter for a regular expression for a family of names of functions
/// the user wants the current specification to designate the negation
/// of.
///
/// @param r the new the regular expression for the possible names of
/// the function(s).
void
function_suppression::set_name_not_regex_str(const string& r)
{priv_->name_not_regex_str_ = r;}

/// Getter for the name of the return type of the function the user
/// wants this specification to designate.  This property might be
/// empty, in which case it's ignored at evaluation time.
///
/// @return the name of the return type of the function.
const string&
function_suppression::get_return_type_name() const
{return priv_->return_type_name_;}

/// Setter for the name of the return type of the function the user
/// wants this specification to designate.  This property might be
/// empty, in which case it's ignored at evaluation time.
///
/// @param tr the new name of the return type of the function to set.
void
function_suppression::set_return_type_name(const string& tr)
{priv_->return_type_name_ = tr;}

/// Getter for a regular expression for a family of return type names
/// for functions the user wants the current specification to
/// designate.
///
/// If the name of the return type of the function as returned by
/// function_suppression::get_return_type_name() is not empty, then
/// this property is ignored at specification evaluation time.  This
/// property might be empty, in which case it's ignored at evaluation
/// time.
///
/// @return the regular expression for the possible names of the
/// return types of the function(s).
const string&
function_suppression::get_return_type_regex_str() const
{return priv_->return_type_regex_str_;}

/// Setter for a regular expression for a family of return type names
/// for functions the user wants the current specification to
/// designate.
///
/// If the name of the return type of the function as returned by
/// function_suppression::get_return_type_name() is not empty, then
/// this property is ignored at specification evaluation time.  This
/// property might be empty, in which case it's ignored at evaluation
/// time.
///
/// @param r the new regular expression for the possible names of the
/// return types of the function(s) to set.
void
function_suppression::set_return_type_regex_str(const string& r)
{priv_->return_type_regex_str_ = r;}

/// Getter for a vector of parameter specifications to specify
/// properties of the parameters of the functions the user wants this
/// specification to designate.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.
///
/// @return the specifications of the parameters of the function(s).
const function_suppression::parameter_specs_type&
function_suppression::get_parameter_specs() const
{return priv_->parm_specs_;}

/// Setter for a vector of parameter specifications to specify
/// properties of the parameters of the functions the user wants this
/// specification to designate.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.
///
/// @param p the new specifications of the parameters of the
/// function(s) to set.
void
function_suppression::set_parameter_specs(parameter_specs_type& p)
{priv_->parm_specs_ = p;}

/// Append a specification of a parameter of the function specification.
///
/// @param p the parameter specification to add.
void
function_suppression::append_parameter_specs(const parameter_spec_sptr p)
{priv_->parm_specs_.push_back(p);}

/// Getter for the name of symbol of the function the user wants this
/// specification to designate.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.
///
/// @return name of the symbol of the function.
const string&
function_suppression::get_symbol_name() const
{return priv_->symbol_name_;}

/// Setter for the name of symbol of the function the user wants this
/// specification to designate.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.
///
/// @return name of the symbol of the function.
void
function_suppression::set_symbol_name(const string& n)
{priv_->symbol_name_ = n;}

/// Getter for a regular expression for a family of names of symbols
/// of functions the user wants this specification to designate.
///
/// If the symbol name as returned by
/// function_suppression::get_symbol_name() is not empty, then this
/// property is ignored at specification evaluation time.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.
///
/// @return the regular expression for a family of names of symbols of
/// functions to designate.
const string&
function_suppression::get_symbol_name_regex_str() const
{return priv_->symbol_name_regex_str_;}

/// Setter for a regular expression for a family of names of symbols
/// of functions the user wants this specification to designate.
///
/// If the symbol name as returned by
/// function_suppression::get_symbol_name() is not empty, then this
/// property is ignored at specification evaluation time.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.
///
/// @param r the new regular expression for a family of names of
/// symbols of functions to set.
void
function_suppression::set_symbol_name_regex_str(const string& r)
{priv_->symbol_name_regex_str_ = r;}

/// Getter for a regular expression for a family of names of symbols
/// of functions the user wants this specification to designate.
///
/// If a symbol name is matched by this regular expression, then the
/// suppression specification will *NOT* suppress the symbol.
///
/// If the symbol name as returned by
/// function_suppression::get_symbol_name() is not empty, then this
/// property is ignored at specification evaluation time.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.
///
/// @return the regular expression string for a family of names of
/// symbols that is to be *NOT* suppressed by this suppression specification.
const string&
function_suppression::get_symbol_name_not_regex_str() const
{return priv_->symbol_name_not_regex_str_;}

/// Setter for a regular expression for a family of names of symbols
/// of functions the user wants this specification to designate.
///
/// If a symbol name is matched by this regular expression, then the
/// suppression specification will *NOT* suppress the symbol.
///
/// If the symbol name as returned by
/// function_suppression::get_symbol_name() is not empty, then this
/// property is ignored at specification evaluation time.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.
///
/// @param the new regular expression string for a family of names of
/// symbols that is to be *NOT* suppressed by this suppression
/// specification.
void
function_suppression::set_symbol_name_not_regex_str(const string& r)
{priv_->symbol_name_not_regex_str_ = r;}

/// Getter for the name of the version of the symbol of the function
/// the user wants this specification to designate.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.
///
/// @return the symbol version of the function.
const string&
function_suppression::get_symbol_version() const
{return priv_->symbol_version_;}

/// Setter for the name of the version of the symbol of the function
/// the user wants this specification to designate.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.
///
/// @param v the new symbol version of the function.
void
function_suppression::set_symbol_version(const string& v)
{priv_->symbol_version_ = v;}

/// Getter for a regular expression for a family of versions of
/// symbols of functions the user wants the current specification to
/// designate.
///
/// If the symbol version as returned by
/// function_suppression::get_symbol_version() is non empty, then this
/// property is ignored.  This property might be empty, in which case
/// it's ignored at evaluation time.
///
/// @return the regular expression for the versions of symbols of
/// functions to designate.
const string&
function_suppression::get_symbol_version_regex_str() const
{return priv_->symbol_version_regex_str_;}

/// Setter for a regular expression for a family of versions of
/// symbols of functions the user wants the current specification to
/// designate.
///
/// If the symbol version as returned by
/// function_suppression::get_symbol_version() is non empty, then this
/// property is ignored.  This property might be empty, in which case
/// it's ignored at evaluation time.
///
/// @param the new regular expression for the versions of symbols of
/// functions to designate.
void
function_suppression::set_symbol_version_regex_str(const string& r)
{priv_->symbol_version_regex_str_ = r;}

/// Getter for the "allow_other_aliases" property of the function
/// suppression specification.
///
/// @return the value of the "allow_other_aliases" property.
bool
function_suppression::get_allow_other_aliases() const
{return priv_->allow_other_aliases_;}

/// Setter for the "allow_other_aliases" property of the function
/// suppression specification.
///
/// @param f the new value of the property.
void
function_suppression::set_allow_other_aliases(bool f)
{priv_->allow_other_aliases_ = f;}

/// Evaluate this suppression specification on a given diff node and
/// say if the diff node should be suppressed or not.
///
/// @param diff the diff node to evaluate this suppression
/// specification against.
///
/// @return true if @p diff should be suppressed.
bool
function_suppression::suppresses_diff(const diff* diff) const
{
  const function_decl_diff* d = is_function_decl_diff(diff);
  if (!d)
    return false;

  function_decl_sptr ff = is_function_decl(d->first_function_decl()),
    sf = is_function_decl(d->second_function_decl());
  ABG_ASSERT(ff && sf);

  return (suppresses_function(ff,
			      FUNCTION_SUBTYPE_CHANGE_KIND,
			      diff->context())
	  || suppresses_function(sf,
				 FUNCTION_SUBTYPE_CHANGE_KIND,
				 diff->context()));
}

/// Evaluate the current function suppression specification on a given
/// @ref function_decl and say if a report about a change involving this
/// @ref function_decl should be suppressed or not.
///
/// @param fn the @ref function_decl to evaluate this suppression
/// specification against.
///
/// @param k the kind of function change @p fn is supposed to have.
///
/// @param ctxt the context of the current diff.
///
/// @return true iff a report about a change involving the function @p
/// fn should be suppressed.
bool
function_suppression::suppresses_function(const function_decl* fn,
					  change_kind k,
					  const diff_context_sptr ctxt) const
{
  if (!(get_change_kind() & k))
    return false;

  // Check if the name and soname of the binaries match the current
  // suppr spec
  if (ctxt)
    {
      // Check if the name of the binaries match the current suppr spec
      if (!names_of_binaries_match(*this, *ctxt))
	if (has_file_name_related_property())
	  return false;

      // Check if the soname of the binaries match the current suppr spec
      if (!sonames_of_binaries_match(*this, *ctxt))
	if (has_soname_related_property())
	  return false;
    }

  string fname = fn->get_qualified_name();

  // Check if the "name" property matches.
  if (!get_name().empty())
    {
      if (get_name() != fn->get_qualified_name())
	return false;

      if (get_allow_other_aliases()
	  && fn->get_symbol()
	  && fn->get_symbol()->get_alias_from_name(fname))
	{
	  // So we are in a case of a languages in which the symbol
	  // name is the same as the function name and we want to
	  // allow the removal of change reports on an aliased
	  // function only if the suppression condition matches the
	  // names of all aliases.
	  string symbol_name;
	  elf_symbol_sptr sym = fn->get_symbol();
	  ABG_ASSERT(sym);
	  symbol_name = sym->get_name();
	  if (sym->has_aliases() && sym->get_alias_from_name(fname))
	    {
	      for (elf_symbol_sptr a = sym->get_next_alias();
		   a && !a->is_main_symbol();
		   a = a->get_next_alias())
		if (a->get_name() != symbol_name)
		  // There is an alias which name is different from
		  // the function (symbol) name given in the
		  // suppression condition.
		  return false;
	    }
	}
    }

  // check if the "name_regexp" property matches.
  const regex_t_sptr name_regex = priv_->get_name_regex();
  if (name_regex)
    {
      if (!regex::match(name_regex, fname))
	return false;

      if (get_allow_other_aliases()
	  && fn->get_symbol()
	  && fn->get_symbol()->get_alias_from_name(fname))
	{
	  // So we are in a case of a languages in which the symbol
	  // name is the same as the function name and we want to
	  // allow the removal of change reports on an aliased
	  // function only if the suppression condition matches *all*
	  // the aliases.
	  string symbol_name;
	  elf_symbol_sptr sym = fn->get_symbol();
	  ABG_ASSERT(sym);
	  symbol_name = sym->get_name();
	  if (sym->has_aliases())
	    {
	      for (elf_symbol_sptr a = sym->get_next_alias();
		   a && !a->is_main_symbol();
		   a = a->get_next_alias())
		if (!regex::match(name_regex, a->get_name()))
		  return false;
	    }
	}
    }

  // check if the "name_not_regexp" property matches.
  const regex_t_sptr name_not_regex = priv_->get_name_not_regex();
  if (name_not_regex)
    {
      if (regex::match(name_not_regex, fname))
	return false;

      if (get_allow_other_aliases()
	  && fn->get_symbol()
	  && fn->get_symbol()->get_alias_from_name(fname))
	{
	  // So we are in a case of a languages in which the symbol
	  // name is the same as the function name and we want to
	  // allow the removal of change reports on an aliased
	  // function only if the suppression condition matches *all*
	  // the aliases.
	  string symbol_name;
	  elf_symbol_sptr sym = fn->get_symbol();
	  ABG_ASSERT(sym);
	  symbol_name = sym->get_name();
	  if (sym->has_aliases())
	    {
	      for (elf_symbol_sptr a = sym->get_next_alias();
		   a && !a->is_main_symbol();
		   a = a->get_next_alias())
		if (regex::match(name_regex, a->get_name()))
		  return false;
	    }
	}
    }

  // Check if the "return_type_name" or "return_type_regexp"
  // properties matches.

  string fn_return_type_name = fn->get_type()->get_return_type()
    ? static_cast<string>
    ((get_type_declaration(fn->get_type()->get_return_type())
      ->get_qualified_name()))
    : "";

  if (!get_return_type_name().empty())
    {
      if (fn_return_type_name != get_return_type_name())
	return false;
    }
  else
    {
      const regex_t_sptr return_type_regex = priv_->get_return_type_regex();
      if (return_type_regex
	  && !regex::match(return_type_regex, fn_return_type_name))
	return false;
    }

  // Check if the "symbol_name", "symbol_name_regexp", and
  // "symbol_name_not_regexp" properties match.
  string fn_sym_name, fn_sym_version;
  elf_symbol_sptr sym = fn->get_symbol();
  if (sym)
    {
      fn_sym_name = sym->get_name();
      fn_sym_version = sym->get_version().str();
    }

  if (sym && !get_symbol_name().empty())
    {
      if (fn_sym_name != get_symbol_name())
	return false;

      if (sym && get_allow_other_aliases())
	{
	  // In this case, we want to allow the suppression of change
	  // reports about an aliased symbol only if the suppression
	  // condition matches the name of all aliases.
	  if (sym->has_aliases())
	    {
	      for (elf_symbol_sptr a = sym->get_next_alias();
		   a && !a->is_main_symbol();
		   a = a->get_next_alias())
		if (a->get_name() != fn_sym_name)
		  return false;
	    }
	}
    }
  else if (sym)
    {
      const regex_t_sptr symbol_name_regex = priv_->get_symbol_name_regex();
      if (symbol_name_regex && !regex::match(symbol_name_regex, fn_sym_name))
	return false;

      const regex_t_sptr symbol_name_not_regex =
	priv_->get_symbol_name_not_regex();
      if (symbol_name_not_regex
	  && regex::match(symbol_name_not_regex, fn_sym_name))
	return false;

      if (get_allow_other_aliases())
	{
	  // In this case, we want to allow the suppression of change
	  // reports about an aliased symbol only if the suppression
	  // condition matches the name of all aliases.
	  if (sym->has_aliases())
	    {
	      for (elf_symbol_sptr a = sym->get_next_alias();
		   a && !a->is_main_symbol();
		   a = a->get_next_alias())
		{
		  if (symbol_name_regex
		      && !regex::match(symbol_name_regex, a->get_name()))
		    return false;

		  if (symbol_name_not_regex
		      && regex::match(symbol_name_not_regex, a->get_name()))
		    return false;
		}
	    }
	}
    }

  // Check if the "symbol_version" and "symbol_version_regexp"
  // properties match.
  if (sym && !get_symbol_version().empty())
    {
      if (fn_sym_version != get_symbol_version())
	return false;
    }
  else if (sym)
    {
      const regex_t_sptr symbol_version_regex =
	priv_->get_symbol_version_regex();
      if (symbol_version_regex
	  && !regex::match(symbol_version_regex, fn_sym_version))
	return false;
    }

  // Check the 'parameter' property.
  if (!get_parameter_specs().empty())
    {
      function_type_sptr fn_type = fn->get_type();
      type_base_sptr parm_type;

      for (parameter_specs_type::const_iterator p =
	     get_parameter_specs().begin();
	   p != get_parameter_specs().end();
	   ++p)
	{
	  size_t index = (*p)->get_index();
	  function_decl::parameter_sptr fn_parm =
	    fn_type->get_parm_at_index_from_first_non_implicit_parm(index);
	  if (!fn_parm)
	    return false;

	  string fn_parm_type_qualified_name;
	  if (fn_parm)
	    {
	      parm_type = fn_parm->get_type();
	      fn_parm_type_qualified_name =
		get_type_declaration(parm_type)->get_qualified_name();
	    }

	  const string& tn = (*p)->get_parameter_type_name();
	  if (!tn.empty())
	    {
	      if (tn != fn_parm_type_qualified_name)
		return false;
	    }
	  else
	    {
	      const regex_t_sptr parm_type_name_regex =
		(*p)->priv_->get_type_name_regex();
	      if (parm_type_name_regex)
		{
		  if (!regex::match(parm_type_name_regex,
				    fn_parm_type_qualified_name))
		    return false;
		}
	    }
	}
    }

  return true;
}

/// Evaluate the current function suppression specification on a given
/// @ref function_decl and say if a report about a change involving this
/// @ref function_decl should be suppressed or not.
///
/// @param fn the @ref function_decl to evaluate this suppression
/// specification against.
///
/// @param k the kind of function change @p fn is supposed to have.
///
/// @param ctxt the context of the current diff.
///
/// @return true iff a report about a change involving the function @p
/// fn should be suppressed.
bool
function_suppression::suppresses_function(const function_decl_sptr fn,
					  change_kind k,
					  const diff_context_sptr ctxt) const
{return suppresses_function(fn.get(), k, ctxt);}

/// Evaluate the current function suppression specification on a given
/// @ref elf_symbol and say if a report about a change involving this
/// @ref elf_symbol should be suppressed or not.
///
/// @param sym the @ref elf_symbol to evaluate this suppression
/// specification against.
///
/// @param k the kind of function change @p sym is supposed to have.
///
/// @param ctxt the context of the current diff.
///
/// @return true iff a report about a change involving the symbol @p
/// sym should be suppressed.
bool
function_suppression::suppresses_function_symbol(const elf_symbol* sym,
						 change_kind k,
						 const diff_context_sptr ctxt)
{
  if (!sym)
    return false;

  if (!(get_change_kind() & k))
    return false;

  if (!sym->is_function())
    return false;

  ABG_ASSERT(k & function_suppression::ADDED_FUNCTION_CHANGE_KIND
	 || k & function_suppression::DELETED_FUNCTION_CHANGE_KIND);

  // Check if the name and soname of the binaries match the current
  // suppr spect
  if (ctxt)
    {
      // Check if the name of the binaries match the current
      // suppr spect
      if (!names_of_binaries_match(*this, *ctxt))
	if (has_file_name_related_property())
	  return false;

      // Check if the soname of the binaries match the current
      // suppr spect
      if (!sonames_of_binaries_match(*this, *ctxt))
	if (has_soname_related_property())
	  return false;
    }

  string sym_name = sym->get_name(), sym_version = sym->get_version().str();
  bool no_symbol_name = false, no_symbol_version = false;

  // Consider the symbol name.
  if (!get_symbol_name().empty())
    {
      if (sym_name != get_symbol_name())
	return false;
    }
  else if (!get_symbol_name_regex_str().empty())
    {
      const regex_t_sptr symbol_name_regex = priv_->get_symbol_name_regex();
      if (symbol_name_regex && !regex::match(symbol_name_regex, sym_name))
	return false;
    }
  else
    no_symbol_name = true;

  // Consider the symbol version
  if (!get_symbol_version().empty())
    {
      if (sym_version != get_symbol_version())
	return false;
    }
  else if (!get_symbol_version_regex_str().empty())
    {
      const regex_t_sptr symbol_version_regex =
	priv_->get_symbol_version_regex();
      if (symbol_version_regex
	  && !regex::match(symbol_version_regex, sym_version))
	return false;
    }
  else
    no_symbol_version = true;

  if (no_symbol_name && no_symbol_version)
    return false;

  return true;
}

/// Evaluate the current function suppression specification on a given
/// @ref elf_symbol and say if a report about a change involving this
/// @ref elf_symbol should be suppressed or not.
///
/// @param sym the @ref elf_symbol to evaluate this suppression
/// specification against.
///
/// @param k the kind of function change @p sym is supposed to have.
///
/// @param ctxt the context of the current diff.
///
/// @return true iff a report about a change involving the symbol @p
/// sym should be suppressed.
bool
function_suppression::suppresses_function_symbol(const elf_symbol_sptr sym,
						 change_kind k,
						 const diff_context_sptr ctxt)
{return suppresses_function_symbol(sym.get(), k, ctxt);}

/// Test if an instance of @ref suppression is an instance of @ref
/// function_suppression.
///
/// @param suppr the instance of @ref suppression to test for.
///
/// @return if @p suppr is an instance of @ref function_suppression, then
/// return the sub-object of the @p suppr of type @ref
/// function_suppression, otherwise return a nil pointer.
function_suppression_sptr
is_function_suppression(const suppression_sptr suppr)
{return dynamic_pointer_cast<function_suppression>(suppr);}

/// The bitwise 'and' operator for the enum @ref
/// function_suppression::change_kind.
///
/// @param l the first operand of the 'and' operator.
///
/// @param r the second operand of the 'and' operator.
///
/// @return the result of 'and' operation on @p l and @p r.
function_suppression::change_kind
operator&(function_suppression::change_kind l,
	  function_suppression::change_kind r)
{
  return static_cast<function_suppression::change_kind>
    (static_cast<unsigned>(l) & static_cast<unsigned>(r));
}

/// The bitwise 'or' operator for the enum @ref
/// function_suppression::change_kind.
///
/// @param l the first operand of the 'or' operator.
///
/// @param r the second operand of the 'or' operator.
///
/// @return the result of 'or' operation on @p l and @p r.
function_suppression::change_kind
operator|(function_suppression::change_kind l,
	  function_suppression::change_kind r)
{
    return static_cast<function_suppression::change_kind>
      (static_cast<unsigned>(l) | static_cast<unsigned>(r));
}

  /// Test whether if a given function suppression matches a function
  /// designated by a regular expression that describes its name.
  ///
  /// @param s the suppression specification to evaluate to see if it
  /// matches a given function name.
  ///
  /// @param fn_name the name of the function of interest.  Note that
  /// this name must be *non* qualified.
  ///
  /// @return true iff the suppression specification @p s matches the
  /// function whose name is @p fn_name.
bool
suppression_matches_function_name(const suppr::function_suppression& s,
				  const string& fn_name)
{
  if (regex_t_sptr regexp = s.priv_->get_name_regex())
    {
      if (!regex::match(regexp, fn_name))
	return false;
    }
  else if (regex_t_sptr regexp = s.priv_->get_name_not_regex())
    {
      if (regex::match(regexp, fn_name))
	return false;
    }
  else if (s.priv_->name_.empty())
    return false;
  else // if (!s.priv_->name_.empty())
    {
      if (s.priv_->name_ != fn_name)
	return false;
    }

  return true;
}

/// Test whether if a given function suppression matches a function
/// designated by a regular expression that describes its linkage
/// name (symbol name).
///
/// @param s the suppression specification to evaluate to see if it
/// matches a given function linkage name
///
/// @param fn_linkage_name the linkage name of the function of interest.
///
/// @return true iff the suppression specification @p s matches the
/// function whose linkage name is @p fn_linkage_name.
bool
suppression_matches_function_sym_name(const suppr::function_suppression& s,
				      const string& fn_linkage_name)
{
  if (regex_t_sptr regexp = s.priv_->get_symbol_name_regex())
    {
      if (!regex::match(regexp, fn_linkage_name))
	return false;
    }
  else if (regex_t_sptr regexp = s.priv_->get_symbol_name_not_regex())
    {
      if (regex::match(regexp, fn_linkage_name))
	return false;
    }
  else if (s.priv_->symbol_name_.empty())
    return false;
  else // if (!s.priv_->symbol_name_.empty())
    {
      if (s.priv_->symbol_name_ != fn_linkage_name)
	return false;
    }

  return true;
}

/// Test if a variable suppression matches a variable denoted by its name.
///
/// @param s the variable suppression to consider.
///
/// @param var_name the name of the variable to consider.
///
/// @return true if the variable is matches by the suppression
/// specification.
bool
suppression_matches_variable_name(const suppr::variable_suppression& s,
				  const string& var_name)
{
  if (regex_t_sptr regexp = s.priv_->get_name_regex())
    {
      if (!regex::match(regexp, var_name))
	return false;
    }
  else if (regex_t_sptr regexp = s.priv_->get_name_not_regex())
    {
      if (regex::match(regexp, var_name))
	return false;
    }
  else if (s.priv_->name_.empty())
    return false;
  else // if (!s.priv_->name_.empty())
    {
      if (s.priv_->name_ != var_name)
	return false;
    }

  return true;
}

/// Test if a variable suppression matches a variable denoted by its
/// symbol name.
///
/// @param s the variable suppression to consider.
///
/// @param var_linkage_name the name of the variable to consider.
///
/// @return true if the variable is matches by the suppression
/// specification.
bool
suppression_matches_variable_sym_name(const suppr::variable_suppression& s,
				      const string& var_linkage_name)
{
  if (regex_t_sptr regexp = s.priv_->get_symbol_name_regex())
    {
      if (!regex::match(regexp, var_linkage_name))
	return false;
    }
  else if (regex_t_sptr regexp =
	   s.priv_->get_symbol_name_not_regex())
    {
      if (regex::match(regexp, var_linkage_name))
	return false;
    }
  else if (s.priv_->symbol_name_.empty())
    return false;
  else // if (!s.priv_->symbol_name_.empty())
    {
      if (s.priv_->symbol_name_ != var_linkage_name)
	return false;
    }

  return true;
}

/// Test if a type suppression matches a type designated by its fully
/// qualified name.
///
/// @param s the type suppression to consider.
///
/// @param type_name the name of the type to consider.
///
/// @return true iff the suppression s matches the type denoted by
/// name @p type_name.
bool
suppression_matches_type(const suppr::type_suppression& s,
			 const string& type_name)
{
  if (regex_t_sptr regexp = s.priv_->get_type_name_regex())
    {
      if (!regex::match(regexp, type_name))
	return false;
    }
  else if (!s.get_type_name().empty())
    {
      if (s.get_type_name() != type_name)
	return false;
    }
  else
    return false;

  return true;
}

/// Parse a string containing a parameter spec, build an instance of
/// function_suppression::parameter_spec from it and return a pointer
/// to that object.
///
/// @return a shared pointer pointer to the newly built instance of
/// function_suppression::parameter_spec.  If the parameter
/// specification could not be parsed, return a nil object.
static function_suppression::parameter_spec_sptr
read_parameter_spec_from_string(const string& str)
{
  string::size_type cur = 0;
  function_suppression::parameter_spec_sptr result;

  // skip leading white spaces.
  for (; cur < str.size(); ++cur)
    if (!isspace(str[cur]))
      break;

  // look for the parameter index
  string index_str;
  if (str[cur] == '\'')
    {
      ++cur;
      for (; cur < str.size(); ++cur)
	if (!isdigit(str[cur]))
	  break;
	else
	  index_str += str[cur];
    }

  // skip white spaces.
  for (; cur < str.size(); ++cur)
    if (!isspace(str[cur]))
      break;

  bool is_regex = false;
  if (str[cur] == '/')
    {
      is_regex = true;
      ++cur;
    }

  // look for the type name (regex)
  string type_name;
  for (; cur < str.size(); ++cur)
    if (!isspace(str[cur]))
      {
	if (is_regex && str[cur] == '/')
	  break;
	type_name += str[cur];
      }

  if (is_regex && str[cur] == '/')
    ++cur;

  if (!index_str.empty() || !type_name.empty())
    {
      std::string type_name_regex;
      if (is_regex)
	{
	  type_name_regex = type_name;
	  type_name.clear();
	}
      function_suppression::parameter_spec* p =
	new function_suppression::parameter_spec(atoi(index_str.c_str()),
						 type_name, type_name_regex);
      result.reset(p);
    }

  return result;
}

/// Parse function suppression specification, build a resulting @ref
/// function_suppression type and return a shared pointer to that
/// object.
///
/// @return a shared pointer to the newly built @ref
/// function_suppression.  If the function suppression specification
/// could not be parsed then a nil shared pointer is returned.
static function_suppression_sptr
read_function_suppression(const ini::config::section& section)
{
  function_suppression_sptr result;

  if (section.get_name() != "suppress_function")
    return result;

  static const char *const sufficient_props[] = {
    "label",
    "file_name_regexp",
    "file_name_not_regexp",
    "soname_regexp",
    "soname_not_regexp",
    "name",
    "name_regexp",
    "name_not_regexp",
    "parameter",
    "return_type_name",
    "return_type_regexp",
    "symbol_name",
    "symbol_name_regexp",
    "symbol_name_not_regexp",
    "symbol_version",
    "symbol_version_regexp",
  };
  if (!check_sufficient_props(sufficient_props,
			      sizeof(sufficient_props)/sizeof(char*),
			      section))
    return result;

  ini::simple_property_sptr drop_artifact =
    is_simple_property(section.find_property("drop_artifact"));
  if (!drop_artifact)
    drop_artifact = is_simple_property(section.find_property("drop"));

  string drop_artifact_str = drop_artifact
    ? drop_artifact->get_value()->as_string()
    : "";

  ini::simple_property_sptr change_kind_prop =
    is_simple_property(section.find_property("change_kind"));
  string change_kind_str = change_kind_prop
    ? change_kind_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr label_prop =
    is_simple_property(section.find_property("label"));
  string label_str = label_prop
    ? label_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr file_name_regex_prop =
    is_simple_property(section.find_property("file_name_regexp"));
  string file_name_regex_str =
    file_name_regex_prop ? file_name_regex_prop->get_value()->as_string() : "";

  ini::simple_property_sptr file_name_not_regex_prop =
    is_simple_property(section.find_property("file_name_not_regexp"));
  string file_name_not_regex_str =
    file_name_not_regex_prop
    ? file_name_not_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr soname_regex_prop =
    is_simple_property(section.find_property("soname_regexp"));
  string soname_regex_str =
    soname_regex_prop ? soname_regex_prop->get_value()->as_string() : "";

  ini::simple_property_sptr soname_not_regex_prop =
    is_simple_property(section.find_property("soname_not_regexp"));
  string soname_not_regex_str =
    soname_not_regex_prop
    ? soname_not_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr name_prop =
    is_simple_property(section.find_property("name"));
  string name = name_prop
    ? name_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr name_regex_prop =
    is_simple_property(section.find_property("name_regexp"));
  string name_regex_str = name_regex_prop
    ? name_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr name_not_regex_prop =
    is_simple_property(section.find_property("name_not_regexp"));
  string name_not_regex_str = name_not_regex_prop
    ? name_not_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr return_type_name_prop =
    is_simple_property(section.find_property("return_type_name"));
  string return_type_name = return_type_name_prop
    ? return_type_name_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr return_type_regex_prop =
    is_simple_property(section.find_property("return_type_regexp"));
  string return_type_regex_str = return_type_regex_prop
    ? return_type_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr sym_name_prop =
    is_simple_property(section.find_property("symbol_name"));
  string sym_name = sym_name_prop
    ? sym_name_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr sym_name_regex_prop =
    is_simple_property(section.find_property("symbol_name_regexp"));
  string sym_name_regex_str = sym_name_regex_prop
    ? sym_name_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr sym_name_not_regex_prop =
    is_simple_property(section.find_property("symbol_name_not_regexp"));
  string sym_name_not_regex_str = sym_name_not_regex_prop
    ? sym_name_not_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr sym_ver_prop =
    is_simple_property(section.find_property("symbol_version"));
  string sym_version = sym_ver_prop
    ? sym_ver_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr sym_ver_regex_prop =
    is_simple_property(section.find_property("symbol_version_regexp"));
  string sym_ver_regex_str = sym_ver_regex_prop
    ? sym_ver_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr allow_other_aliases_prop =
    is_simple_property(section.find_property("allow_other_aliases"));
  string allow_other_aliases = allow_other_aliases_prop
    ? allow_other_aliases_prop->get_value()->as_string()
    : "";

  function_suppression::parameter_spec_sptr parm;
  function_suppression::parameter_specs_type parms;
  for (ini::config::properties_type::const_iterator p =
	 section.get_properties().begin();
       p != section.get_properties().end();
       ++p)
    if ((*p)->get_name() == "parameter")
      {
	ini::simple_property_sptr prop = is_simple_property(*p);
	ABG_ASSERT(prop);
	if ((parm = read_parameter_spec_from_string
	      (prop->get_value()->as_string())))
	  parms.push_back(parm);
      }

  result.reset(new function_suppression(label_str,
					name,
					name_regex_str,
					return_type_name,
					return_type_regex_str,
					parms,
					sym_name,
					sym_name_regex_str,
					sym_version,
					sym_ver_regex_str));

  if ((drop_artifact_str == "yes" || drop_artifact_str == "true")
      && (!name.empty()
	  || !name_regex_str.empty()
	  || !name_not_regex_str.empty()
	  || !sym_name.empty()
	  || !sym_name_regex_str.empty()
	  || !sym_name_not_regex_str.empty()))
    result->set_drops_artifact_from_ir(true);

  if (!change_kind_str.empty())
    result->set_change_kind
      (function_suppression::parse_change_kind(change_kind_str));

  if (!allow_other_aliases.empty())
    result->set_allow_other_aliases(allow_other_aliases == "yes"
				    || allow_other_aliases == "true");

  if (!name_not_regex_str.empty())
    result->set_name_not_regex_str(name_not_regex_str);

  if (!sym_name_not_regex_str.empty())
    result->set_symbol_name_not_regex_str(sym_name_not_regex_str);

  if (!file_name_regex_str.empty())
    result->set_file_name_regex_str(file_name_regex_str);

  if (!file_name_not_regex_str.empty())
    result->set_file_name_not_regex_str(file_name_not_regex_str);

  if (!soname_regex_str.empty())
    result->set_soname_regex_str(soname_regex_str);

  if (!soname_not_regex_str.empty())
    result->set_soname_not_regex_str(soname_not_regex_str);

  return result;
}

// </function_suppression stuff>

// <variable_suppression stuff>

/// Constructor for the @ref variable_suppression type.
///
/// @param label an informative text string that the evalution code
/// might use to designate this variable suppression specification in
/// error messages.  This parameter might be empty, in which case it's
/// ignored at evaluation time.
///
/// @param name the name of the variable the user wants the current
/// specification to designate.  This parameter might be empty, in
/// which case it's ignored at evaluation time.
///
/// @param name_regex_str if @p name is empty, this parameter is a
/// regular expression for a family of names of variables the user
/// wants the current specification to designate.  If @p name is not
/// empty, then this parameter is ignored at evaluation time.  This
/// parameter might be empty, in which case it's ignored at evaluation
/// time.
///
/// @param symbol_name the name of the symbol of the variable the user
/// wants the current specification to designate.  This parameter
/// might be empty, in which case it's ignored at evaluation time.
///
/// @param symbol_name_str if @p symbol_name is empty, this parameter
/// is a regular expression for a family of names of symbols of
/// variables the user wants the current specification to designate.
/// If @p symbol_name is not empty, then this parameter is ignored at
/// evaluation time.  This parameter might be empty, in which case
/// it's ignored at evaluation time.
///
/// @param symbol_version the version of the symbol of the variable
/// the user wants the current specification to designate.  This
/// parameter might be empty, in which case it's ignored at evaluation
/// time.
///
/// @param symbol_version_regex if @p symbol_version is empty, then
/// this parameter is a regular expression for a family of versions of
/// symbol for the variables the user wants the current specification
/// to designate.  If @p symbol_version is not empty, then this
/// parameter is ignored at evaluation time.  This parameter might be
/// empty, in which case it's ignored at evaluation time.
///
/// @param type_name the name of the type of the variable the user
/// wants the current specification to designate.  This parameter
/// might be empty, in which case it's ignored at evaluation time.
///
/// @param type_name_regex_str if @p type_name is empty, then this
/// parameter is a regular expression for a family of type names of
/// variables the user wants the current specification to designate.
/// If @p type_name is not empty, then this parameter is ignored at
/// evluation time.  This parameter might be empty, in which case it's
/// ignored at evaluation time.
variable_suppression::variable_suppression(const string& label,
					   const string& name,
					   const string& name_regex_str,
					   const string& symbol_name,
					   const string& symbol_name_regex_str,
					   const string& symbol_version,
					   const string& symbol_version_regex,
					   const string& type_name,
					   const string& type_name_regex_str)
  : suppression_base(label),
    priv_(new priv(name, name_regex_str,
		   symbol_name, symbol_name_regex_str,
		   symbol_version, symbol_version_regex,
		   type_name, type_name_regex_str))
{}

/// Virtual destructor for the @erf variable_suppression type.
/// variable_suppression type.
variable_suppression::~variable_suppression()
{}

/// Parses a string containing the content of the "change-kind"
/// property and returns the an instance of @ref
/// variable_suppression::change_kind as a result.
///
/// @param s the string to parse.
///
/// @return the resulting @ref variable_suppression::change_kind.
variable_suppression::change_kind
variable_suppression::parse_change_kind(const string& s)
{
  if (s == "variable-subtype-change")
    return VARIABLE_SUBTYPE_CHANGE_KIND;
  else if (s == "added-variable")
    return ADDED_VARIABLE_CHANGE_KIND;
  else if (s == "deleted-variable")
    return DELETED_VARIABLE_CHANGE_KIND;
  else if (s == "all")
    return ALL_CHANGE_KIND;
  else
    return UNDEFINED_CHANGE_KIND;
}

/// Getter of the "change_king" property.
///
/// @return the value of the "change_kind" property.
variable_suppression::change_kind
variable_suppression::get_change_kind() const
{return priv_->change_kind_;}

/// Setter of the "change_kind" property.
///
/// @param k the new value of of the change_kind.
void
variable_suppression::set_change_kind(change_kind k)
{priv_->change_kind_ = k;}

/// Getter for the name of the variable the user wants the current
/// specification to designate.  This property might be empty, in
/// which case it's ignored at evaluation time.
///
/// @return the name of the variable.
const string&
variable_suppression::get_name() const
{return priv_->name_;}

/// Setter for the name of the variable the user wants the current
/// specification to designate.  This property might be empty, in
/// which case it's ignored at evaluation time.
///
/// @param n the new name of the variable to set.
void
variable_suppression::set_name(const string& n)
{priv_->name_ = n;}

/// Getter for the regular expression for a family of names of
/// variables the user wants the current specification to designate.
/// If the variable name as returned by
/// variable_suppression::get_name() is not empty, then this property
/// is ignored at evaluation time.  This property might be empty, in
/// which case it's ignored at evaluation time.
///
/// @return the regular expression for the variable name.
const string&
variable_suppression::get_name_regex_str() const
{return priv_->name_regex_str_;}

/// Setter for the regular expression for a family of names of
/// variables the user wants the current specification to designate.
/// If the variable name as returned by
/// variable_suppression::get_name() is not empty, then this property
/// is ignored at evaluation time.  This property might be empty, in
/// which case it's ignored at evaluation time.
///
/// @param r the new regular expression for the variable name.
void
variable_suppression::set_name_regex_str(const string& r)
{priv_->name_regex_str_ = r;}

/// Getter for the "name_not_regexp" property of the specification.
///
/// @return the value of the "name_not_regexp" property.
const string&
variable_suppression::get_name_not_regex_str() const
{return priv_->name_not_regex_str_;}

/// Setter for the "name_not_regexp" property of the specification.
///
/// @param r the new value of the "name_not_regexp" property.
void
variable_suppression::set_name_not_regex_str(const string& r)
{priv_->name_not_regex_str_ = r;}

/// Getter for the name of the symbol of the variable the user wants
/// the current specification to designate.
///
/// This property might be empty, in which case it is ignored at
/// evaluation time.
///
/// @return the name of the symbol of the variable.
const string&
variable_suppression::get_symbol_name() const
{return priv_->symbol_name_;}

/// Setter for the name of the symbol of the variable the user wants
/// the current specification to designate.
///
/// This property might be empty, in which case it is ignored at
/// evaluation time.
///
/// @param n the new name of the symbol of the variable.
void
variable_suppression::set_symbol_name(const string& n)
{priv_->symbol_name_ = n;}

/// Getter of the regular expression for a family of symbol names of
/// the variables this specification is about to designate.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.  Otherwise, it is taken in account iff the
/// property returned by variable_suppression::get_symbol_name() is
/// empty.
///
/// @return the regular expression for a symbol name of the variable.
const string&
variable_suppression::get_symbol_name_regex_str() const
{return priv_->symbol_name_regex_str_;}

/// Setter of the regular expression for a family of symbol names of
/// the variables this specification is about to designate.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.  Otherwise, it is taken in account iff the
/// property returned by variable_suppression::get_symbol_name() is
/// empty.
///
/// @param r the regular expression for a symbol name of the variable.
void
variable_suppression::set_symbol_name_regex_str(const string& r)
{priv_->symbol_name_regex_str_ = r;}

/// Getter for a regular expression for a family of names of symbols
/// of variables the user wants this specification to designate.
///
/// If a symbol name is matched by this regular expression, then the
/// suppression specification will *NOT* suppress the symbol.
///
/// If the symbol name as returned by
/// variable_suppression::get_symbol_name() is not empty, then this
/// property is ignored at specification evaluation time.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.
///
/// @return the regular expression string for a family of names of
/// symbols that is to be *NOT* suppressed by this suppression specification.
const string&
variable_suppression::get_symbol_name_not_regex_str() const
{return priv_->symbol_name_not_regex_str_;}

/// Setter for a regular expression for a family of names of symbols
/// of variables the user wants this specification to designate.
///
/// If a symbol name is matched by this regular expression, then the
/// suppression specification will *NOT* suppress the symbol.
///
/// If the symbol name as returned by
/// variable_suppression::get_symbol_name() is not empty, then this
/// property is ignored at specification evaluation time.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.
///
/// @param the new regular expression string for a family of names of
/// symbols that is to be *NOT* suppressed by this suppression
/// specification.
void
variable_suppression::set_symbol_name_not_regex_str(const string& r)
{priv_->symbol_name_not_regex_str_ = r;}

/// Getter for the version of the symbol of the variable the user
/// wants the current specification to designate.  This property might
/// be empty, in which case it's ignored at evaluation time.
///
/// @return the symbol version of the variable.
const string&
variable_suppression::get_symbol_version() const
{return priv_->symbol_version_;}

/// Setter for the version of the symbol of the variable the user
/// wants the current specification to designate.  This property might
/// be empty, in which case it's ignored at evaluation time.
///
/// @return the new symbol version of the variable.
void
variable_suppression::set_symbol_version(const string& v)
{priv_->symbol_version_ = v;}

/// Getter of the regular expression for a family of versions of
/// symbol for the variables the user wants the current specification
/// to designate.  If @p symbol_version is not empty, then this
/// property is ignored at evaluation time.  This property might be
/// empty, in which case it's ignored at evaluation time.
///
/// @return the regular expression of the symbol version of the
/// variable.
const string&
variable_suppression::get_symbol_version_regex_str() const
{return priv_->symbol_version_regex_str_;}

/// Setter of the regular expression for a family of versions of
/// symbol for the variables the user wants the current specification
/// to designate.  If @p symbol_version is not empty, then this
/// property is ignored at evaluation time.  This property might be
/// empty, in which case it's ignored at evaluation time.
///
/// @param v the new regular expression of the symbol version of the
/// variable.
void
variable_suppression::set_symbol_version_regex_str(const string& r)
{priv_->symbol_version_regex_str_ = r;}

/// Getter for the name of the type of the variable the user wants the
/// current specification to designate.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.
///
/// @return the name of the variable type.
const string&
variable_suppression::get_type_name() const
{return priv_->type_name_;}

/// Setter for the name of the type of the variable the user wants the
/// current specification to designate.
///
/// This property might be empty, in which case it's ignored at
/// evaluation time.
///
/// @param n the new name of the variable type.
void
variable_suppression::set_type_name(const string& n)
{priv_->type_name_ = n;}

/// Getter for the regular expression for a family of type names of
/// variables the user wants the current specification to designate.
///
/// If the type name as returned by
/// variable_suppression::get_type_name() is not empty, then this
/// property is ignored at evaluation time.  This property might be
/// empty, in which case it's ignored at evaluation time.
///
/// @return the regular expression of the variable type name.
const string&
variable_suppression::get_type_name_regex_str() const
{return priv_->type_name_regex_str_;}

/// Setter for the regular expression for a family of type names of
/// variables the user wants the current specification to designate.
///
/// If the type name as returned by
/// variable_suppression::get_type_name() is not empty, then this
/// property is ignored at evaluation time.  This property might be
/// empty, in which case it's ignored at evaluation time.
///
/// @param r the regular expression of the variable type name.
void
variable_suppression::set_type_name_regex_str(const string& r)
{priv_->type_name_regex_str_ = r;}

/// Evaluate this suppression specification on a given diff node and
/// say if the diff node should be suppressed or not.
///
/// @param diff the diff node to evaluate this suppression
/// specification against.
///
/// @return true if @p diff should be suppressed.
bool
variable_suppression::suppresses_diff(const diff* diff) const
{
  const var_diff* d = is_var_diff(diff);
  if (!d)
    return false;

  var_decl_sptr fv = is_var_decl(is_decl(d->first_subject())),
    sv = is_var_decl(is_decl(d->second_subject()));

  ABG_ASSERT(fv && sv);

  return (suppresses_variable(fv,
			      VARIABLE_SUBTYPE_CHANGE_KIND,
			      diff->context())
	  || suppresses_variable(sv,
				 VARIABLE_SUBTYPE_CHANGE_KIND,
				 diff->context()));
}

/// Evaluate the current variable suppression specification on a given
/// @ref var_decl and say if a report about a change involving this
/// @ref var_decl should be suppressed or not.
///
/// @param var the @ref var_decl to evaluate this suppression
/// specification against.
///
/// @param k the kind of variable change @p var is supposed to have.
///
/// @param ctxt the context of the current diff.
///
/// @return true iff a report about a change involving the variable @p
/// var should be suppressed.
bool
variable_suppression::suppresses_variable(const var_decl* var,
					  change_kind k,
					  const diff_context_sptr ctxt) const
{
  if (!(get_change_kind() & k))
    return false;

  // Check if the name and soname of the binaries match
  if (ctxt)
    {
      // Check if the name of the binaries match the current
      // suppr spec
      if (!names_of_binaries_match(*this, *ctxt))
	if (has_file_name_related_property())
	  return false;

      // Check if the soname of the binaries match the current suppr
      // spec
      if (!sonames_of_binaries_match(*this, *ctxt))
	if (has_soname_related_property())
	  return false;
    }

  string var_name = var->get_qualified_name();

  // Check for "name" property match.
  if (!get_name().empty())
    {
      if (get_name() != var_name)
	return false;
    }
  else
    {
      // If the "name" property is empty, then consider checking for the
      // "name_regex" and "name_not_regex" properties match
      if (get_name().empty())
	{
	  const regex_t_sptr name_regex = priv_->get_name_regex();
	  if (name_regex && !regex::match(name_regex, var_name))
	    return false;

	  const regex_t_sptr name_not_regex = priv_->get_name_not_regex();
	  if (name_not_regex && regex::match(name_not_regex, var_name))
	    return false;
	}
    }

  // Check for the symbol_name, symbol_name_regex and
  // symbol_name_not_regex property match.
  string var_sym_name = var->get_symbol() ? var->get_symbol()->get_name() : "";
  if (!get_symbol_name().empty())
    {
      if (get_symbol_name() != var_sym_name)
	return false;
    }
  else
    {
      const regex_t_sptr sym_name_regex = priv_->get_symbol_name_regex();
      if (sym_name_regex && !regex::match(sym_name_regex, var_sym_name))
	return false;

      const regex_t_sptr sym_name_not_regex =
	priv_->get_symbol_name_not_regex();
      if (sym_name_not_regex && regex::match(sym_name_not_regex, var_sym_name))
	return false;
    }

  // Check for symbol_version and symbol_version_regexp property match
  string var_sym_version =
    var->get_symbol() ? var->get_symbol()->get_version().str() : "";
  if (!get_symbol_version().empty())
    {
      if (get_symbol_version() != var_sym_version)
	return false;
    }
  else
    {
      const regex_t_sptr symbol_version_regex =
	priv_->get_symbol_version_regex();
      if (symbol_version_regex
	  && !regex::match(symbol_version_regex, var_sym_version))
	return false;
    }

  // Check for the "type_name" and type_name_regex properties match.
  string var_type_name =
    get_type_declaration(var->get_type())->get_qualified_name();

  if (!get_type_name().empty())
    {
      if (get_type_name() != var_type_name)
	return false;
    }
  else
    {
      if (get_type_name().empty())
	{
	  const regex_t_sptr type_name_regex = priv_->get_type_name_regex();
	  if (type_name_regex && !regex::match(type_name_regex, var_type_name))
	    return false;
	}
    }

  return true;
}

/// Evaluate the current variable suppression specification on a given
/// @ref var_decl and say if a report about a change involving this
/// @ref var_decl should be suppressed or not.
///
/// @param var the @ref var_decl to evaluate this suppression
/// specification against.
///
/// @param k the kind of variable change @p var is supposed to have.
///
/// @param ctxt the context of the current diff.
///
/// @return true iff a report about a change involving the variable @p
/// var should be suppressed.
bool
variable_suppression::suppresses_variable(const var_decl_sptr var,
					  change_kind k,
					  const diff_context_sptr ctxt) const
{return suppresses_variable(var.get(), k, ctxt);}

/// Evaluate the current variable suppression specification on a given
/// @ref elf_symbol and say if a report about a change involving this
/// @ref elf_symbol should be suppressed or not.
///
/// @param sym the @ref elf_symbol to evaluate this suppression
/// specification against.
///
/// @param k the kind of variable change @p sym is supposed to have.
///
/// @param ctxt the context of the current diff.
///
/// @return true iff a report about a change involving the symbol @p
/// sym should be suppressed.
bool
variable_suppression::suppresses_variable_symbol(const elf_symbol* sym,
						 change_kind k,
						 const diff_context_sptr ctxt) const
{
  if (!sym)
    return false;

  if (!(get_change_kind() & k))
    return false;

  if (!sym->is_variable())
    return false;

  ABG_ASSERT(k & ADDED_VARIABLE_CHANGE_KIND
	 || k & DELETED_VARIABLE_CHANGE_KIND);

  // Check if the name and soname of the binaries match the current
  // suppr spec.
  if (ctxt)
    {
      // Check if the name of the binaries match the current suppr
      // spec
      if (!names_of_binaries_match(*this, *ctxt))
	if (has_file_name_related_property())
	  return false;

      // Check if the soname of the binaries match the current suppr spec
      if (!sonames_of_binaries_match(*this, *ctxt))
	if (has_soname_related_property())
	  return false;
    }

  string sym_name = sym->get_name(), sym_version = sym->get_version().str();

  bool no_symbol_name = false, no_symbol_version = false;

  // Consider the symbol name
  if (!get_name().empty())
    {
      if (get_name() != sym_name)
	return false;
    }
  else if (!get_symbol_name().empty())
    {
      if (get_symbol_name() != sym_name)
	return false;
    }
  else if (!get_symbol_name_regex_str().empty())
    {
      const regex_t_sptr sym_name_regex = priv_->get_symbol_name_regex();
      if (sym_name_regex && !regex::match(sym_name_regex, sym_name))
	return false;
    }
  else
    no_symbol_name = true;

  // Consider the symbol version.
  if (!get_symbol_version().empty())
    {
      if (get_symbol_version() != sym_version)
	return false;
    }
  else if (!get_symbol_version_regex_str().empty())
    {
      const regex_t_sptr symbol_version_regex =
	priv_->get_symbol_version_regex();
      if (symbol_version_regex
	  && !regex::match(symbol_version_regex, sym_version))
	return false;
    }
  else
    no_symbol_version = true;

  if (no_symbol_name && no_symbol_version)
    return false;

  return true;
}

/// Evaluate the current variable suppression specification on a given
/// @ref elf_symbol and say if a report about a change involving this
/// @ref elf_symbol should be suppressed or not.
///
/// @param sym the @ref elf_symbol to evaluate this suppression
/// specification against.
///
/// @param k the kind of variable change @p sym is supposed to have.
///
/// @param ctxt the context of the current diff.
///
/// @return true iff a report about a change involving the symbol @p
/// sym should be suppressed.
bool
variable_suppression::suppresses_variable_symbol(const elf_symbol_sptr sym,
						 change_kind k,
						 const diff_context_sptr ctxt) const
{return suppresses_variable_symbol(sym.get(), k, ctxt);}

/// Test if an instance of @ref suppression is an instance of @ref
/// variable_suppression.
///
/// @param suppr the instance of @ref suppression to test for.
///
/// @return if @p suppr is an instance of @ref variable_suppression, then
/// return the sub-object of the @p suppr of type @ref
/// variable_suppression, otherwise return a nil pointer.
variable_suppression_sptr
is_variable_suppression(const suppression_sptr s)
{return dynamic_pointer_cast<variable_suppression>(s);}

/// The bitwise 'and' operator for the enum @ref
/// variable_suppression::change_kind.
///
/// @param l the first operand of the 'and' operator.
///
/// @param r the second operand of the 'and' operator.
///
/// @return the result of 'and' operation on @p l and @p r.
variable_suppression::change_kind
operator&(variable_suppression::change_kind l,
	  variable_suppression::change_kind r)
{
  return static_cast<variable_suppression::change_kind>
    (static_cast<unsigned>(l) & static_cast<unsigned>(r));
}

/// The bitwise 'or' operator for the enum @ref
/// variable_suppression::change_kind.
///
/// @param l the first operand of the 'or' operator.
///
/// @param r the second operand of the 'or' operator.
///
/// @return the result of 'or' operation on @p l and @p r.
variable_suppression::change_kind
operator|(variable_suppression::change_kind l,
	  variable_suppression::change_kind r)
{
    return static_cast<variable_suppression::change_kind>
    (static_cast<unsigned>(l) | static_cast<unsigned>(r));
}

/// Parse variable suppression specification, build a resulting @ref
/// variable_suppression type and return a shared pointer to that
/// object.
///
/// @return a shared pointer to the newly built @ref
/// variable_suppression.  If the variable suppression specification
/// could not be parsed then a nil shared pointer is returned.
static variable_suppression_sptr
read_variable_suppression(const ini::config::section& section)
{
  variable_suppression_sptr result;

  if (section.get_name() != "suppress_variable")
    return result;

  static const char *const sufficient_props[] = {
    "label",
    "file_name_regexp",
    "file_name_not_regexp",
    "soname_regexp",
    "soname_not_regexp",
    "name",
    "name_regexp",
    "name_not_regexp",
    "symbol_name",
    "symbol_name_regexp",
    "symbol_name_not_regexp",
    "symbol_version",
    "symbol_version_regexp",
    "type_name",
    "type_name_regexp",
  };
  if (!check_sufficient_props(sufficient_props,
			      sizeof(sufficient_props)/sizeof(char*),
			      section))
    return result;

  ini::simple_property_sptr drop_artifact =
    is_simple_property(section.find_property("drop_artifact"));
  if (!drop_artifact)
    drop_artifact = is_simple_property(section.find_property("drop"));

  string drop_artifact_str = drop_artifact
    ? drop_artifact->get_value()->as_string()
    : "";

  ini::simple_property_sptr change_kind_prop =
    is_simple_property(section.find_property("change_kind"));
  string change_kind_str = change_kind_prop
    ? change_kind_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr label_prop =
    is_simple_property(section.find_property("label"));
  string label_str = (label_prop
		      ? label_prop->get_value()->as_string()
		      : "");

  ini::simple_property_sptr file_name_regex_prop =
    is_simple_property(section.find_property("file_name_regexp"));
  string file_name_regex_str =
    file_name_regex_prop ? file_name_regex_prop->get_value()->as_string() : "";

 ini::simple_property_sptr file_name_not_regex_prop =
    is_simple_property(section.find_property("file_name_not_regexp"));
  string file_name_not_regex_str =
    file_name_not_regex_prop
    ? file_name_not_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr soname_regex_prop =
    is_simple_property(section.find_property("soname_regexp"));
  string soname_regex_str =
    soname_regex_prop ? soname_regex_prop->get_value()->as_string() : "";

  ini::simple_property_sptr soname_not_regex_prop =
    is_simple_property(section.find_property("soname_not_regexp"));
  string soname_not_regex_str =
    soname_not_regex_prop
    ? soname_not_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr name_prop =
    is_simple_property(section.find_property("name"));
  string name_str = (name_prop
		     ? name_prop->get_value()->as_string()
		     : "");

  ini::simple_property_sptr name_regex_prop =
    is_simple_property(section.find_property("name_regexp"));
  string name_regex_str = (name_regex_prop
			   ? name_regex_prop->get_value()->as_string()
			   : "");

  ini::simple_property_sptr name_not_regex_prop =
    is_simple_property(section.find_property("name_not_regexp"));
  string name_not_regex_str = name_not_regex_prop
    ? name_not_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr sym_name_prop =
    is_simple_property(section.find_property("symbol_name"));
  string symbol_name = (sym_name_prop
			? sym_name_prop->get_value()->as_string()
			: "");

  ini::simple_property_sptr sym_name_regex_prop =
    is_simple_property(section.find_property("symbol_name_regexp"));
  string symbol_name_regex_str = sym_name_regex_prop
    ? sym_name_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr sym_name_not_regex_prop =
    is_simple_property(section.find_property("symbol_name_not_regexp"));
  string symbol_name_not_regex_str = sym_name_not_regex_prop
    ? sym_name_not_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr sym_version_prop =
    is_simple_property(section.find_property("symbol_version"));
  string symbol_version = sym_version_prop
    ? sym_version_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr sym_version_regex_prop =
    is_simple_property(section.find_property("symbol_version_regexp"));
  string symbol_version_regex_str = sym_version_regex_prop
    ? sym_version_regex_prop->get_value()->as_string()
     : "";

  ini::simple_property_sptr type_name_prop =
    is_simple_property(section.find_property("type_name"));
  string type_name_str = type_name_prop
    ? type_name_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr type_name_regex_prop =
    is_simple_property(section.find_property("type_name_regexp"));
  string type_name_regex_str = type_name_regex_prop
    ? type_name_regex_prop->get_value()->as_string()
     : "";

  result.reset(new variable_suppression(label_str,
					name_str,
					name_regex_str,
					symbol_name,
					symbol_name_regex_str,
					symbol_version,
					symbol_version_regex_str,
					type_name_str,
					type_name_regex_str));

  if ((drop_artifact_str == "yes" || drop_artifact_str == "true")
      && (!name_str.empty()
	  || !name_regex_str.empty()
	  || !name_not_regex_str.empty()
	  || !symbol_name.empty()
	  || !symbol_name_regex_str.empty()
	  || !symbol_name_not_regex_str.empty()))
    result->set_drops_artifact_from_ir(true);

  if (!name_not_regex_str.empty())
    result->set_name_not_regex_str(name_not_regex_str);

  if (!symbol_name_not_regex_str.empty())
    result->set_symbol_name_not_regex_str(symbol_name_not_regex_str);

  if (!change_kind_str.empty())
    result->set_change_kind
      (variable_suppression::parse_change_kind(change_kind_str));

  if (!file_name_regex_str.empty())
    result->set_file_name_regex_str(file_name_regex_str);

  if (!file_name_not_regex_str.empty())
    result->set_file_name_not_regex_str(file_name_not_regex_str);

  if (!soname_regex_str.empty())
    result->set_soname_regex_str(soname_regex_str);

  if (!soname_not_regex_str.empty())
    result->set_soname_not_regex_str(soname_not_regex_str);

  return result;
}

// </variable_suppression stuff>

// <file_suppression stuff>

/// Constructor for the the @ref file_suppression type.
///
/// @param label the label of the suppression directive.
///
/// @param fname_regex_str the regular expression string that
/// designates the file name that instances of @ref file_suppression
/// should match.
///
/// @param fname_not_regex_str the regular expression string that
/// designates the file name that instances of @ref file_suppression
/// shoult *NOT* match.  In other words, this file_suppression should
/// be activated if its file name does not match the regular
/// expression @p fname_not_regex_str.
file_suppression::file_suppression(const string& label,
				   const string& fname_regex_str,
				   const string& fname_not_regex_str)
  : suppression_base(label,
		     fname_regex_str,
		     fname_not_regex_str)
{}

/// Test if instances of this @ref file_suppression suppresses a
/// certain instance of @ref diff.
///
/// This function always returns false because, obviously, a
/// file_suppression is meants to prevents Abigail tools from loading
/// some files.  It is not meant to act on instance of @ref diff.
/// @return false.
bool
file_suppression::suppresses_diff(const diff*) const
{return false;}

/// Test if a instances of this @ref file_suppression suppresses a
/// given file.
///
/// @param file_path the file path to test against.
///
/// @return true iff this file_suppression matches the file path @p
/// file_path.
bool
file_suppression::suppresses_file(const string& file_path)
{
  if (file_path.empty())
    return false;

  string fname;
  tools_utils::base_name(file_path, fname);

  bool has_regexp = false;

  if (regex_t_sptr regexp = suppression_base::priv_->get_file_name_regex())
    {
      has_regexp = true;
      if (!regex::match(regexp, fname))
	return false;
    }

  if (regex_t_sptr regexp = suppression_base::priv_->get_file_name_not_regex())
    {
      has_regexp = true;
      if (regex::match(regexp, fname))
	return false;
    }

  if (!has_regexp)
    return false;

  return true;
}

/// Destructor of @ref file_suppression.
file_suppression::~file_suppression()
{
}

/// Read a file suppression from an instance of ini::config::section
/// and build a @ref type_suppression as a result.
///
/// @param section the section (from an ini file) to read the file
/// suppression from.
///
/// @return file_suppression_sptr.
static file_suppression_sptr
read_file_suppression(const ini::config::section& section)
{
  file_suppression_sptr result;

  if (section.get_name() != "suppress_file")
    return result;

  static const char *const sufficient_props[] = {
    "file_name_regexp",
    "file_name_not_regexp",
    "soname_regexp",
    "soname_not_regexp",
  };
  if (!check_sufficient_props(sufficient_props,
			      sizeof(sufficient_props)/sizeof(char*),
			      section))
    return result;

  ini::simple_property_sptr label_prop =
    is_simple_property(section.find_property("label"));
  string label_str = (label_prop
		      ? label_prop->get_value()->as_string()
		      : "");

  ini::simple_property_sptr file_name_regex_prop =
    is_simple_property(section.find_property("file_name_regexp"));
  string file_name_regex_str =
    file_name_regex_prop ? file_name_regex_prop->get_value()->as_string() : "";

 ini::simple_property_sptr file_name_not_regex_prop =
    is_simple_property(section.find_property("file_name_not_regexp"));
  string file_name_not_regex_str =
    file_name_not_regex_prop
    ? file_name_not_regex_prop->get_value()->as_string()
    : "";

  ini::simple_property_sptr soname_regex_prop =
    is_simple_property(section.find_property("soname_regexp"));
  string soname_regex_str =
    soname_regex_prop ? soname_regex_prop->get_value()->as_string() : "";

  ini::simple_property_sptr soname_not_regex_prop =
    is_simple_property(section.find_property("soname_not_regexp"));
  string soname_not_regex_str =
    soname_not_regex_prop
    ? soname_not_regex_prop->get_value()->as_string()
    : "";

  result.reset(new file_suppression(label_str,
				    file_name_regex_str,
				    file_name_not_regex_str));

  if (!soname_regex_str.empty())
    {
      result->set_soname_regex_str(soname_regex_str);
      result->set_drops_artifact_from_ir(true);
    }

  if (!soname_not_regex_str.empty())
    {
      result->set_soname_not_regex_str(soname_not_regex_str);
      result->set_drops_artifact_from_ir(true);
    }

  return result;
}

/// Test if a given suppression specification is a file suppression
/// specification.
///
/// @param s the instance of @ref suppression_base to test.
///
/// @return the instance of @ref file_suppression that @p s points to,
/// iff s is an instance of @ref file_suppression.  Otherwise, returns
/// nil.
file_suppression_sptr
is_file_suppression(const suppression_sptr s)
{return dynamic_pointer_cast<file_suppression>(s);}

/// Test if a given file path is "suppressed" by at least one file
/// suppression specification among a vector of suppression
/// specifications.
///
/// @param file_path the file path to test.
///
/// @param sprs the vector of suppressions to use to test if one of
/// them at lease matches the file path @p file_path.
///
/// @return a pointer to the first instance of @ref file_suppression
/// that matches @p file_path, or nil if no file suppression matches.
file_suppression_sptr
file_is_suppressed(const string& file_path,
		   const suppressions_type& sprs)
{
  for (suppressions_type::const_iterator i = sprs.begin(); i != sprs.end(); ++i)
    if (file_suppression_sptr s = is_file_suppression(*i))
      if (s->suppresses_file(file_path))
	return s;

  return file_suppression_sptr();
}

/// Test if a given SONAME is matched by a given suppression
/// specification.
///
/// @param soname the SONAME to consider.
///
/// @param suppr the suppression specification to consider.
///
/// @return true iff a given SONAME is matched by a given suppression
/// specification.
bool
suppression_matches_soname(const string& soname,
			   const suppression_base& suppr)
{
  return suppr.priv_->matches_soname(soname);
}

/// Test if a given SONAME or file name is matched by a given
/// suppression specification.
///
/// @param soname the SONAME to consider.
///
/// @param filename the file name to consider.
///
/// @param suppr the suppression specification to consider.
///
/// @return true iff either @p soname or @p filename is matched by the
/// suppression specification @p suppr.
bool
suppression_matches_soname_or_filename(const string& soname,
				       const string& filename,
				       const suppression_base& suppr)
{
  return (suppression_matches_soname(soname, suppr)
	 || suppr.priv_->matches_binary_name(filename));
}

/// @return the name of the artificial private type suppression
/// specification that is auto-generated by libabigail to suppress
/// change reports about types that are not defined in public headers.
const char*
get_private_types_suppr_spec_label()
{
  static const char *PRIVATE_TYPES_SUPPR_SPEC_NAME =
    "Artificial private types suppression specification";

  return PRIVATE_TYPES_SUPPR_SPEC_NAME;
}

/// Test if a type suppression specification represents a private type
/// suppression automatically generated by libabigail from the user
/// telling us where public headers are.
///
/// @param s the suppression specification we are looking at.
///
/// @return true iff @p s is a private type suppr spec.
bool
is_private_type_suppr_spec(const type_suppression& s)
{return s.get_label() == get_private_types_suppr_spec_label();}

/// Test if a type suppression specification represents a private type
/// suppression automatically generated by libabigail from the user
/// telling us where public headers are.
///
/// @param s the suppression specification we are looking at.
///
/// @return true iff @p s is a private type suppr spec.
bool
is_private_type_suppr_spec(const suppression_sptr& s)
{
  type_suppression_sptr type_suppr = is_type_suppression(s);
  return (type_suppr
	  && type_suppr->get_label() == get_private_types_suppr_spec_label());
}

// </file_suppression stuff>
}// end namespace suppr
} // end namespace abigail
