/* Library interface to C front end
   Copyright (C) 2014-2021 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 "gcc-interface.h"
#include "hash-set.h"
#include "machmode.h"
#include "vec.h"
#include "double-int.h"
#include "input.h"
#include "alias.h"
#include "symtab.h"
#include "options.h"
#include "wide-int.h"
#include "inchash.h"
#include "tree.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "c-tree.h"
#include "toplev.h"
#include "timevar.h"
#include "hash-table.h"
#include "tm.h"
#include "c-family/c-pragma.h"
#include "c-lang.h"
#include "diagnostic.h"
#include "langhooks.h"
#include "langhooks-def.h"

#include "callbacks.hh"
#include "connection.hh"
#include "marshall.hh"
#include "rpc.hh"
#include "gcc-c-interface.h"
#include "context.hh"

#include <vector>

using namespace cc1_plugin;



// A wrapper for pushdecl that doesn't let gdb have a chance to
// instantiate a symbol.

static void
pushdecl_safe (tree decl)
{
  void (*save) (enum c_oracle_request, tree identifier);

  save = c_binding_oracle;
  c_binding_oracle = NULL;
  pushdecl (decl);
  c_binding_oracle = save;
}



static void
plugin_binding_oracle (enum c_oracle_request kind, tree identifier)
{
  enum gcc_c_oracle_request request;

  gcc_assert (current_context != NULL);

  switch (kind)
    {
    case C_ORACLE_SYMBOL:
      request = GCC_C_ORACLE_SYMBOL;
      break;
    case C_ORACLE_TAG:
      request = GCC_C_ORACLE_TAG;
      break;
    case C_ORACLE_LABEL:
      request = GCC_C_ORACLE_LABEL;
      break;
    default:
      abort ();
    }

  int ignore;
  cc1_plugin::call (current_context, "binding_oracle", &ignore,
		    request, IDENTIFIER_POINTER (identifier));
}

static void
plugin_pragma_user_expression (cpp_reader *)
{
  c_binding_oracle = plugin_binding_oracle;
}

static void
plugin_init_extra_pragmas (void *, void *)
{
  c_register_pragma ("GCC", "user_expression", plugin_pragma_user_expression);
}



// Maybe rewrite a decl to its address.
static tree
address_rewriter (tree *in, int *walk_subtrees, void *arg)
{
  plugin_context *ctx = (plugin_context *) arg;

  if (!DECL_P (*in) || DECL_NAME (*in) == NULL_TREE)
    return NULL_TREE;

  decl_addr_value value;
  value.decl = *in;
  decl_addr_value *found_value = ctx->address_map.find (&value);
  if (found_value != NULL)
    ;
  else if (DECL_IS_UNDECLARED_BUILTIN (*in))
    {
      gcc_address address;

      if (!cc1_plugin::call (ctx, "address_oracle", &address,
			     IDENTIFIER_POINTER (DECL_NAME (*in))))
	return NULL_TREE;
      if (address == 0)
	return NULL_TREE;

      // Insert the decl into the address map in case it is referenced
      // again.
      value.address = build_int_cst_type (ptr_type_node, address);
      decl_addr_value **slot = ctx->address_map.find_slot (&value, INSERT);
      gcc_assert (*slot == NULL);
      *slot
	= static_cast<decl_addr_value *> (xmalloc (sizeof (decl_addr_value)));
      **slot = value;
      found_value = *slot;
    }
  else
    return NULL_TREE;

  if (found_value->address != error_mark_node)
    {
      // We have an address for the decl, so rewrite the tree.
      tree ptr_type = build_pointer_type (TREE_TYPE (*in));
      *in = fold_build1 (INDIRECT_REF, TREE_TYPE (*in),
			 fold_build1 (CONVERT_EXPR, ptr_type,
				      found_value->address));
    }

  *walk_subtrees = 0;

  return NULL_TREE;
}

// When generating code for gdb, we want to be able to use absolute
// addresses to refer to otherwise external objects that gdb knows
// about.  gdb passes in these addresses when building decls, and then
// before gimplification we go through the trees, rewriting uses to
// the equivalent of "*(TYPE *) ADDR".
static void
rewrite_decls_to_addresses (void *function_in, void *)
{
  tree function = (tree) function_in;

  // Do nothing if we're not in gdb.
  if (current_context == NULL)
    return;

  walk_tree (&DECL_SAVED_TREE (function), address_rewriter, current_context,
	     NULL);
}



gcc_decl
plugin_build_decl (cc1_plugin::connection *self,
		   const char *name,
		   enum gcc_c_symbol_kind sym_kind,
		   gcc_type sym_type_in,
		   const char *substitution_name,
		   gcc_address address,
		   const char *filename,
		   unsigned int line_number)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree identifier = get_identifier (name);
  enum tree_code code;
  tree decl;
  tree sym_type = convert_in (sym_type_in);

  switch (sym_kind)
    {
    case GCC_C_SYMBOL_FUNCTION:
      code = FUNCTION_DECL;
      break;

    case GCC_C_SYMBOL_VARIABLE:
      code = VAR_DECL;
      break;

    case GCC_C_SYMBOL_TYPEDEF:
      code = TYPE_DECL;
      break;

    case GCC_C_SYMBOL_LABEL:
      // FIXME: we aren't ready to handle labels yet.
      // It isn't clear how to translate them properly
      // and in any case a "goto" isn't likely to work.
      return convert_out (error_mark_node);

    default:
      abort ();
    }

  location_t loc = ctx->get_location_t (filename, line_number);

  decl = build_decl (loc, code, identifier, sym_type);
  TREE_USED (decl) = 1;
  TREE_ADDRESSABLE (decl) = 1;

  if (sym_kind != GCC_C_SYMBOL_TYPEDEF)
    {
      decl_addr_value value;

      DECL_EXTERNAL (decl) = 1;
      value.decl = decl;
      if (substitution_name != NULL)
	{
	  // If the translator gave us a name without a binding,
	  // we can just substitute error_mark_node, since we know the
	  // translator will be reporting an error anyhow.
	  value.address
	    = lookup_name (get_identifier (substitution_name));
	  if (value.address == NULL_TREE)
	    value.address = error_mark_node;
	}
      else
	value.address = build_int_cst_type (ptr_type_node, address);
      decl_addr_value **slot = ctx->address_map.find_slot (&value, INSERT);
      gcc_assert (*slot == NULL);
      *slot
	= static_cast<decl_addr_value *> (xmalloc (sizeof (decl_addr_value)));
      **slot = value;
    }

  return convert_out (ctx->preserve (decl));
}

int
plugin_bind (cc1_plugin::connection *,
	     gcc_decl decl_in, int is_global)
{
  tree decl = convert_in (decl_in);
  c_bind (DECL_SOURCE_LOCATION (decl), decl, is_global);
  rest_of_decl_compilation (decl, is_global, 0);
  return 1;
}

int
plugin_tagbind (cc1_plugin::connection *self,
		const char *name, gcc_type tagged_type,
		const char *filename, unsigned int line_number)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree t = convert_in (tagged_type), x;
  c_pushtag (ctx->get_location_t (filename, line_number),
	     get_identifier (name), t);

  /* Propagate the newly-added type name so that previously-created
     variant types are not disconnected from their main variants.  */
  for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
    TYPE_NAME (x) = TYPE_NAME (t);

  return 1;
}

