/* Generic plugin context
   Copyright (C) 2020 Free Software Foundation, Inc.

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 <cc1plugin-config.h>

#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION

#include "../gcc/config.h"

#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION

#include "gcc-plugin.h"
#include "system.h"
#include "coretypes.h"
#include "stringpool.h"
#include "hash-set.h"
#include "diagnostic.h"
#include "langhooks.h"
#include "langhooks-def.h"

#include "gcc-interface.h"

#include "context.hh"
#include "marshall.hh"



#ifdef __GNUC__
#pragma GCC visibility push(default)
#endif
int plugin_is_GPL_compatible;
#ifdef __GNUC__
#pragma GCC visibility pop
#endif

cc1_plugin::plugin_context *cc1_plugin::current_context;



// This is put into the lang hooks when the plugin starts.

static void
plugin_print_error_function (diagnostic_context *context, const char *file,
			     diagnostic_info *diagnostic)
{
  if (current_function_decl != NULL_TREE
      && DECL_NAME (current_function_decl) != NULL_TREE
      && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
		 GCC_FE_WRAPPER_FUNCTION) == 0)
    return;
  lhd_print_error_function (context, file, diagnostic);
}



location_t
cc1_plugin::plugin_context::get_location_t (const char *filename,
					    unsigned int line_number)
{
  if (filename == NULL)
    return UNKNOWN_LOCATION;

  filename = intern_filename (filename);
  linemap_add (line_table, LC_ENTER, false, filename, line_number);
  location_t loc = linemap_line_start (line_table, line_number, 0);
  linemap_add (line_table, LC_LEAVE, false, NULL, 0);
  return loc;
}

// Add a file name to FILE_NAMES and return the canonical copy.
const char *
cc1_plugin::plugin_context::intern_filename (const char *filename)
{
  const char **slot = file_names.find_slot (filename, INSERT);
  if (*slot == NULL)
    {
      /* The file name must live as long as the line map, which
	 effectively means as long as this compilation.  So, we copy
	 the string here but never free it.  */
      *slot = xstrdup (filename);
    }
  return *slot;
}

void
cc1_plugin::plugin_context::mark ()
{
  for (const auto &item : address_map)
    {
      ggc_mark (item->decl);
      ggc_mark (item->address);
    }

  for (const auto &item : preserved)
    ggc_mark (&item);
}



// Perform GC marking.

static void
gc_mark (void *, void *)
{
  if (cc1_plugin::current_context != NULL)
    cc1_plugin::current_context->mark ();
}

void
cc1_plugin::generic_plugin_init (struct plugin_name_args *plugin_info,
				 unsigned int version)
{
  long fd = -1;
  for (int i = 0; i < plugin_info->argc; ++i)
    {
      if (strcmp (plugin_info->argv[i].key, "fd") == 0)
	{
	  char *tail;
	  errno = 0;
	  fd = strtol (plugin_info->argv[i].value, &tail, 0);
	  if (*tail != '\0' || errno != 0)
	    fatal_error (input_location,
			 "%s: invalid file descriptor argument to plugin",
			 plugin_info->base_name);
	  break;
	}
    }
  if (fd == -1)
    fatal_error (input_location,
		 "%s: required plugin argument %<fd%> is missing",
		 plugin_info->base_name);

  current_context = new plugin_context (fd);

  // Handshake.
  cc1_plugin::protocol_int h_version;
  if (!current_context->require ('H')
      || ! ::cc1_plugin::unmarshall (current_context, &h_version))
    fatal_error (input_location,
		 "%s: handshake failed", plugin_info->base_name);
  if (h_version != version)
    fatal_error (input_location,
		 "%s: unknown version in handshake", plugin_info->base_name);

  register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING,
		     gc_mark, NULL);

  lang_hooks.print_error_function = plugin_print_error_function;
}
