/* Code dealing with "using" directives for GDB.
   Copyright (C) 2003-2024 Free Software Foundation, Inc.

   This file is part of GDB.

   This program 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 of the License, or
   (at your option) any later version.

   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "namespace.h"
#include "frame.h"
#include "symtab.h"

/* Add a using directive to USING_DIRECTIVES.  If the using directive
   in question has already been added, don't add it twice.

   Create a new struct using_direct which imports the namespace SRC
   into the scope DEST.  ALIAS is the name of the imported namespace
   in the current scope.  If ALIAS is NULL then the namespace is known
   by its original name.  DECLARATION is the name if the imported
   variable if this is a declaration import (Eg. using A::x),
   otherwise it is NULL.  EXCLUDES is a list of names not to import
   from an imported module or NULL.  For EXCLUDES the contents of the
   vector are copied, but the pointed to characters are not
   copied.  */

void
add_using_directive (struct using_direct **using_directives,
		     const char *dest,
		     const char *src,
		     const char *alias,
		     const char *declaration,
		     const std::vector<const char *> &excludes,
		     unsigned int decl_line,
		     struct obstack *obstack)
{
  struct using_direct *current;
  struct using_direct *newobj;
  int alloc_len;

  /* Has it already been added?  */

  for (current = *using_directives; current != NULL; current = current->next)
    {
      int ix;

      if (strcmp (current->import_src, src) != 0)
	continue;
      if (strcmp (current->import_dest, dest) != 0)
	continue;
      if ((alias == NULL && current->alias != NULL)
	  || (alias != NULL && current->alias == NULL)
	  || (alias != NULL && current->alias != NULL
	      && strcmp (alias, current->alias) != 0))
	continue;
      if ((declaration == NULL && current->declaration != NULL)
	  || (declaration != NULL && current->declaration == NULL)
	  || (declaration != NULL && current->declaration != NULL
	      && strcmp (declaration, current->declaration) != 0))
	continue;

      /* Compare the contents of EXCLUDES.  */
      for (ix = 0; ix < excludes.size (); ++ix)
	if (current->excludes[ix] == NULL
	    || strcmp (excludes[ix], current->excludes[ix]) != 0)
	  break;
      if (ix < excludes.size () || current->excludes[ix] != NULL)
	continue;

      if (decl_line != current->decl_line)
	continue;

      /* Parameters exactly match CURRENT.  */
      return;
    }

  alloc_len = (sizeof(*newobj)
	       + (excludes.size () * sizeof(*newobj->excludes)));
  newobj = (struct using_direct *) obstack_alloc (obstack, alloc_len);
  memset (newobj, 0, sizeof (*newobj));

  newobj->import_src = src;
  newobj->import_dest = dest;
  newobj->alias = alias;
  newobj->declaration = declaration;

  if (!excludes.empty ())
    memcpy (newobj->excludes, excludes.data (),
	    excludes.size () * sizeof (*newobj->excludes));
  newobj->excludes[excludes.size ()] = NULL;

  newobj->decl_line = decl_line;

  newobj->next = *using_directives;
  *using_directives = newobj;
}

/* See namespace.h.  */

bool
using_direct::valid_line (unsigned int boundary) const
{
  try
    {
      CORE_ADDR curr_pc = get_frame_pc (get_selected_frame (nullptr));
      symtab_and_line curr_sal = find_pc_line (curr_pc, 0);
      return (decl_line <= curr_sal.line)
	     || (decl_line >= boundary);
    }
  catch (const gdb_exception &ex)
    {
      return true;
    }
}