gcc_type
plugin_build_pointer_type (cc1_plugin::connection *,
			   gcc_type base_type)
{
  // No need to preserve a pointer type as the base type is preserved.
  return convert_out (build_pointer_type (convert_in (base_type)));
}

// TYPE_NAME needs to be a valid pointer, even if there is no name available.

static tree
build_anonymous_node (enum tree_code code)
{
  tree node = make_node (code);
  tree type_decl = build_decl (input_location, TYPE_DECL, NULL_TREE, node);
  TYPE_NAME (node) = type_decl;
  TYPE_STUB_DECL (node) = type_decl;
  return node;
}

gcc_type
plugin_build_record_type (cc1_plugin::connection *self)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  return convert_out (ctx->preserve (build_anonymous_node (RECORD_TYPE)));
}

gcc_type
plugin_build_union_type (cc1_plugin::connection *self)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  return convert_out (ctx->preserve (build_anonymous_node (UNION_TYPE)));
}

int
plugin_build_add_field (cc1_plugin::connection *,
			gcc_type record_or_union_type_in,
			const char *field_name,
			gcc_type field_type_in,
			unsigned long bitsize,
			unsigned long bitpos)
{
  tree record_or_union_type = convert_in (record_or_union_type_in);
  tree field_type = convert_in (field_type_in);

  gcc_assert (TREE_CODE (record_or_union_type) == RECORD_TYPE
	      || TREE_CODE (record_or_union_type) == UNION_TYPE);

  /* Note that gdb does not preserve the location of field decls, so
     we can't provide a decent location here.  */
  tree decl = build_decl (BUILTINS_LOCATION, FIELD_DECL,
			  get_identifier (field_name), field_type);
  DECL_FIELD_CONTEXT (decl) = record_or_union_type;

  if (TREE_CODE (field_type) == INTEGER_TYPE
      && TYPE_PRECISION (field_type) != bitsize)
    {
      DECL_BIT_FIELD_TYPE (decl) = field_type;
      TREE_TYPE (decl)
	= c_build_bitfield_integer_type (bitsize, TYPE_UNSIGNED (field_type));
    }

  SET_DECL_MODE (decl, TYPE_MODE (TREE_TYPE (decl)));

  // There's no way to recover this from DWARF.
  SET_DECL_OFFSET_ALIGN (decl, TYPE_PRECISION (pointer_sized_int_node));

  tree pos = bitsize_int (bitpos);
  pos_from_bit (&DECL_FIELD_OFFSET (decl), &DECL_FIELD_BIT_OFFSET (decl),
		DECL_OFFSET_ALIGN (decl), pos);

  DECL_SIZE (decl) = bitsize_int (bitsize);
  DECL_SIZE_UNIT (decl) = size_int ((bitsize + BITS_PER_UNIT - 1)
				    / BITS_PER_UNIT);

  DECL_CHAIN (decl) = TYPE_FIELDS (record_or_union_type);
  TYPE_FIELDS (record_or_union_type) = decl;

  return 1;
}

