/* Support for plugin-supplied behaviors of known functions.
   Copyright (C) 2022 Free Software Foundation, Inc.
   Contributed by David Malcolm <dmalcolm@redhat.com>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
#include "analyzer/analyzer.h"
#include "diagnostic-core.h"
#include "analyzer/analyzer-logging.h"
#include "stringpool.h"
#include "basic-block.h"
#include "gimple.h"
#include "analyzer/known-function-manager.h"
#include "analyzer/region-model.h"

#if ENABLE_ANALYZER

namespace ana {

/* class known_function_manager : public log_user.  */

known_function_manager::known_function_manager (logger *logger)
: log_user (logger)
{
  memset (m_combined_fns_arr, 0, sizeof (m_combined_fns_arr));
}

known_function_manager::~known_function_manager ()
{
  /* Delete all owned kfs.  */
  for (auto iter : m_map_id_to_kf)
    delete iter.second;
  for (auto iter : m_combined_fns_arr)
    delete iter;
}

void
known_function_manager::add (const char *name,
			     std::unique_ptr<known_function> kf)
{
  LOG_FUNC_1 (get_logger (), "registering %s", name);
  tree id = get_identifier (name);
  m_map_id_to_kf.put (id, kf.release ());
}

void
known_function_manager::add (enum built_in_function name,
			     std::unique_ptr<known_function> kf)
{
  gcc_assert (name < END_BUILTINS);
  delete m_combined_fns_arr[name];
  m_combined_fns_arr[name] = kf.release ();
}

void
known_function_manager::add (enum internal_fn ifn,
			     std::unique_ptr<known_function> kf)
{
  gcc_assert (ifn < IFN_LAST);
  delete m_combined_fns_arr[ifn + END_BUILTINS];
  m_combined_fns_arr[ifn + END_BUILTINS] = kf.release ();
}

/* Get any known_function for FNDECL for call CD.

   The call must match all assumptions made by the known_function (such as
   e.g. "argument 1's type must be a pointer type").

   Return NULL if no known_function is found, or it does not match the
   assumption(s).  */

const known_function *
known_function_manager::get_match (tree fndecl, const call_details &cd) const
{
  /* Look for a matching built-in.  */
  if (fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
    {
      if (const known_function *candidate
	  = get_normal_builtin (DECL_FUNCTION_CODE (fndecl)))
	if (gimple_builtin_call_types_compatible_p (cd.get_call_stmt (),
						    fndecl))
	  return candidate;
    }

  /* Look for a match by name.  */

  /* Reject fndecls that aren't in the root namespace.  */
  if (DECL_CONTEXT (fndecl)
      && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL)
    return NULL;
  if (tree identifier = DECL_NAME (fndecl))
    if (const known_function *candidate = get_by_identifier (identifier))
      if (candidate->matches_call_types_p (cd))
	return candidate;

  return NULL;
}

/* Get any known_function for IFN, or NULL.  */

const known_function *
known_function_manager::get_internal_fn (enum internal_fn ifn) const
{
  gcc_assert (ifn < IFN_LAST);
  return m_combined_fns_arr[ifn + END_BUILTINS];
}

/* Get any known_function for NAME, without type-checking.
   Return NULL if there isn't one.  */

const known_function *
known_function_manager::get_normal_builtin (enum built_in_function name) const
{
  /* The numbers for built-in functions in enum combined_fn are the same as
     for the built_in_function enum.  */
  gcc_assert (name < END_BUILTINS);
  return m_combined_fns_arr[name];
}

/* Get any known_function matching IDENTIFIER, without type-checking.
   Return NULL if there isn't one.  */

const known_function *
known_function_manager::get_by_identifier (tree identifier) const
{
  known_function_manager *mut_this = const_cast<known_function_manager *>(this);
  known_function **slot = mut_this->m_map_id_to_kf.get (identifier);
  if (slot)
    return *slot;
  else
    return NULL;
}

} // namespace ana

#endif /* #if ENABLE_ANALYZER */
