/* Support for plugin-supplied behaviors of known functions.
   Copyright (C) 2022-2023 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"
#include "analyzer/call-details.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 */