int
plugin_finish_record_or_union (cc1_plugin::connection *,
			       gcc_type record_or_union_type_in,
			       unsigned long size_in_bytes)
{
  tree record_or_union_type = convert_in (record_or_union_type_in);

  gcc_assert (TREE_CODE (record_or_union_type) == RECORD_TYPE
	      || TREE_CODE (record_or_union_type) == UNION_TYPE);

  /* We built the field list in reverse order, so fix it now.  */
  TYPE_FIELDS (record_or_union_type)
    = nreverse (TYPE_FIELDS (record_or_union_type));

  if (TREE_CODE (record_or_union_type) == UNION_TYPE)
    {
      /* Unions can just be handled by the generic code.  */
      layout_type (record_or_union_type);
    }
  else
    {
      // FIXME there's no way to get this from DWARF,
      // or even, it seems, a particularly good way to deduce it.
      SET_TYPE_ALIGN (record_or_union_type,
		      TYPE_PRECISION (pointer_sized_int_node));

      TYPE_SIZE (record_or_union_type) = bitsize_int (size_in_bytes
						      * BITS_PER_UNIT);
      TYPE_SIZE_UNIT (record_or_union_type) = size_int (size_in_bytes);

      compute_record_mode (record_or_union_type);
      finish_bitfield_layout (record_or_union_type);
      // FIXME we have no idea about TYPE_PACKED
    }

  tree t = record_or_union_type, x;
  for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
    {
      /* Like finish_struct, update the qualified variant types.  */
      TYPE_FIELDS (x) = TYPE_FIELDS (t);
      TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
      C_TYPE_FIELDS_READONLY (x) = C_TYPE_FIELDS_READONLY (t);
      C_TYPE_FIELDS_VOLATILE (x) = C_TYPE_FIELDS_VOLATILE (t);
      C_TYPE_VARIABLE_SIZE (x) = C_TYPE_VARIABLE_SIZE (t);
      /* We copy these fields too.  */
      SET_TYPE_ALIGN (x, TYPE_ALIGN (t));
      TYPE_SIZE (x) = TYPE_SIZE (t);
      TYPE_SIZE_UNIT (x) = TYPE_SIZE_UNIT (t);
      if (x != record_or_union_type)
	compute_record_mode (x);
    }

  return 1;
}

