/* Subclasses of logical_location with knowledge of "tree".
   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"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
#include "pretty-print.h"
#include "tree-logical-location.h"
#include "langhooks.h"

/* class compiler_logical_location : public logical_location.  */

/* Get a string for DECL suitable for use by the SARIF logicalLocation
   "name" property (SARIF v2.1.0 section 3.33.4).  */

const char *
compiler_logical_location::get_short_name_for_tree (tree decl)
{
  gcc_assert (decl);
  return identifier_to_locale (lang_hooks.decl_printable_name (decl, 0));
}

/* Get a string for DECL suitable for use by the SARIF logicalLocation
   "fullyQualifiedName" property (SARIF v2.1.0 section 3.33.5).  */

const char *
compiler_logical_location::get_name_with_scope_for_tree (tree decl)
{
  gcc_assert (decl);
  return identifier_to_locale (lang_hooks.decl_printable_name (decl, 1));
}

/* Get a string for DECL suitable for use by the SARIF logicalLocation
   "decoratedName" property (SARIF v2.1.0 section 3.33.6).  */

const char *
compiler_logical_location::get_internal_name_for_tree (tree decl)
{
  gcc_assert (decl);
  if (HAS_DECL_ASSEMBLER_NAME_P (decl))
    if (tree id = DECL_ASSEMBLER_NAME (decl))
      return IDENTIFIER_POINTER (id);
  return NULL;
}

/* Get what kind of SARIF logicalLocation DECL is (if any).  */

enum logical_location_kind
compiler_logical_location::get_kind_for_tree (tree decl)
{
  if (!decl)
    return LOGICAL_LOCATION_KIND_UNKNOWN;

  switch (TREE_CODE (decl))
    {
    default:
      return LOGICAL_LOCATION_KIND_UNKNOWN;
    case FUNCTION_DECL:
      return LOGICAL_LOCATION_KIND_FUNCTION;
    case PARM_DECL:
      return LOGICAL_LOCATION_KIND_PARAMETER;
    case VAR_DECL:
      return LOGICAL_LOCATION_KIND_VARIABLE;
    }
}

/* class tree_logical_location : public compiler_logical_location.  */

/* Implementation of the logical_location vfuncs, using m_decl.  */

const char *
tree_logical_location::get_short_name () const
{
  gcc_assert (m_decl);
  return get_short_name_for_tree (m_decl);
}

const char *
tree_logical_location::get_name_with_scope () const
{
  gcc_assert (m_decl);
  return get_name_with_scope_for_tree (m_decl);
}

const char *
tree_logical_location::get_internal_name () const
{
  gcc_assert (m_decl);
  return get_internal_name_for_tree (m_decl);
}

enum logical_location_kind
tree_logical_location::get_kind () const
{
  gcc_assert (m_decl);
  return get_kind_for_tree (m_decl);
}

/* class current_fndecl_logical_location : public compiler_logical_location.  */

/* Implementation of the logical_location vfuncs, using
   current_function_decl.  */

const char *
current_fndecl_logical_location::get_short_name () const
{
  gcc_assert (current_function_decl);
  return get_short_name_for_tree (current_function_decl);
}

const char *
current_fndecl_logical_location::get_name_with_scope () const
{
  gcc_assert (current_function_decl);
  return get_name_with_scope_for_tree (current_function_decl);
}

const char *
current_fndecl_logical_location::get_internal_name () const
{
  gcc_assert (current_function_decl);
  return get_internal_name_for_tree (current_function_decl);
}

enum logical_location_kind
current_fndecl_logical_location::get_kind () const
{
  gcc_assert (current_function_decl);
  return get_kind_for_tree (current_function_decl);
}