gcc_type
plugin_build_enum_type (cc1_plugin::connection *self,
			gcc_type underlying_int_type_in)
{
  tree underlying_int_type = convert_in (underlying_int_type_in);

  if (underlying_int_type == error_mark_node)
    return convert_out (error_mark_node);

  tree result = build_anonymous_node (ENUMERAL_TYPE);

  TYPE_PRECISION (result) = TYPE_PRECISION (underlying_int_type);
  TYPE_UNSIGNED (result) = TYPE_UNSIGNED (underlying_int_type);

  plugin_context *ctx = static_cast<plugin_context *> (self);
  return convert_out (ctx->preserve (result));
}

int
plugin_build_add_enum_constant (cc1_plugin::connection *,
				gcc_type enum_type_in,
				const char *name,
				unsigned long value)
{
  tree cst, decl, cons;
  tree enum_type = convert_in (enum_type_in);

  gcc_assert (TREE_CODE (enum_type) == ENUMERAL_TYPE);

  cst = build_int_cst (enum_type, value);
  /* Note that gdb does not preserve the location of enum constants,
     so we can't provide a decent location here.  */
  decl = build_decl (BUILTINS_LOCATION, CONST_DECL,
		     get_identifier (name), enum_type);
  DECL_INITIAL (decl) = cst;
  pushdecl_safe (decl);

  cons = tree_cons (DECL_NAME (decl), cst, TYPE_VALUES (enum_type));
  TYPE_VALUES (enum_type) = cons;

  return 1;
}

int
plugin_finish_enum_type (cc1_plugin::connection *,
			 gcc_type enum_type_in)
{
  tree enum_type = convert_in (enum_type_in);
  tree minnode, maxnode, iter;

  iter = TYPE_VALUES (enum_type);
  minnode = maxnode = TREE_VALUE (iter);
  for (iter = TREE_CHAIN (iter);
       iter != NULL_TREE;
       iter = TREE_CHAIN (iter))
    {
      tree value = TREE_VALUE (iter);
      if (tree_int_cst_lt (maxnode, value))
	maxnode = value;
      if (tree_int_cst_lt (value, minnode))
	minnode = value;
    }
  TYPE_MIN_VALUE (enum_type) = minnode;
  TYPE_MAX_VALUE (enum_type) = maxnode;

  layout_type (enum_type);

  return 1;
}

gcc_type
plugin_build_function_type (cc1_plugin::connection *self,
			    gcc_type return_type_in,
			    const struct gcc_type_array *argument_types_in,
			    int is_varargs)
{
  tree return_type = convert_in (return_type_in);
  tree result;

  std::vector<tree> argument_types (argument_types_in->n_elements);
  for (int i = 0; i < argument_types_in->n_elements; ++i)
    argument_types[i] = convert_in (argument_types_in->elements[i]);

  if (is_varargs)
    result = build_varargs_function_type_array (return_type,
						argument_types_in->n_elements,
						argument_types.data ());
  else
    result = build_function_type_array (return_type,
					argument_types_in->n_elements,
					argument_types.data ());

  plugin_context *ctx = static_cast<plugin_context *> (self);
  return convert_out (ctx->preserve (result));
}

/* Return a builtin type associated with BUILTIN_NAME.  */

static tree
safe_lookup_builtin_type (const char *builtin_name)
{
  tree result = NULL_TREE;

  if (!builtin_name)
    return result;

  result = identifier_global_value (get_identifier (builtin_name));

  if (!result)
    return result;

  gcc_assert (TREE_CODE (result) == TYPE_DECL);
  result = TREE_TYPE (result);
  return result;
}

static gcc_type
plugin_int_check (cc1_plugin::connection *self,
		  int is_unsigned, unsigned long size_in_bytes,
		  tree result)
{
  if (result == NULL_TREE)
    result = error_mark_node;
  else
    {
      gcc_assert (!TYPE_UNSIGNED (result) == !is_unsigned);
      gcc_assert (TREE_CODE (TYPE_SIZE (result)) == INTEGER_CST);
      gcc_assert (TYPE_PRECISION (result) == BITS_PER_UNIT * size_in_bytes);

      plugin_context *ctx = static_cast<plugin_context *> (self);
      ctx->preserve (result);
    }
  return convert_out (result);
}

gcc_type
plugin_int_type_v0 (cc1_plugin::connection *self,
		    int is_unsigned, unsigned long size_in_bytes)
{
  tree result = c_common_type_for_size (BITS_PER_UNIT * size_in_bytes,
					is_unsigned);

  return plugin_int_check (self, is_unsigned, size_in_bytes, result);
}

gcc_type
plugin_int_type (cc1_plugin::connection *self,
		 int is_unsigned, unsigned long size_in_bytes,
		 const char *builtin_name)
{
  if (!builtin_name)
    return plugin_int_type_v0 (self, is_unsigned, size_in_bytes);

  tree result = safe_lookup_builtin_type (builtin_name);
  gcc_assert (!result || TREE_CODE (result) == INTEGER_TYPE);

  return plugin_int_check (self, is_unsigned, size_in_bytes, result);
}

gcc_type
plugin_char_type (cc1_plugin::connection *)
{
  return convert_out (char_type_node);
}

gcc_type
plugin_float_type_v0 (cc1_plugin::connection *,
		   unsigned long size_in_bytes)
{
  if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (float_type_node))
    return convert_out (float_type_node);
  if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (double_type_node))
    return convert_out (double_type_node);
  if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (long_double_type_node))
    return convert_out (long_double_type_node);
  return convert_out (error_mark_node);
}

gcc_type
plugin_float_type (cc1_plugin::connection *self,
		   unsigned long size_in_bytes,
		   const char *builtin_name)
{
  if (!builtin_name)
    return plugin_float_type_v0 (self, size_in_bytes);

  tree result = safe_lookup_builtin_type (builtin_name);

  if (!result)
    return convert_out (error_mark_node);

  gcc_assert (TREE_CODE (result) == REAL_TYPE);
  gcc_assert (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (result));

  return convert_out (result);
}

gcc_type
plugin_void_type (cc1_plugin::connection *)
{
  return convert_out (void_type_node);
}

gcc_type
plugin_bool_type (cc1_plugin::connection *)
{
  return convert_out (boolean_type_node);
}

gcc_type
plugin_build_array_type (cc1_plugin::connection *self,
			 gcc_type element_type_in, int num_elements)
{
  tree element_type = convert_in (element_type_in);
  tree result;

  if (num_elements == -1)
    result = build_array_type (element_type, NULL_TREE);
  else
    result = build_array_type_nelts (element_type, num_elements);

  plugin_context *ctx = static_cast<plugin_context *> (self);
  return convert_out (ctx->preserve (result));
}

gcc_type
plugin_build_vla_array_type (cc1_plugin::connection *self,
			     gcc_type element_type_in,
			     const char *upper_bound_name)
{
  tree element_type = convert_in (element_type_in);
  tree upper_bound = lookup_name (get_identifier (upper_bound_name));
  tree range = build_index_type (upper_bound);

  tree result = build_array_type (element_type, range);
  C_TYPE_VARIABLE_SIZE (result) = 1;

  plugin_context *ctx = static_cast<plugin_context *> (self);
  return convert_out (ctx->preserve (result));
}

gcc_type
plugin_build_qualified_type (cc1_plugin::connection *,
			     gcc_type unqualified_type_in,
			     enum gcc_qualifiers qualifiers)
{
  tree unqualified_type = convert_in (unqualified_type_in);
  int quals = 0;

  if ((qualifiers & GCC_QUALIFIER_CONST) != 0)
    quals |= TYPE_QUAL_CONST;
  if ((qualifiers & GCC_QUALIFIER_VOLATILE) != 0)
    quals |= TYPE_QUAL_VOLATILE;
  if ((qualifiers & GCC_QUALIFIER_RESTRICT) != 0)
    quals |= TYPE_QUAL_RESTRICT;

  return convert_out (build_qualified_type (unqualified_type, quals));
}

gcc_type
plugin_build_complex_type (cc1_plugin::connection *self,
			   gcc_type base_type)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  return convert_out (ctx->preserve (build_complex_type (convert_in (base_type))));
}

gcc_type
plugin_build_vector_type (cc1_plugin::connection *self,
			  gcc_type base_type, int nunits)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  return convert_out (ctx->preserve (build_vector_type (convert_in (base_type),
							nunits)));
}

int
plugin_build_constant (cc1_plugin::connection *self, gcc_type type_in,
		       const char *name, unsigned long value,
		       const char *filename, unsigned int line_number)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree cst, decl;
  tree type = convert_in (type_in);

  cst = build_int_cst (type, value);
  decl = build_decl (ctx->get_location_t (filename, line_number),
		     CONST_DECL, get_identifier (name), type);
  DECL_INITIAL (decl) = cst;
  pushdecl_safe (decl);

  return 1;
}

gcc_type
plugin_error (cc1_plugin::connection *,
	      const char *message)
{
  error ("%s", message);
  return convert_out (error_mark_node);
}



#ifdef __GNUC__
#pragma GCC visibility push(default)
#endif

int
plugin_init (struct plugin_name_args *plugin_info,
	     struct plugin_gcc_version *)
{
  generic_plugin_init (plugin_info, GCC_C_FE_VERSION_1);

  register_callback (plugin_info->base_name, PLUGIN_PRAGMAS,
		     plugin_init_extra_pragmas, NULL);
  register_callback (plugin_info->base_name, PLUGIN_PRE_GENERICIZE,
		     rewrite_decls_to_addresses, NULL);

#define GCC_METHOD0(R, N)			\
  {						\
    cc1_plugin::callback_ftype *fun		\
      = cc1_plugin::invoker<R>::invoke<plugin_ ## N>;	\
    current_context->add_callback (# N, fun);	\
  }
#define GCC_METHOD1(R, N, A)				\
  {							\
    cc1_plugin::callback_ftype *fun			\
      = cc1_plugin::invoker<R, A>::invoke<plugin_ ## N>;	\
    current_context->add_callback (# N, fun);		\
  }
#define GCC_METHOD2(R, N, A, B)				\
  {							\
    cc1_plugin::callback_ftype *fun			\
      = cc1_plugin::invoker<R, A, B>::invoke<plugin_ ## N>;	\
    current_context->add_callback (# N, fun);		\
  }
#define GCC_METHOD3(R, N, A, B, C)			\
  {							\
    cc1_plugin::callback_ftype *fun			\
      = cc1_plugin::invoker<R, A, B, C>::invoke<plugin_ ## N>;	\
    current_context->add_callback (# N, fun);		\
  }
#define GCC_METHOD4(R, N, A, B, C, D)		\
  {						\
    cc1_plugin::callback_ftype *fun		\
      = cc1_plugin::invoker<R, A, B, C,		\
			    D>::invoke<plugin_ ## N>;	\
    current_context->add_callback (# N, fun);	\
  }
#define GCC_METHOD5(R, N, A, B, C, D, E)	\
  {						\
    cc1_plugin::callback_ftype *fun		\
      = cc1_plugin::invoker<R, A, B, C, D,	\
			    E>::invoke<plugin_ ## N>;	\
    current_context->add_callback (# N, fun);	\
  }
#define GCC_METHOD7(R, N, A, B, C, D, E, F, G)		\
  {							\
    cc1_plugin::callback_ftype *fun			\
      = cc1_plugin::invoker<R, A, B, C, D,		\
			    E, F, G>::invoke<plugin_ ## N>;		\
    current_context->add_callback (# N, fun);		\
  }

#include "gcc-c-fe.def"

#undef GCC_METHOD0
#undef GCC_METHOD1
#undef GCC_METHOD2
#undef GCC_METHOD3
#undef GCC_METHOD4
#undef GCC_METHOD5
#undef GCC_METHOD7

  return 0;
}
